Skip to content

chore(engine): return -38003 for FCUv2 payloadAttributes mismatch#22924

Merged
emmajam merged 1 commit into
paradigmxyz:mainfrom
Muzry:fix-fcuv2-return-38003
Mar 26, 2026
Merged

chore(engine): return -38003 for FCUv2 payloadAttributes mismatch#22924
emmajam merged 1 commit into
paradigmxyz:mainfrom
Muzry:fix-fcuv2-return-38003

Conversation

@Muzry
Copy link
Copy Markdown
Contributor

@Muzry Muzry commented Mar 10, 2026

This PR updates engine_forkchoiceUpdatedV2 to return -38003: Invalid payload attributes when the wrong payloadAttributes version is used.

In particular, FCUv2 payload-attribute version mismatches such as:

  • missing withdrawals at or after Shanghai
  • unexpected withdrawals before Shanghai

should be treated as Invalid payload attributes, not Invalid params.

Why

This change aligns the client with the latest Engine API spec update in:

It also follows the implementation discussion and prior client-side change in:

The spec was clarified so that FCUv2 now behaves consistently with newer forkchoiceUpdated versions for payloadAttributes structure/version
mismatches.

What changed

  • Updated FCUv2 payload attributes validation to return -38003 for payloadAttributes version mismatches.
  • Added/updated regression coverage for the affected FCUv2 cases.

Hive impact

This fixes the Hive engine-withdrawals failure caused by returning the wrong error code for FCUv2 payloadAttributes mismatches.

Relevant Hive failure:

After this change, the client returns the expected error code for the affected FCUv2 cases.

If my understanding or interpretation of the spec change is incorrect, please let me know and I can adjust the implementation accordingly.

Copy link
Copy Markdown
Collaborator

@mattsse mattsse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we changed this recently, no idea anymore what is correct here

also dont think this matters

@emmajam
Copy link
Copy Markdown
Member

emmajam commented Mar 23, 2026

@Muzry happy to merge this, can you get CI green please?

@mattsse mattsse changed the title engine: return -38003 for FCUv2 payloadAttributes mismatch chore(engine): return -38003 for FCUv2 payloadAttributes mismatch Mar 23, 2026
@Muzry Muzry force-pushed the fix-fcuv2-return-38003 branch from d766219 to a895541 Compare March 24, 2026 07:35
@Muzry
Copy link
Copy Markdown
Contributor Author

Muzry commented Mar 24, 2026

@mattsse @emmajam Thanks for the reply. I’ll try to get the CI green. Could you please take another look?

@github-project-automation github-project-automation Bot moved this from Backlog to In Progress in Reth Tracker Mar 26, 2026
@emmajam emmajam added this pull request to the merge queue Mar 26, 2026
Merged via the queue into paradigmxyz:main with commit 0cbd0aa Mar 26, 2026
36 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Reth Tracker Mar 26, 2026
github-merge-queue Bot pushed a commit to tempoxyz/tempo that referenced this pull request Mar 31, 2026
Automated nightly update of reth dependencies from `paradigmxyz/reth`
main branch.

## Upstream reth changes


[`7f4a9a0...f0d07c3`](paradigmxyz/reth@7f4a9a0...f0d07c3)

🔗 Amp thread:
https://ampcode.com/threads/T-019d4215-b76f-7663-b8f3-8fde1da1165c
**Engine**
- Share execution cache and sparse trie pipeline with payload builder
([#23242](paradigmxyz/reth#23242),
[#23246](paradigmxyz/reth#23246))
- Add method to get payload resolve future
([#23256](paradigmxyz/reth#23256))
- Backpressure, take 2
([#23280](paradigmxyz/reth#23280))
- Return -38003 for FCUv2 payloadAttributes mismatch
([#22924](paradigmxyz/reth#22924))
- Fix double decrement in account cache size
([#23249](paradigmxyz/reth#23249))

**Trie**
- Call root before prune
([#23243](paradigmxyz/reth#23243))
- Use Entry API in `MultiProofTargets::extend_inner`
([#23247](paradigmxyz/reth#23247))
- Record trie cursor metrics
([#23252](paradigmxyz/reth#23252))
- Add `SparseStateTrie::update_account_stateless` for stateless
validation ([#23272](paradigmxyz/reth#23272))

**Networking**
- Prefer peer-reported block number in session activation
([#23275](paradigmxyz/reth#23275))
- Resolve DNS for ExternalAddr in `external_addr_with`
([#23269](paradigmxyz/reth#23269))

**Consensus**
- Retry block subscription on initial connection failure
([#23233](paradigmxyz/reth#23233))

**Refactor**
- Remove OP `ExecutionPayload` impl and op feature from
payload-primitives
([#23253](paradigmxyz/reth#23253))
- Remove OP `PayloadAttributesBuilder` impl and op feature from
engine-local ([#23255](paradigmxyz/reth#23255))
- Relax RPC converter impls
([#23254](paradigmxyz/reth#23254))

**Perf / Bench**
- Use `FastInstant` for remaining metrics timing
([#23265](paradigmxyz/reth#23265))
- Add hourly main regression bench
([#23219](paradigmxyz/reth#23219))

**DB**
- Add `create_test_provider_factory_with_chain_spec_and_db_args`
([#23270](paradigmxyz/reth#23270))

**CLI**
- Add more WARN logging before download retries
([#23258](paradigmxyz/reth#23258))
- Use `HeaderTy` for stage dump headers
([#23274](paradigmxyz/reth#23274))

**Testing**
- Add regression test for parked basefee ancestor handling
([#23277](paradigmxyz/reth#23277))

**Deps**
- Bump alloy 1.8.2, alloy-evm, lighthouse v8.1.3
([#23241](paradigmxyz/reth#23241),
[#23289](paradigmxyz/reth#23289),
[#23239](paradigmxyz/reth#23239))
- Weekly `cargo update`
([#23267](paradigmxyz/reth#23267))

## Migrations

🔗 Amp thread:
https://ampcode.com/threads/T-019d4215-e6e7-7542-acaa-239d595b2916
- **Reth dependency bump**: All `reth-*` crates updated from rev
`7f4a9a0` to `f0d07c3`; `alloy-evm` bumped from `0.29.2` to `0.30.0`
- **`reth-etl` reordered**: Moved from its previous position to sit next
to `reth-trie` (no functional change)
- **`tempo-contracts` feature dropped**: Removed default `features =
["serde"]` from workspace dependency
- **`TransactionEnv` → `TransactionEnvMut` rename**:
`reth_evm::TransactionEnv` trait was renamed to `TransactionEnvMut`; all
imports and impls updated
- **`TransactionEnv::nonce()` removed**: The `nonce(&self)` method was
removed from the trait; call sites now use
`revm::context::Transaction::nonce()` instead
- **`TxResult::into_result()` added**: New required method
`into_result(self) -> ResultAndState` added to the `TxResult` trait impl
for `TempoTxResult`
- **`BuildArguments::new` signature expanded**: Two new parameters
(`None, None`) added for `execution_cache` and `trie_handle`;
corresponding destructure updated to ignore them
- **`builder.finish()` signature change**: Now takes an additional
`Option` parameter (passed as `None`) for trie handle

[GitHub
Workflow](https://github.com/tempoxyz/tempo/actions/runs/23779717485)
github-merge-queue Bot pushed a commit to tempoxyz/tempo that referenced this pull request Apr 1, 2026
Automated nightly update of reth dependencies from `paradigmxyz/reth`
main branch.

## Upstream reth changes


[`7f4a9a0...f8efc76`](paradigmxyz/reth@7f4a9a0...f8efc76)

🔗 Amp thread:
https://ampcode.com/threads/T-019d473e-4c63-7539-bda6-d72354aae810
**Engine**
- Share execution cache and sparse trie pipeline with payload builder
([#23242](paradigmxyz/reth#23242),
[#23246](paradigmxyz/reth#23246))
- Add backpressure, take 2
([#23280](paradigmxyz/reth#23280))
- Add method to get payload resolve future
([#23256](paradigmxyz/reth#23256))
- Return -38003 for FCUv2 payloadAttributes mismatch
([#22924](paradigmxyz/reth#22924))
- Fix double decrement in account cache size
([#23249](paradigmxyz/reth#23249))

**Trie**
- Call root before prune
([#23243](paradigmxyz/reth#23243))
- Use Entry API in `MultiProofTargets::extend_inner`
([#23247](paradigmxyz/reth#23247))
- Record trie cursor metrics
([#23252](paradigmxyz/reth#23252))
- Add `SparseStateTrie::update_account_stateless` for stateless
validation ([#23272](paradigmxyz/reth#23272))

**RPC**
- Integrate `reth-rpc-traits` and remove `IntoRpcTx`
([#23288](paradigmxyz/reth#23288))
- Relax rpc converter impls
([#23254](paradigmxyz/reth#23254))

**Net**
- Prefer peer-reported block number in session activation
([#23275](paradigmxyz/reth#23275))
- Retry block subscription on initial connection failure
([#23233](paradigmxyz/reth#23233))
- Resolve DNS for ExternalAddr in `external_addr_with`
([#23269](paradigmxyz/reth#23269))

**Payload / Refactor**
- Remove OP `ExecutionPayload` impl and op feature from
payload-primitives
([#23253](paradigmxyz/reth#23253))
- Remove OP `PayloadAttributesBuilder` impl and op feature from
engine-local ([#23255](paradigmxyz/reth#23255))
- Remove changeset count APIs from storage
([#23310](paradigmxyz/reth#23310))

**DB / Storage**
- Add `create_test_provider_factory_with_chain_spec_and_db_args`
([#23270](paradigmxyz/reth#23270))
- Add `reth-bb` binary with multi-segment big block execution support
([#23140](paradigmxyz/reth#23140))
- Add era type override functionality to `EraClient`
([#23307](paradigmxyz/reth#23307))
- Make snapshot API URL overridable
([#23303](paradigmxyz/reth#23303))

**Perf**
- Use `FastInstant` for remaining metrics timing
([#23265](paradigmxyz/reth#23265))

**Bench / Testing**
- Add hourly main regression bench
([#23219](paradigmxyz/reth#23219))
- Add regression test for parked basefee ancestor handling
([#23277](paradigmxyz/reth#23277))

**CLI**
- Add more WARN logging before download retries
([#23258](paradigmxyz/reth#23258))
- Use `HeaderTy` for stage dump headers
([#23274](paradigmxyz/reth#23274))

**Deps**
- Bump alloy 1.8.2, alloy-evm, Lighthouse v8.1.3
([#23241](paradigmxyz/reth#23241),
[#23289](paradigmxyz/reth#23289),
[#23239](paradigmxyz/reth#23239))
- Weekly `cargo update`
([#23267](paradigmxyz/reth#23267))

**Grafana**
- Add sparse trie idle metrics to overview
([#23302](paradigmxyz/reth#23302))

## Migrations

🔗 Amp thread:
https://ampcode.com/threads/T-019d473e-8aba-7283-b729-057391d70bc6
- **Reth dependency bump**: All `reth-*` crates updated from rev
`7f4a9a0` to `f8efc76`
- **alloy-evm version bump**: `0.29.2` → `0.30.0`; `revm-inspectors`
`0.36.1` → `0.36.0`
- **`TransactionEnv` → `TransactionEnvMut`**: Trait moved from
`reth_evm::TransactionEnv` to `alloy_evm::TransactionEnvMut`; `nonce()`
getter removed from the trait (now accessed via
`revm::context::Transaction::nonce()` instead)
- **`FromConsensusHeader` re-export flattened**: Import path changed
from `reth_rpc_convert::transaction::FromConsensusHeader` to
`reth_rpc_convert::FromConsensusHeader`
- **`TxResult::into_result` added**: New required method on the
`TxResult` trait to consume and return `ResultAndState`
- **`BuildArguments::new` signature expanded**: Now takes two additional
`None` parameters (likely cached/prebuilt payload fields)
- **`BuildArguments` destructure**: Uses `..` rest pattern to ignore new
fields
- **`BlockBuilder::finish` signature change**: Now takes an additional
parameter (`None` — likely an optional requests list)
- **`snapshot_api_url` field added**: New required field on download URL
config struct

[GitHub
Workflow](https://github.com/tempoxyz/tempo/actions/runs/23831300439)

---------

Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
Co-authored-by: Arsenii Kulikov <62447812+klkvr@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants