From cb6ba085bc5b28faa8f92438dfc8c0decbe9e90d Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 3 Jul 2024 13:43:04 +0200 Subject: [PATCH 1/9] validate EL block hash when running consensus block tests We currently don't have an easy way to test EL block hash computation. As the EL block hash in consensus-spec-tests is computed correctly, update the test runners that load block from test files to also verify the EL block hash. This increases missing test coverage. Requires https://github.com/ethereum/consensus-specs/pull/3829 --- beacon_chain/spec/helpers.nim | 23 +++++++++++++------ .../bellatrix/test_fixture_operations.nim | 9 +++++++- .../capella/test_fixture_operations.nim | 9 +++++++- .../deneb/test_fixture_operations.nim | 9 +++++++- .../electra/test_fixture_operations.nim | 9 +++++++- tests/consensus_spec/fixtures_utils.nim | 23 ++++++++++++++++--- .../test_fixture_fork_choice.nim | 5 +--- .../test_fixture_sanity_blocks.nim | 12 ++++++---- .../test_fixture_transition.nim | 12 +++++----- tests/testblockutil.nim | 2 +- 10 files changed, 83 insertions(+), 30 deletions(-) diff --git a/beacon_chain/spec/helpers.nim b/beacon_chain/spec/helpers.nim index a168a8ec74..93cc417f39 100644 --- a/beacon_chain/spec/helpers.nim +++ b/beacon_chain/spec/helpers.nim @@ -393,14 +393,17 @@ func is_merge_transition_complete*( state.latest_execution_payload_header != defaultExecutionPayloadHeader # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/sync/optimistic.md#helpers -func is_execution_block*(blck: SomeForkyBeaconBlock): bool = - when typeof(blck).kind >= ConsensusFork.Bellatrix: +func is_execution_block*(body: SomeForkyBeaconBlockBody): bool = + when typeof(body).kind >= ConsensusFork.Bellatrix: const defaultExecutionPayload = - default(typeof(blck.body.execution_payload)) - blck.body.execution_payload != defaultExecutionPayload + default(typeof(body.execution_payload)) + body.execution_payload != defaultExecutionPayload else: false +func is_execution_block*(blck: SomeForkyBeaconBlock): bool = + blck.body.is_execution_block + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#is_merge_transition_block func is_merge_transition_block( state: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState | @@ -474,9 +477,10 @@ proc computeWithdrawalsTrieRoot*( raiseAssert "HexaryTrie.put failed: " & $exc.msg tr.rootHash() -proc blockToBlockHeader*(blck: ForkyBeaconBlock): ExecutionBlockHeader = - template payload: auto = blck.body.execution_payload +proc toExecutionBlockHeader*( + payload: ForkyExecutionPayload, + parentRoot: Eth2Digest): ExecutionBlockHeader = static: # `GasInt` is signed. We only use it for hashing. doAssert sizeof(GasInt) == sizeof(payload.gas_limit) doAssert sizeof(GasInt) == sizeof(payload.gas_used) @@ -526,5 +530,10 @@ proc blockToBlockHeader*(blck: ForkyBeaconBlock): ExecutionBlockHeader = excessBlobGas : excessBlobGas, # EIP-4844 parentBeaconBlockRoot : parentBeaconBlockRoot) # EIP-4788 +proc compute_execution_block_hash*( + payload: ForkyExecutionPayload, + parentRoot: Eth2Digest): Eth2Digest = + rlpHash payload.toExecutionBlockHeader(parentRoot) + proc compute_execution_block_hash*(blck: ForkyBeaconBlock): Eth2Digest = - rlpHash blockToBlockHeader(blck) + blck.body.execution_payload.compute_execution_block_hash(blck.parent_root) diff --git a/tests/consensus_spec/bellatrix/test_fixture_operations.nim b/tests/consensus_spec/bellatrix/test_fixture_operations.nim index 7ec841519f..3ef5d1e317 100644 --- a/tests/consensus_spec/bellatrix/test_fixture_operations.nim +++ b/tests/consensus_spec/bellatrix/test_fixture_operations.nim @@ -110,9 +110,12 @@ suite baseDescription & "Attester Slashing " & preset(): applyAttesterSlashing, path) suite baseDescription & "Block Header " & preset(): - func applyBlockHeader( + proc applyBlockHeader( preState: var bellatrix.BeaconState, blck: bellatrix.BeaconBlock): Result[void, cstring] = + if blck.is_execution_block: + check blck.body.execution_payload.block_hash == + blck.compute_execution_block_hash() var cache: StateCache process_block_header(preState, blck, {}, cache) @@ -143,6 +146,10 @@ suite baseDescription & "Execution Payload " & preset(): let payloadValid = os_ops.readFile( OpExecutionPayloadDir/"pyspec_tests"/path/"execution.yaml" ).contains("execution_valid: true") + if payloadValid and body.is_execution_block: + check body.execution_payload.block_hash == + body.execution_payload.compute_execution_block_hash( + preState.latest_block_header.hash_tree_root()) func executePayload(_: bellatrix.ExecutionPayload): bool = payloadValid process_execution_payload( preState, body.execution_payload, executePayload) diff --git a/tests/consensus_spec/capella/test_fixture_operations.nim b/tests/consensus_spec/capella/test_fixture_operations.nim index 22198cb467..7ad797165f 100644 --- a/tests/consensus_spec/capella/test_fixture_operations.nim +++ b/tests/consensus_spec/capella/test_fixture_operations.nim @@ -114,9 +114,12 @@ suite baseDescription & "Attester Slashing " & preset(): applyAttesterSlashing, path) suite baseDescription & "Block Header " & preset(): - func applyBlockHeader( + proc applyBlockHeader( preState: var capella.BeaconState, blck: capella.BeaconBlock): Result[void, cstring] = + if blck.is_execution_block: + check blck.body.execution_payload.block_hash == + blck.compute_execution_block_hash() var cache: StateCache process_block_header(preState, blck, {}, cache) @@ -160,6 +163,10 @@ suite baseDescription & "Execution Payload " & preset(): let payloadValid = os_ops.readFile( OpExecutionPayloadDir/"pyspec_tests"/path/"execution.yaml" ).contains("execution_valid: true") + if payloadValid and body.is_execution_block: + check body.execution_payload.block_hash == + body.execution_payload.compute_execution_block_hash( + preState.latest_block_header.hash_tree_root()) func executePayload(_: capella.ExecutionPayload): bool = payloadValid process_execution_payload( preState, body.execution_payload, executePayload) diff --git a/tests/consensus_spec/deneb/test_fixture_operations.nim b/tests/consensus_spec/deneb/test_fixture_operations.nim index 78dad933bd..62f119c239 100644 --- a/tests/consensus_spec/deneb/test_fixture_operations.nim +++ b/tests/consensus_spec/deneb/test_fixture_operations.nim @@ -114,9 +114,12 @@ suite baseDescription & "Attester Slashing " & preset(): applyAttesterSlashing, path) suite baseDescription & "Block Header " & preset(): - func applyBlockHeader( + proc applyBlockHeader( preState: var deneb.BeaconState, blck: deneb.BeaconBlock): Result[void, cstring] = + if blck.is_execution_block: + check blck.body.execution_payload.block_hash == + blck.compute_execution_block_hash() var cache: StateCache process_block_header(preState, blck, {}, cache) @@ -163,6 +166,10 @@ suite baseDescription & "Execution Payload " & preset(): let payloadValid = os_ops.readFile( OpExecutionPayloadDir/"pyspec_tests"/path/"execution.yaml" ).contains("execution_valid: true") + if payloadValid and body.is_execution_block: + check body.execution_payload.block_hash == + body.execution_payload.compute_execution_block_hash( + preState.latest_block_header.hash_tree_root()) func executePayload(_: deneb.ExecutionPayload): bool = payloadValid process_execution_payload(preState, body, executePayload) diff --git a/tests/consensus_spec/electra/test_fixture_operations.nim b/tests/consensus_spec/electra/test_fixture_operations.nim index d3974d56b2..732d8509d0 100644 --- a/tests/consensus_spec/electra/test_fixture_operations.nim +++ b/tests/consensus_spec/electra/test_fixture_operations.nim @@ -121,9 +121,12 @@ suite baseDescription & "Attester Slashing " & preset(): applyAttesterSlashing, path) suite baseDescription & "Block Header " & preset(): - func applyBlockHeader( + proc applyBlockHeader( preState: var electra.BeaconState, blck: electra.BeaconBlock): Result[void, cstring] = + if blck.is_execution_block: + check blck.body.execution_payload.block_hash == + blck.compute_execution_block_hash() var cache: StateCache process_block_header(preState, blck, {}, cache) @@ -197,6 +200,10 @@ suite baseDescription & "Execution Payload " & preset(): let payloadValid = os_ops.readFile( OpExecutionPayloadDir/"pyspec_tests"/path/"execution.yaml" ).contains("execution_valid: true") + if payloadValid and body.is_execution_block: + check body.execution_payload.block_hash == + body.execution_payload.compute_execution_block_hash( + preState.latest_block_header.hash_tree_root()) func executePayload(_: electra.ExecutionPayload): bool = payloadValid process_execution_payload(preState, body, executePayload) diff --git a/tests/consensus_spec/fixtures_utils.nim b/tests/consensus_spec/fixtures_utils.nim index c658ef5a21..52afd93d06 100644 --- a/tests/consensus_spec/fixtures_utils.nim +++ b/tests/consensus_spec/fixtures_utils.nim @@ -14,13 +14,13 @@ import ./os_ops, ../../beacon_chain/spec/datatypes/[phase0, altair, bellatrix], ../../beacon_chain/spec/[ - eth2_merkleization, eth2_ssz_serialization, forks], + eth2_merkleization, eth2_ssz_serialization, forks, helpers], # Status libs, snappy, stew/byteutils export - eth2_merkleization, eth2_ssz_serialization + eth2_merkleization, eth2_ssz_serialization, helpers # Process current EF test format # --------------------------------------------- @@ -166,4 +166,21 @@ proc loadForkedState*( withState(state[]): forkyState.data = parseTest(path, SSZ, consensusFork.BeaconState) forkyState.root = hash_tree_root(forkyState.data) - state \ No newline at end of file + state + +proc loadBlock*( + path: string, + consensusFork: static ConsensusFork, + validateBlockHash = true): auto = + var blck = parseTest(path, SSZ, consensusFork.SignedBeaconBlock) + blck.root = hash_tree_root(blck.message) + when consensusFork >= ConsensusFork.Bellatrix: + if blck.message.is_execution_block: + if blck.message.body.execution_payload.block_hash != + blck.message.compute_execution_block_hash(): + try: + stderr.write "Invalid `block_hash`: ", path, "\n" + except IOError: + discard + quit 1 + blck diff --git a/tests/consensus_spec/test_fixture_fork_choice.nim b/tests/consensus_spec/test_fixture_fork_choice.nim index 163996b8fb..522b712c50 100644 --- a/tests/consensus_spec/test_fixture_fork_choice.nim +++ b/tests/consensus_spec/test_fixture_fork_choice.nim @@ -124,10 +124,7 @@ proc loadOps( doAssert step.hasKey"blobs" == step.hasKey"proofs" withConsensusFork(fork): let - blck = parseTest( - path/filename & ".ssz_snappy", - SSZ, consensusFork.SignedBeaconBlock) - + blck = loadBlock(path/filename & ".ssz_snappy", consensusFork) blobData = when consensusFork >= ConsensusFork.Deneb: if step.hasKey"blobs": diff --git a/tests/consensus_spec/test_fixture_sanity_blocks.nim b/tests/consensus_spec/test_fixture_sanity_blocks.nim index 22b2eb35d5..f0272e8774 100644 --- a/tests/consensus_spec/test_fixture_sanity_blocks.nim +++ b/tests/consensus_spec/test_fixture_sanity_blocks.nim @@ -10,7 +10,7 @@ import chronicles, - ../../beacon_chain/spec/forks, + ../../beacon_chain/spec/forks, ../../beacon_chain/spec/helpers, ../../beacon_chain/spec/state_transition, ./os_ops, ../testutil @@ -20,7 +20,8 @@ from std/strutils import toLowerAscii from ../../beacon_chain/spec/presets import const_preset, defaultRuntimeConfig from ./fixtures_utils import - SSZ, SszTestsDir, hash_tree_root, parseTest, readSszBytes, toSszType + SSZ, SszTestsDir, hash_tree_root, loadBlock, parseTest, + readSszBytes, toSszType proc runTest( consensusFork: static ConsensusFork, @@ -43,8 +44,9 @@ proc runTest( # so purely lexicographic sorting wouldn't sort properly. let numBlocks = toSeq(walkPattern(testPath/"blocks_*.ssz_snappy")).len for i in 0 ..< numBlocks: - let blck = parseTest(testPath/"blocks_" & $i & ".ssz_snappy", - SSZ, consensusFork.SignedBeaconBlock) + let blck = loadBlock( + testPath/"blocks_" & $i & ".ssz_snappy", consensusFork, + validateBlockHash = hasPostState) if hasPostState: # The return value is the block rewards, which aren't tested here; @@ -96,4 +98,4 @@ template runForkBlockTests(consensusFork: static ConsensusFork) = RandomDir, suiteName, path) withAll(ConsensusFork): - runForkBlockTests(consensusFork) \ No newline at end of file + runForkBlockTests(consensusFork) diff --git a/tests/consensus_spec/test_fixture_transition.nim b/tests/consensus_spec/test_fixture_transition.nim index 6a699c0107..44f9fe163a 100644 --- a/tests/consensus_spec/test_fixture_transition.nim +++ b/tests/consensus_spec/test_fixture_transition.nim @@ -16,7 +16,7 @@ import from std/sequtils import toSeq from std/streams import close, openFileStream from ../testutil import preset, suite, test -from ./fixtures_utils import SszTestsDir, parseTest +from ./fixtures_utils import SszTestsDir, loadBlock, parseTest type TransitionInfo = object @@ -54,8 +54,8 @@ proc runTest( for i in 0 ..< numBlocks: if i <= fork_block: let - blck = parseTest( - testPath/"blocks_" & $i & ".ssz_snappy", SSZ, AnteBeaconBlock) + blck = loadBlock( + testPath/"blocks_" & $i & ".ssz_snappy", AnteBeaconBlock.kind) res = state_transition( cfg, fhPreState[], blck, cache, info, flags = {skipStateRootValidation}, noRollback) @@ -65,8 +65,8 @@ proc runTest( discard res.expect("no failure when applying block " & $i) else: let - blck = parseTest( - testPath/"blocks_" & $i & ".ssz_snappy", SSZ, PostBeaconBlock) + blck = loadBlock( + testPath/"blocks_" & $i & ".ssz_snappy", PostBeaconBlock.kind) res = state_transition( cfg, fhPreState[], blck, cache, info, flags = {skipStateRootValidation}, noRollback) @@ -161,4 +161,4 @@ suite "EF - Electra - Transition " & preset(): runTest( deneb.BeaconState, electra.BeaconState, deneb.SignedBeaconBlock, electra.SignedBeaconBlock, cfg, "EF - Electra - Transition", - TransitionDir, suiteName, path, transitionInfo.fork_block) \ No newline at end of file + TransitionDir, suiteName, path, transitionInfo.fork_block) diff --git a/tests/testblockutil.nim b/tests/testblockutil.nim index 3b5fc267ac..100f2e6d86 100644 --- a/tests/testblockutil.nim +++ b/tests/testblockutil.nim @@ -112,7 +112,7 @@ proc build_empty_merge_execution_payload(state: bellatrix.BeaconState): timestamp: timestamp, base_fee_per_gas: EIP1559_INITIAL_BASE_FEE) - payload.block_hash = rlpHash blockToBlockHeader(bellatrix.BeaconBlock(body: + payload.block_hash = compute_execution_block_hash(bellatrix.BeaconBlock(body: bellatrix.BeaconBlockBody(execution_payload: payload))) bellatrix.ExecutionPayloadForSigning(executionPayload: payload, From a5a1117c3037e43524571f1c508989e12826a71f Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 3 Jul 2024 17:41:46 +0200 Subject: [PATCH 2/9] fix --- beacon_chain/spec/helpers.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon_chain/spec/helpers.nim b/beacon_chain/spec/helpers.nim index 93cc417f39..6ba737bf7c 100644 --- a/beacon_chain/spec/helpers.nim +++ b/beacon_chain/spec/helpers.nim @@ -504,7 +504,7 @@ proc toExecutionBlockHeader*( Opt.none(uint64) parentBeaconBlockRoot = when typeof(payload).kind >= ConsensusFork.Deneb: - Opt.some ExecutionHash256(data: blck.parent_root.data) + Opt.some ExecutionHash256(data: parentRoot.data) else: Opt.none(ExecutionHash256) From 4c23696dc6403843338703566ad5f68b8a92f1d3 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Sat, 10 Aug 2024 01:42:39 +0200 Subject: [PATCH 3/9] resolve merge conflicts --- beacon_chain/spec/helpers.nim | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/beacon_chain/spec/helpers.nim b/beacon_chain/spec/helpers.nim index 83ef67e02b..2828038411 100644 --- a/beacon_chain/spec/helpers.nim +++ b/beacon_chain/spec/helpers.nim @@ -395,29 +395,19 @@ func is_merge_transition_complete*( default(typeof(state.latest_execution_payload_header)) state.latest_execution_payload_header != defaultExecutionPayloadHeader -<<<<<<< HEAD -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/sync/optimistic.md#helpers +# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.4/sync/optimistic.md#helpers func is_execution_block*(body: SomeForkyBeaconBlockBody): bool = when typeof(body).kind >= ConsensusFork.Bellatrix: -======= -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.4/sync/optimistic.md#helpers -func is_execution_block*(blck: SomeForkyBeaconBlock): bool = - when typeof(blck).kind >= ConsensusFork.Bellatrix: ->>>>>>> unstable const defaultExecutionPayload = default(typeof(body.execution_payload)) body.execution_payload != defaultExecutionPayload else: false -<<<<<<< HEAD func is_execution_block*(blck: SomeForkyBeaconBlock): bool = blck.body.is_execution_block -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.3/specs/bellatrix/beacon-chain.md#is_merge_transition_block -======= # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.4/specs/bellatrix/beacon-chain.md#is_merge_transition_block ->>>>>>> unstable func is_merge_transition_block( state: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState | electra.BeaconState, From 990c990e737285ddbdd50d314588691b828490b8 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 14 Aug 2024 20:08:34 +0200 Subject: [PATCH 4/9] fix genesis case, and deal with `incorrect_block_hash` test --- .../consensus_spec/bellatrix/test_fixture_operations.nim | 9 +++++---- tests/consensus_spec/capella/test_fixture_operations.nim | 9 +++++---- tests/consensus_spec/deneb/test_fixture_operations.nim | 7 ++++--- tests/consensus_spec/electra/test_fixture_operations.nim | 9 +++++---- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/tests/consensus_spec/bellatrix/test_fixture_operations.nim b/tests/consensus_spec/bellatrix/test_fixture_operations.nim index c1521f1478..cb921a0367 100644 --- a/tests/consensus_spec/bellatrix/test_fixture_operations.nim +++ b/tests/consensus_spec/bellatrix/test_fixture_operations.nim @@ -24,7 +24,7 @@ from std/sequtils import mapIt, toSeq from std/strutils import contains from ../../../beacon_chain/spec/beaconstate import get_base_reward_per_increment, get_state_exit_queue_info, - get_total_active_balance, process_attestation + get_total_active_balance, latest_block_root, process_attestation const OpDir = SszTestsDir/const_preset/"bellatrix"/"operations" @@ -148,9 +148,10 @@ suite baseDescription & "Execution Payload " & preset(): OpExecutionPayloadDir/"pyspec_tests"/path/"execution.yaml" ).contains("execution_valid: true") if payloadValid and body.is_execution_block: - check body.execution_payload.block_hash == + let expectedOk = (path != "incorrect_block_hash") + check expectedOk == (body.execution_payload.block_hash == body.execution_payload.compute_execution_block_hash( - preState.latest_block_header.hash_tree_root()) + preState.latest_block_root(preState.hash_tree_root()))) func executePayload(_: bellatrix.ExecutionPayload): bool = payloadValid process_execution_payload( preState, body.execution_payload, executePayload) @@ -206,4 +207,4 @@ suite baseDescription & "Voluntary Exit " & preset(): for path in walkTests(OpVoluntaryExitDir): runTest[SignedVoluntaryExit, typeof applyVoluntaryExit]( OpVoluntaryExitDir, suiteName, "Voluntary Exit", "voluntary_exit", - applyVoluntaryExit, path) \ No newline at end of file + applyVoluntaryExit, path) diff --git a/tests/consensus_spec/capella/test_fixture_operations.nim b/tests/consensus_spec/capella/test_fixture_operations.nim index 69363c8a4a..8357871703 100644 --- a/tests/consensus_spec/capella/test_fixture_operations.nim +++ b/tests/consensus_spec/capella/test_fixture_operations.nim @@ -24,7 +24,7 @@ from std/sequtils import mapIt, toSeq from std/strutils import contains from ../../../beacon_chain/spec/beaconstate import get_base_reward_per_increment, get_state_exit_queue_info, - get_total_active_balance, process_attestation + get_total_active_balance, latest_block_root, process_attestation const OpDir = SszTestsDir/const_preset/"capella"/"operations" @@ -165,9 +165,10 @@ suite baseDescription & "Execution Payload " & preset(): OpExecutionPayloadDir/"pyspec_tests"/path/"execution.yaml" ).contains("execution_valid: true") if payloadValid and body.is_execution_block: - check body.execution_payload.block_hash == + let expectedOk = (path != "incorrect_block_hash") + check expectedOk == (body.execution_payload.block_hash == body.execution_payload.compute_execution_block_hash( - preState.latest_block_header.hash_tree_root()) + preState.latest_block_root(preState.hash_tree_root()))) func executePayload(_: capella.ExecutionPayload): bool = payloadValid process_execution_payload( preState, body.execution_payload, executePayload) @@ -234,4 +235,4 @@ suite baseDescription & "Withdrawals " & preset(): for path in walkTests(OpWithdrawalsDir): runTest[capella.ExecutionPayload, typeof applyWithdrawals]( OpWithdrawalsDir, suiteName, "Withdrawals", "execution_payload", - applyWithdrawals, path) \ No newline at end of file + applyWithdrawals, path) diff --git a/tests/consensus_spec/deneb/test_fixture_operations.nim b/tests/consensus_spec/deneb/test_fixture_operations.nim index c1e943be55..1021412856 100644 --- a/tests/consensus_spec/deneb/test_fixture_operations.nim +++ b/tests/consensus_spec/deneb/test_fixture_operations.nim @@ -168,9 +168,10 @@ suite baseDescription & "Execution Payload " & preset(): OpExecutionPayloadDir/"pyspec_tests"/path/"execution.yaml" ).contains("execution_valid: true") if payloadValid and body.is_execution_block: - check body.execution_payload.block_hash == + let expectedOk = (path != "incorrect_block_hash") + check expectedOk == (body.execution_payload.block_hash == body.execution_payload.compute_execution_block_hash( - preState.latest_block_header.hash_tree_root()) + preState.latest_block_root(preState.hash_tree_root()))) func executePayload(_: deneb.ExecutionPayload): bool = payloadValid process_execution_payload(preState, body, executePayload) @@ -236,4 +237,4 @@ suite baseDescription & "Withdrawals " & preset(): for path in walkTests(OpWithdrawalsDir): runTest[deneb.ExecutionPayload, typeof applyWithdrawals]( OpWithdrawalsDir, suiteName, "Withdrawals", "execution_payload", - applyWithdrawals, path) \ No newline at end of file + applyWithdrawals, path) diff --git a/tests/consensus_spec/electra/test_fixture_operations.nim b/tests/consensus_spec/electra/test_fixture_operations.nim index d760eea280..0ccffc06f4 100644 --- a/tests/consensus_spec/electra/test_fixture_operations.nim +++ b/tests/consensus_spec/electra/test_fixture_operations.nim @@ -24,7 +24,7 @@ from std/sequtils import mapIt, toSeq from std/strutils import contains from ../../../beacon_chain/spec/beaconstate import get_base_reward_per_increment, get_state_exit_queue_info, - get_total_active_balance, process_attestation + get_total_active_balance, latest_block_root, process_attestation const OpDir = SszTestsDir/const_preset/"electra"/"operations" @@ -204,9 +204,10 @@ suite baseDescription & "Execution Payload " & preset(): OpExecutionPayloadDir/"pyspec_tests"/path/"execution.yaml" ).contains("execution_valid: true") if payloadValid and body.is_execution_block: - check body.execution_payload.block_hash == + let expectedOk = (path != "incorrect_block_hash") + check expectedOk == (body.execution_payload.block_hash == body.execution_payload.compute_execution_block_hash( - preState.latest_block_header.hash_tree_root()) + preState.latest_block_root(preState.hash_tree_root()))) func executePayload(_: electra.ExecutionPayload): bool = payloadValid process_execution_payload(preState, body, executePayload) @@ -288,4 +289,4 @@ suite baseDescription & "Withdrawals " & preset(): for path in walkTests(OpWithdrawalsDir): runTest[electra.ExecutionPayload, typeof applyWithdrawals]( OpWithdrawalsDir, suiteName, "Withdrawals", "execution_payload", - applyWithdrawals, path) \ No newline at end of file + applyWithdrawals, path) From f5e6916fa78baa213a114bd252b39466a03dba36 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 14 Aug 2024 20:18:01 +0200 Subject: [PATCH 5/9] add missing export marker --- beacon_chain/spec/beaconstate.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon_chain/spec/beaconstate.nim b/beacon_chain/spec/beaconstate.nim index 8f3ec0345e..a033a29d14 100644 --- a/beacon_chain/spec/beaconstate.nim +++ b/beacon_chain/spec/beaconstate.nim @@ -2158,7 +2158,7 @@ func upgrade_to_electra*( post -func latest_block_root(state: ForkyBeaconState, state_root: Eth2Digest): +func latest_block_root*(state: ForkyBeaconState, state_root: Eth2Digest): Eth2Digest = # The root of the last block that was successfully applied to this state - # normally, when a block is applied, the data from the header is stored in From 89021d059cbe2c6cb31e0c1be992291d773825b2 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 14 Aug 2024 20:26:48 +0200 Subject: [PATCH 6/9] fix import --- tests/consensus_spec/deneb/test_fixture_operations.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/consensus_spec/deneb/test_fixture_operations.nim b/tests/consensus_spec/deneb/test_fixture_operations.nim index 1021412856..0dc6c84fa1 100644 --- a/tests/consensus_spec/deneb/test_fixture_operations.nim +++ b/tests/consensus_spec/deneb/test_fixture_operations.nim @@ -24,7 +24,7 @@ from std/sequtils import mapIt, toSeq from std/strutils import contains from ../../../beacon_chain/spec/beaconstate import get_base_reward_per_increment, get_state_exit_queue_info, - get_total_active_balance, process_attestation + get_total_active_balance, latest_block_root, process_attestation const OpDir = SszTestsDir/const_preset/"deneb"/"operations" From 66083f5c76af0908443965399a6316a136616039 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 14 Aug 2024 21:01:00 +0200 Subject: [PATCH 7/9] htr mutates underlying data, messing with differ, create copy in test --- tests/consensus_spec/bellatrix/test_fixture_operations.nim | 3 ++- tests/consensus_spec/capella/test_fixture_operations.nim | 3 ++- tests/consensus_spec/deneb/test_fixture_operations.nim | 3 ++- tests/consensus_spec/electra/test_fixture_operations.nim | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/consensus_spec/bellatrix/test_fixture_operations.nim b/tests/consensus_spec/bellatrix/test_fixture_operations.nim index cb921a0367..e31990e27b 100644 --- a/tests/consensus_spec/bellatrix/test_fixture_operations.nim +++ b/tests/consensus_spec/bellatrix/test_fixture_operations.nim @@ -151,7 +151,8 @@ suite baseDescription & "Execution Payload " & preset(): let expectedOk = (path != "incorrect_block_hash") check expectedOk == (body.execution_payload.block_hash == body.execution_payload.compute_execution_block_hash( - preState.latest_block_root(preState.hash_tree_root()))) + preState.latest_block_root( + assignClone(preState)[].hash_tree_root()))) func executePayload(_: bellatrix.ExecutionPayload): bool = payloadValid process_execution_payload( preState, body.execution_payload, executePayload) diff --git a/tests/consensus_spec/capella/test_fixture_operations.nim b/tests/consensus_spec/capella/test_fixture_operations.nim index 8357871703..156062a3d6 100644 --- a/tests/consensus_spec/capella/test_fixture_operations.nim +++ b/tests/consensus_spec/capella/test_fixture_operations.nim @@ -168,7 +168,8 @@ suite baseDescription & "Execution Payload " & preset(): let expectedOk = (path != "incorrect_block_hash") check expectedOk == (body.execution_payload.block_hash == body.execution_payload.compute_execution_block_hash( - preState.latest_block_root(preState.hash_tree_root()))) + preState.latest_block_root( + assignClone(preState)[].hash_tree_root()))) func executePayload(_: capella.ExecutionPayload): bool = payloadValid process_execution_payload( preState, body.execution_payload, executePayload) diff --git a/tests/consensus_spec/deneb/test_fixture_operations.nim b/tests/consensus_spec/deneb/test_fixture_operations.nim index 0dc6c84fa1..d498e37422 100644 --- a/tests/consensus_spec/deneb/test_fixture_operations.nim +++ b/tests/consensus_spec/deneb/test_fixture_operations.nim @@ -171,7 +171,8 @@ suite baseDescription & "Execution Payload " & preset(): let expectedOk = (path != "incorrect_block_hash") check expectedOk == (body.execution_payload.block_hash == body.execution_payload.compute_execution_block_hash( - preState.latest_block_root(preState.hash_tree_root()))) + preState.latest_block_root( + assignClone(preState)[].hash_tree_root()))) func executePayload(_: deneb.ExecutionPayload): bool = payloadValid process_execution_payload(preState, body, executePayload) diff --git a/tests/consensus_spec/electra/test_fixture_operations.nim b/tests/consensus_spec/electra/test_fixture_operations.nim index 0ccffc06f4..1eb9a02b08 100644 --- a/tests/consensus_spec/electra/test_fixture_operations.nim +++ b/tests/consensus_spec/electra/test_fixture_operations.nim @@ -207,7 +207,8 @@ suite baseDescription & "Execution Payload " & preset(): let expectedOk = (path != "incorrect_block_hash") check expectedOk == (body.execution_payload.block_hash == body.execution_payload.compute_execution_block_hash( - preState.latest_block_root(preState.hash_tree_root()))) + preState.latest_block_root( + assignClone(preState)[].hash_tree_root()))) func executePayload(_: electra.ExecutionPayload): bool = payloadValid process_execution_payload(preState, body, executePayload) From 8a7b07768928d52f410156337a72c28d3a6a7797 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Fri, 22 Nov 2024 00:02:55 +0100 Subject: [PATCH 8/9] Handle payloads with empty tx (unsupported in ordered trie tool) --- tests/consensus_spec/bellatrix/test_fixture_operations.nim | 5 +++-- tests/consensus_spec/capella/test_fixture_operations.nim | 5 +++-- tests/consensus_spec/deneb/test_fixture_operations.nim | 5 +++-- tests/consensus_spec/electra/test_fixture_operations.nim | 5 +++-- tests/consensus_spec/fixtures_utils.nim | 5 +++-- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/tests/consensus_spec/bellatrix/test_fixture_operations.nim b/tests/consensus_spec/bellatrix/test_fixture_operations.nim index f4df73d499..8877fa1360 100644 --- a/tests/consensus_spec/bellatrix/test_fixture_operations.nim +++ b/tests/consensus_spec/bellatrix/test_fixture_operations.nim @@ -20,7 +20,7 @@ import ../fixtures_utils, ../os_ops, ../../helpers/debug_state -from std/sequtils import mapIt, toSeq +from std/sequtils import anyIt, mapIt, toSeq from std/strutils import contains from ../../../beacon_chain/spec/beaconstate import get_base_reward_per_increment, get_state_exit_queue_info, @@ -147,7 +147,8 @@ suite baseDescription & "Execution Payload " & preset(): let payloadValid = os_ops.readFile( OpExecutionPayloadDir/"pyspec_tests"/path/"execution.yaml" ).contains("execution_valid: true") - if payloadValid and body.is_execution_block: + if payloadValid and body.is_execution_block and + not body.execution_payload.transactions.anyIt(it.len == 0): let expectedOk = (path != "incorrect_block_hash") check expectedOk == (body.execution_payload.block_hash == body.compute_execution_block_hash( diff --git a/tests/consensus_spec/capella/test_fixture_operations.nim b/tests/consensus_spec/capella/test_fixture_operations.nim index c771d21823..1a21b83a19 100644 --- a/tests/consensus_spec/capella/test_fixture_operations.nim +++ b/tests/consensus_spec/capella/test_fixture_operations.nim @@ -20,7 +20,7 @@ import ../fixtures_utils, ../os_ops, ../../helpers/debug_state -from std/sequtils import mapIt, toSeq +from std/sequtils import anyIt, mapIt, toSeq from std/strutils import contains from ../../../beacon_chain/spec/beaconstate import get_base_reward_per_increment, get_state_exit_queue_info, @@ -164,7 +164,8 @@ suite baseDescription & "Execution Payload " & preset(): let payloadValid = os_ops.readFile( OpExecutionPayloadDir/"pyspec_tests"/path/"execution.yaml" ).contains("execution_valid: true") - if payloadValid and body.is_execution_block: + if payloadValid and body.is_execution_block and + not body.execution_payload.transactions.anyIt(it.len == 0): let expectedOk = (path != "incorrect_block_hash") check expectedOk == (body.execution_payload.block_hash == body.compute_execution_block_hash( diff --git a/tests/consensus_spec/deneb/test_fixture_operations.nim b/tests/consensus_spec/deneb/test_fixture_operations.nim index c914e41493..356c3b2f06 100644 --- a/tests/consensus_spec/deneb/test_fixture_operations.nim +++ b/tests/consensus_spec/deneb/test_fixture_operations.nim @@ -20,7 +20,7 @@ import ../fixtures_utils, ../os_ops, ../../helpers/debug_state -from std/sequtils import mapIt, toSeq +from std/sequtils import anyIt, mapIt, toSeq from std/strutils import contains from ../../../beacon_chain/spec/beaconstate import get_base_reward_per_increment, get_state_exit_queue_info, @@ -167,7 +167,8 @@ suite baseDescription & "Execution Payload " & preset(): let payloadValid = os_ops.readFile( OpExecutionPayloadDir/"pyspec_tests"/path/"execution.yaml" ).contains("execution_valid: true") - if payloadValid and body.is_execution_block: + if payloadValid and body.is_execution_block and + not body.execution_payload.transactions.anyIt(it.len == 0): let expectedOk = (path != "incorrect_block_hash") check expectedOk == (body.execution_payload.block_hash == body.compute_execution_block_hash( diff --git a/tests/consensus_spec/electra/test_fixture_operations.nim b/tests/consensus_spec/electra/test_fixture_operations.nim index 0ea0bc4590..ab1af59afa 100644 --- a/tests/consensus_spec/electra/test_fixture_operations.nim +++ b/tests/consensus_spec/electra/test_fixture_operations.nim @@ -20,7 +20,7 @@ import ../fixtures_utils, ../os_ops, ../../helpers/debug_state -from std/sequtils import mapIt, toSeq +from std/sequtils import anyIt, mapIt, toSeq from std/strutils import contains from ../../../beacon_chain/spec/beaconstate import get_base_reward_per_increment, get_state_exit_queue_info, @@ -202,7 +202,8 @@ suite baseDescription & "Execution Payload " & preset(): let payloadValid = os_ops.readFile( OpExecutionPayloadDir/"pyspec_tests"/path/"execution.yaml" ).contains("execution_valid: true") - if payloadValid and body.is_execution_block: + if payloadValid and body.is_execution_block and + not body.execution_payload.transactions.anyIt(it.len == 0): let expectedOk = (path != "incorrect_block_hash") check expectedOk == (body.execution_payload.block_hash == body.compute_execution_block_hash( diff --git a/tests/consensus_spec/fixtures_utils.nim b/tests/consensus_spec/fixtures_utils.nim index 313a7c5b9f..ad79d411a9 100644 --- a/tests/consensus_spec/fixtures_utils.nim +++ b/tests/consensus_spec/fixtures_utils.nim @@ -9,7 +9,7 @@ import # Standard library - std/[strutils, typetraits], + std/[sequtils, strutils, typetraits], # Internals ./os_ops, ../../beacon_chain/spec/datatypes/[phase0, altair, bellatrix], @@ -182,7 +182,8 @@ proc loadBlock*( var blck = parseTest(path, SSZ, consensusFork.SignedBeaconBlock) blck.root = hash_tree_root(blck.message) when consensusFork >= ConsensusFork.Bellatrix: - if blck.message.is_execution_block: + if blck.message.is_execution_block and + not blck.message.body.execution_payload.transactions.anyIt(it.len == 0): if blck.message.body.execution_payload.block_hash != blck.message.compute_execution_block_hash(): try: From 5acdbf8d676d3c72462b2bb48268aa622ebdba22 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Mon, 6 Jan 2025 12:31:45 +0100 Subject: [PATCH 9/9] Update copyright years --- beacon_chain/spec/beaconstate.nim | 2 +- beacon_chain/spec/helpers.nim | 2 +- tests/consensus_spec/bellatrix/test_fixture_operations.nim | 2 +- tests/consensus_spec/capella/test_fixture_operations.nim | 2 +- tests/consensus_spec/deneb/test_fixture_operations.nim | 2 +- tests/consensus_spec/electra/test_fixture_operations.nim | 2 +- tests/consensus_spec/fixtures_utils.nim | 2 +- tests/consensus_spec/test_fixture_fork_choice.nim | 2 +- tests/consensus_spec/test_fixture_kzg.nim | 2 +- tests/consensus_spec/test_fixture_sanity_blocks.nim | 2 +- tests/consensus_spec/test_fixture_transition.nim | 2 +- tests/testblockutil.nim | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/beacon_chain/spec/beaconstate.nim b/beacon_chain/spec/beaconstate.nim index 09ce696b62..93d1721c49 100644 --- a/beacon_chain/spec/beaconstate.nim +++ b/beacon_chain/spec/beaconstate.nim @@ -1,5 +1,5 @@ # beacon_chain -# Copyright (c) 2018-2024 Status Research & Development GmbH +# Copyright (c) 2018-2025 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). diff --git a/beacon_chain/spec/helpers.nim b/beacon_chain/spec/helpers.nim index 4f2e1bea4f..a609ee87c8 100644 --- a/beacon_chain/spec/helpers.nim +++ b/beacon_chain/spec/helpers.nim @@ -1,5 +1,5 @@ # beacon_chain -# Copyright (c) 2018-2024 Status Research & Development GmbH +# Copyright (c) 2018-2025 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). diff --git a/tests/consensus_spec/bellatrix/test_fixture_operations.nim b/tests/consensus_spec/bellatrix/test_fixture_operations.nim index 8877fa1360..8869027616 100644 --- a/tests/consensus_spec/bellatrix/test_fixture_operations.nim +++ b/tests/consensus_spec/bellatrix/test_fixture_operations.nim @@ -1,5 +1,5 @@ # beacon_chain -# Copyright (c) 2018-2024 Status Research & Development GmbH +# Copyright (c) 2018-2025 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). diff --git a/tests/consensus_spec/capella/test_fixture_operations.nim b/tests/consensus_spec/capella/test_fixture_operations.nim index 1a21b83a19..adc613e08b 100644 --- a/tests/consensus_spec/capella/test_fixture_operations.nim +++ b/tests/consensus_spec/capella/test_fixture_operations.nim @@ -1,5 +1,5 @@ # beacon_chain -# Copyright (c) 2022-2024 Status Research & Development GmbH +# Copyright (c) 2022-2025 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). diff --git a/tests/consensus_spec/deneb/test_fixture_operations.nim b/tests/consensus_spec/deneb/test_fixture_operations.nim index 356c3b2f06..c0b5989be9 100644 --- a/tests/consensus_spec/deneb/test_fixture_operations.nim +++ b/tests/consensus_spec/deneb/test_fixture_operations.nim @@ -1,5 +1,5 @@ # beacon_chain -# Copyright (c) 2022-2024 Status Research & Development GmbH +# Copyright (c) 2022-2025 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). diff --git a/tests/consensus_spec/electra/test_fixture_operations.nim b/tests/consensus_spec/electra/test_fixture_operations.nim index e171a47dca..092afc7ee3 100644 --- a/tests/consensus_spec/electra/test_fixture_operations.nim +++ b/tests/consensus_spec/electra/test_fixture_operations.nim @@ -1,5 +1,5 @@ # beacon_chain -# Copyright (c) 2024 Status Research & Development GmbH +# Copyright (c) 2024-2025 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). diff --git a/tests/consensus_spec/fixtures_utils.nim b/tests/consensus_spec/fixtures_utils.nim index d07185031d..8ef5b917ad 100644 --- a/tests/consensus_spec/fixtures_utils.nim +++ b/tests/consensus_spec/fixtures_utils.nim @@ -1,5 +1,5 @@ # beacon_chain -# Copyright (c) 2018-2024 Status Research & Development GmbH +# Copyright (c) 2018-2025 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). diff --git a/tests/consensus_spec/test_fixture_fork_choice.nim b/tests/consensus_spec/test_fixture_fork_choice.nim index c1acdfa2e4..b938901659 100644 --- a/tests/consensus_spec/test_fixture_fork_choice.nim +++ b/tests/consensus_spec/test_fixture_fork_choice.nim @@ -1,5 +1,5 @@ # beacon_chain -# Copyright (c) 2018-2024 Status Research & Development GmbH +# Copyright (c) 2018-2025 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). diff --git a/tests/consensus_spec/test_fixture_kzg.nim b/tests/consensus_spec/test_fixture_kzg.nim index df6318cd59..1ba8db274a 100644 --- a/tests/consensus_spec/test_fixture_kzg.nim +++ b/tests/consensus_spec/test_fixture_kzg.nim @@ -1,5 +1,5 @@ # beacon_chain -# Copyright (c) 2024 Status Research & Development GmbH +# Copyright (c) 2024-2025 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). diff --git a/tests/consensus_spec/test_fixture_sanity_blocks.nim b/tests/consensus_spec/test_fixture_sanity_blocks.nim index 5c4949260e..85497f47c2 100644 --- a/tests/consensus_spec/test_fixture_sanity_blocks.nim +++ b/tests/consensus_spec/test_fixture_sanity_blocks.nim @@ -1,5 +1,5 @@ # beacon_chain -# Copyright (c) 2018-2024 Status Research & Development GmbH +# Copyright (c) 2018-2025 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). diff --git a/tests/consensus_spec/test_fixture_transition.nim b/tests/consensus_spec/test_fixture_transition.nim index 44f9fe163a..1e2f67cca9 100644 --- a/tests/consensus_spec/test_fixture_transition.nim +++ b/tests/consensus_spec/test_fixture_transition.nim @@ -1,5 +1,5 @@ # beacon_chain -# Copyright (c) 2021-2024 Status Research & Development GmbH +# Copyright (c) 2021-2025 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). diff --git a/tests/testblockutil.nim b/tests/testblockutil.nim index 54bb7960a1..8469de18c9 100644 --- a/tests/testblockutil.nim +++ b/tests/testblockutil.nim @@ -1,5 +1,5 @@ # beacon_chain -# Copyright (c) 2018-2024 Status Research & Development GmbH +# Copyright (c) 2018-2025 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).