spec: complete Generic Relayer Architecture compliance#23
Merged
Conversation
Cherry-picks the best of each branch and fills the remaining gaps against https://hackmd.io/T4TkZYFQQnCupiuW231DYw: From the rpc branch (not present in master): - Add maxFeePerGas / maxPriorityFeePerGas to FeeDataResponse so EIP-1559 clients can build type-2 transactions without a second eth_feeHistory call. - Add feeCollector to FeeDataResponse as a single-call convenience (mirrors relayer_getCapabilities, avoids a second round-trip). - Extract fetch_gas_fees() that fetches both legacy gasPrice and EIP-1559 max fees in one provider interaction. Missing spec error codes now wired (4200-4214 complete): - 4200 Insufficient Payment — pub(crate) for fee-verification middleware - 4201 Invalid Signature — pub(crate) for signature-validation middleware - 4203 Rate Limit Exceeded — pub(crate) for rate-limiting middleware - 4204 Quote Expired — enforced when context.expiry is present - 4207 Transaction Too Large — enforced at 128 KB calldata limit - 4212 Multichain Not Supported — gated by --disable-multichain / config Config additions: - disable_multichain flag (--disable-multichain / RELAYX_DISABLE_MULTICHAIN / config.json "disableMultichain") for operators that want to disable relayer_sendTransactionMultichain. - fee_collector_for_chain() that checks per-chain feeCollectors map before falling back to the global feeCollector.
Per the Generic Relayer Architecture spec update, numeric fields in
receipt and fee data responses must be decimal strings, not hex:
- SpecReceipt.blockNumber: format!("{}", r.block_number) instead of 0x hex
- SpecReceipt.gasUsed: format!("{}", r.gas_used) instead of 0x hex
- FeeDataResponse.gasPrice: decimal wei string instead of 0x hex
Add hex_to_decimal() helper to convert the hex strings returned by
fetch_gas_fees() at the response-building boundary.
The new disable_multichain field was missing from the two Config struct literals used in unit and integration tests, causing a compile error.
Clippy (--all-targets): - Replace useless vec![...] with array literals in 4 multichain test cases - Replace &[item.clone()] with std::slice::from_ref(&item) in unit test Format: - Break hex_to_decimal() method chain across lines per rustfmt style - Re-run cargo fmt to ensure all files are consistently formatted README: - Error codes table: replace old wrong table with complete 4200-4214 spec - getFeeData response: add maxFeePerGas, maxPriorityFeePerGas, feeCollector fields; change gasPrice example from hex to decimal - getStatus receipt: change blockNumber / gasUsed examples to decimal - Config: add feeCollectors per-chain map and disableMultichain flag - CLI flags: add --disable-simulation and --disable-multichain rows - sendTransaction context: document expiry field - Test count: 40 total (12 unit + 28 integration)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR merges the best of all three branches (
master,rpc,feature) andfills the remaining gaps against the
Generic Relayer Architecture spec.
Branch comparison
featurerpcmasterrelayer_*methodstaskId/authorizationListin sendTransactionmaxFeePerGas/maxPriorityFeePerGasingetFeeDatafeeCollectoringetFeeDataresponse--disable-multichainoperator flagfeeCollectorconfigChanges
From
rpcbranch (cherry-picked, not inmaster)FeeDataResponsegainsmaxFeePerGasandmaxPriorityFeePerGas(optional,omitted on pre-EIP-1559 chains). Clients can build type-2 transactions without
a separate
eth_feeHistorycall.feeCollectoradded toFeeDataResponseas a convenience field (mirrorsrelayer_getCapabilities). Clients that only callgetFeeDatanow know whereto route the payment without a second round-trip.
fetch_gas_fees()helper fetches both legacygasPriceand EIP-1559maxFeePerGas/maxPriorityFeePerGasin a single provider interaction.Spec error codes completed (4200–4214 now full)
pub(crate)— fee-verification middlewarepub(crate)— signature-validation middlewarepub(crate)— rate-limiting middlewarecontext.expiryis present insendTransactionsendTransaction--disable-multichainflagConfig additions
--disable-multichain/RELAYX_DISABLE_MULTICHAIN/config.json "disableMultichain"—operators that don't want to support cross-chain settlement can return 4212 instead.
fee_collector_for_chain(chain_id)— checks{ "feeCollectors": { chainId: "0x..." } }before falling back to the global
feeCollector.Test plan
cargo clippy -- -D warningspasses (verified locally)cargo fmt --allpasses (verified locally)cargo buildsucceeds with zero errors (verified locally)relayer_getFeeDataresponse includesmaxFeePerGas/maxPriorityFeePerGas/feeCollectorwhen chain is EIP-1559relayer_sendTransactionwithcontext.expiryin the past returns 4204relayer_sendTransactionwith calldata > 128 KB returns 4207relayer_sendTransactionMultichainwith--disable-multichainreturns 4212