Skip to content

spec: complete Generic Relayer Architecture compliance#23

Merged
ch4r10t33r merged 5 commits into
masterfrom
spec/complete-compliance
Mar 17, 2026
Merged

spec: complete Generic Relayer Architecture compliance#23
ch4r10t33r merged 5 commits into
masterfrom
spec/complete-compliance

Conversation

@ch4r10t33r
Copy link
Copy Markdown
Member

Summary

This PR merges the best of all three branches (master, rpc, feature) and
fills the remaining gaps against the
Generic Relayer Architecture spec.

Branch comparison

Feature feature rpc master This PR
All 5 relayer_* methods ✅ (merged)
Numeric status codes 100/110/200/400/500
taskId / authorizationList in sendTransaction
Webhook callbacks
EIP-1559 maxFeePerGas / maxPriorityFeePerGas in getFeeData
feeCollector in getFeeData response
Error codes 4202/4205/4206/4208–4211/4213/4214 partial partial
Missing error codes 4200/4201/4203/4204/4207/4212
--disable-multichain operator flag
Per-chain feeCollector config

Changes

From rpc branch (cherry-picked, not in master)

  • FeeDataResponse gains maxFeePerGas and maxPriorityFeePerGas (optional,
    omitted on pre-EIP-1559 chains). Clients can build type-2 transactions without
    a separate eth_feeHistory call.
  • feeCollector added to FeeDataResponse as a convenience field (mirrors
    relayer_getCapabilities). Clients that only call getFeeData now know where
    to route the payment without a second round-trip.
  • New fetch_gas_fees() helper fetches both legacy gasPrice and EIP-1559
    maxFeePerGas / maxPriorityFeePerGas in a single provider interaction.

Spec error codes completed (4200–4214 now full)

Code Message Where raised
4200 Insufficient Payment pub(crate) — fee-verification middleware
4201 Invalid Signature pub(crate) — signature-validation middleware
4203 Rate Limit Exceeded pub(crate) — rate-limiting middleware
4204 Quote Expired Enforced when context.expiry is present in sendTransaction
4207 Transaction Too Large Enforced at 128 KB calldata limit in sendTransaction
4212 Multichain Not Supported Gated by --disable-multichain flag

Config 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 warnings passes (verified locally)
  • cargo fmt --all passes (verified locally)
  • cargo build succeeds with zero errors (verified locally)
  • relayer_getFeeData response includes maxFeePerGas / maxPriorityFeePerGas / feeCollector when chain is EIP-1559
  • relayer_sendTransaction with context.expiry in the past returns 4204
  • relayer_sendTransaction with calldata > 128 KB returns 4207
  • relayer_sendTransactionMultichain with --disable-multichain returns 4212

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)
@ch4r10t33r ch4r10t33r marked this pull request as ready for review March 17, 2026 10:22
@ch4r10t33r ch4r10t33r merged commit 266e912 into master Mar 17, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant