This repository was archived by the owner on Aug 5, 2026. It is now read-only.
forked from paradigmxyz/reth
-
Notifications
You must be signed in to change notification settings - Fork 11
test: e2e for debug_executionWitness
#348
Merged
Merged
Changes from 4 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
0386e6b
base test passing
itschaindev 7cd738e
verify parent state root
itschaindev 3184aba
Merge branch 'unstable' into jk/326-test-execution-witness
itschaindev 2e56952
fix lint
itschaindev e177d10
use parent block for state provider
itschaindev 1412305
Merge branch 'unstable' into jk/326-test-execution-witness
itschaindev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| package proofs | ||
|
|
||
| import ( | ||
| "strings" | ||
| "testing" | ||
|
|
||
| "github.com/ethereum-optimism/optimism/op-devstack/devtest" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/presets" | ||
| "github.com/ethereum-optimism/optimism/op-service/eth" | ||
| "github.com/ethereum/go-ethereum/common/hexutil" | ||
| "github.com/ethereum/go-ethereum/core/types" | ||
| "github.com/ethereum/go-ethereum/rlp" | ||
| "github.com/stretchr/testify/require" | ||
| ) | ||
|
|
||
| // ExecutionWitness represents the response from debug_executionWitness | ||
| type ExecutionWitness struct { | ||
| Keys []hexutil.Bytes `json:"keys"` | ||
| Codes []hexutil.Bytes `json:"codes"` | ||
| State []hexutil.Bytes `json:"state"` | ||
| Headers []hexutil.Bytes `json:"headers"` | ||
| } | ||
|
|
||
| // TestDebugExecutionWitness tests the debug_executionWitness RPC method on Reth L2. | ||
| // This verifies that the execution witness can be retrieved for a block containing transactions | ||
| // and that the response contains valid state, codes, keys, and headers data. | ||
| func TestDebugExecutionWitness(gt *testing.T) { | ||
| t := devtest.SerialT(gt) | ||
| preset := presets.NewSingleChainMultiNode(t) | ||
|
|
||
| // Create a funded account and recipient | ||
| account := preset.FunderL2.NewFundedEOA(eth.Ether(10)) | ||
| recipient := preset.FunderL2.NewFundedEOA(eth.Ether(1)) | ||
| recipientAddr := recipient.Address() | ||
|
|
||
| // Wait for current block | ||
| currentBlock := preset.L2EL.WaitForBlock() | ||
| t.Logf("Current L2 block number: %d", currentBlock.Number) | ||
|
|
||
| // Send a transaction to create some state changes | ||
| transferAmount := eth.Ether(1) | ||
| tx := account.Transfer(recipientAddr, transferAmount) | ||
| t.Logf("Sent transaction from account: %s to recipient: %s", account.Address().Hex(), recipientAddr.Hex()) | ||
|
|
||
| receipt, err := tx.Included.Eval(t.Ctx()) | ||
| require.NoError(t, err) | ||
| require.Equal(t, types.ReceiptStatusSuccessful, receipt.Status) | ||
| t.Logf("Transaction included in block: %d", receipt.BlockNumber.Uint64()) | ||
|
|
||
| l2RethClient := preset.L2ELB.Escape().L2EthClient() | ||
|
|
||
| // Get the block to inspect the state changes | ||
| block, err := l2RethClient.InfoByNumber(t.Ctx(), receipt.BlockNumber.Uint64()) | ||
| require.NoError(t, err) | ||
| t.Logf("Block %d has state root: %s", block.NumberU64(), block.Root().Hex()) | ||
|
|
||
| // Call debug_executionWitness via RPC | ||
| var witness ExecutionWitness | ||
| blockNumberHex := hexutil.EncodeUint64(block.NumberU64()) | ||
|
|
||
| // Use the RPC client's CallContext method directly | ||
| err = l2RethClient.RPC().CallContext(t.Ctx(), &witness, "debug_executionWitness", blockNumberHex) | ||
| require.NoError(t, err, "debug_executionWitness RPC call should succeed") | ||
|
|
||
| // Verify the witness contains expected data | ||
| require.NotEmpty(t, witness.Keys, "Witness should contain keys data") | ||
| require.NotEmpty(t, witness.Codes, "Witness should contain codes data") | ||
| require.NotEmpty(t, witness.State, "State should not be empty") | ||
| require.NotNil(t, witness.Headers, "Witness should contain headers data") | ||
|
|
||
| // Verify the parent header is present and decode it | ||
| require.NotEmpty(t, witness.Headers, "Headers should contain at least the parent block") | ||
| parentHeaderBytes := witness.Headers[len(witness.Headers)-1] | ||
| require.NotEmpty(t, parentHeaderBytes, "Parent header should not be empty") | ||
| t.Logf("Parent header size: %d bytes", len(parentHeaderBytes)) | ||
|
|
||
| // Decode the parent header to verify it's valid RLP and extract state root | ||
| var parentHeader types.Header | ||
| err = rlp.DecodeBytes(parentHeaderBytes, &parentHeader) | ||
| require.NoError(t, err, "Parent header should be valid RLP-encoded") | ||
|
|
||
| // Verify the parent header matches the expected parent block | ||
| expectedParentNumber := block.NumberU64() - 1 | ||
| require.Equal(t, expectedParentNumber, parentHeader.Number.Uint64(), | ||
| "Parent header should be for block %d", expectedParentNumber) | ||
|
|
||
| // Get the actual parent block from the chain to verify state root | ||
| actualParentBlock, err := l2RethClient.InfoByNumber(t.Ctx(), expectedParentNumber) | ||
| require.NoError(t, err, "Should be able to fetch parent block from chain") | ||
|
|
||
| // Verify the parent header's state root matches the actual parent block's state root | ||
| require.Equal(t, actualParentBlock.Root(), parentHeader.Root, | ||
| "Parent header state root in witness should match actual parent block state root") | ||
| t.Logf("Verified parent header state root matches chain: %s", parentHeader.Root.Hex()) | ||
|
|
||
| // Verify that the witness contains keys for the accounts involved in the transaction | ||
| senderAddrHex := strings.ToLower(account.Address().Hex()) | ||
| recipientAddrHex := strings.ToLower(recipientAddr.Hex()) | ||
|
|
||
| // Check if the witness keys contains the accounts | ||
| // The witness format may vary, so we check for the presence of either the address or its hash | ||
| foundSender := false | ||
| foundRecipient := false | ||
|
|
||
| for _, value := range witness.Keys { | ||
| keyLower := strings.ToLower(value.String()) | ||
| if strings.Contains(keyLower, senderAddrHex) { | ||
| foundSender = true | ||
| } | ||
| if strings.Contains(keyLower, recipientAddrHex) { | ||
| foundRecipient = true | ||
| } | ||
| } | ||
|
|
||
| // We should find at least the sender since they initiated the transaction | ||
| require.True(t, foundSender, "Witness should contain state data for the transaction sender") | ||
| t.Logf("Verified sender account is present in execution witness") | ||
|
|
||
| // The recipient might not always be in the witness depending on the implementation | ||
| if foundRecipient { | ||
| t.Logf("Verified recipient account is present in execution witness") | ||
| } | ||
| t.Log("Successfully retrieved and validated execution witness from Reth") | ||
| } |
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.