From f3267dde9359627049af4d2dcb719a60037fdd07 Mon Sep 17 00:00:00 2001 From: Katya Ryazantseva Date: Fri, 13 Dec 2024 14:16:21 +0100 Subject: [PATCH 1/4] Add random_execution_payload_header to bellatrix state --- .../test/helpers/execution_payload.py | 78 ++++++++++++++++++- .../pyspec/eth2spec/test/helpers/random.py | 5 ++ .../eth2spec/test/helpers/withdrawals.py | 14 ++++ .../test/utils/randomized_block_tests.py | 5 +- 4 files changed, 99 insertions(+), 3 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py b/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py index 80684b9e6e..cf3cd08b59 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py +++ b/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py @@ -1,13 +1,17 @@ from eth_hash.auto import keccak from hashlib import sha256 from trie import HexaryTrie +from random import Random from rlp import encode from rlp.sedes import big_endian_int, Binary, List from eth2spec.test.helpers.keys import privkeys from eth2spec.utils.ssz.ssz_impl import hash_tree_root from eth2spec.debug.random_value import get_random_bytes_list -from eth2spec.test.helpers.withdrawals import get_expected_withdrawals +from eth2spec.test.helpers.withdrawals import ( + get_expected_withdrawals, + get_random_withdrawal, +) from eth2spec.test.helpers.forks import ( is_post_capella, is_post_deneb, @@ -263,6 +267,69 @@ def compute_el_block_hash_for_block(spec, block): spec, block.body.execution_payload, block.parent_root, requests_hash) +def build_empty_execution_payload_header(spec, state): + latest = state.latest_execution_payload_header + timestamp = spec.compute_timestamp_at_slot(state, state.slot) + execution_payload = build_empty_execution_payload(spec, state) + + execution_payload_header = spec.ExecutionPayloadHeader( + parent_hash = latest.block_hash, + fee_recipient = spec.ExecutionAddress(), + state_root = latest.state_root, + receipts_root = spec.Bytes32(), + logs_bloom = spec.ByteVector[spec.BYTES_PER_LOGS_BLOOM](), + prev_randao = spec.Bytes32(), + block_number = 0, + gas_limit = 0, + gas_used = 0, + timestamp = timestamp, + extra_data = spec.ByteList[spec.MAX_EXTRA_DATA_BYTES](), + base_fee_per_gas = 0, + block_hash = compute_el_block_hash(spec, execution_payload, state), + transactions_root = spec.hash_tree_root(execution_payload.transactions), + ) + if is_post_capella(spec): + execution_payload_header.withdrawals_root = spec.Root() + + if is_post_deneb(spec): + execution_payload_header.blob_gas_used = 0 + execution_payload_header.excess_blob_gas = 0 + + return execution_payload_header + + +def build_randomized_execution_payload_header(spec, state, rng=Random(10000)): + execution_payload_header = build_empty_execution_payload_header(spec, state) + execution_payload = build_randomized_execution_payload(spec, state) + + execution_payload_header.fee_recipient = spec.ExecutionAddress(get_random_bytes_list(rng, 20)), + execution_payload_header.state_root = spec.Bytes32(get_random_bytes_list(rng, 32)), + execution_payload_header.receipts_root = spec.Bytes32(get_random_bytes_list(rng, 32)), + execution_payload_header.logs_bloom = spec.ByteVector[spec.BYTES_PER_LOGS_BLOOM]( + get_random_bytes_list(rng, spec.BYTES_PER_LOGS_BLOOM) + ), + execution_payload_header.prev_randao = spec.Bytes32(get_random_bytes_list(rng, 32)), + execution_payload_header.block_number = rng.randint(0, int(10e10)), + execution_payload_header.gas_limit = rng.randint(0, int(10e10)), + execution_payload_header.gas_used = rng.randint(0, int(10e10)), + extra_data_length = rng.randint(0, spec.MAX_EXTRA_DATA_BYTES) + execution_payload_header.extra_data = spec.ByteList[spec.MAX_EXTRA_DATA_BYTES]( + get_random_bytes_list(rng, extra_data_length) + ), + execution_payload_header.base_fee_per_gas = rng.randint(0, int(10e10)), + execution_payload_header.block_hash = compute_el_block_hash(spec, execution_payload, state), + execution_payload_header.transactions_root = spec.hash_tree_root(execution_payload.transactions), + + if is_post_capella(spec): + execution_payload_header.withdrawals_root = spec.hash_tree_root(execution_payload.withdrawals) + + if is_post_deneb(spec): + execution_payload_header.blob_gas_used = rng.randint(0, int(10e10)) + execution_payload_header.excess_blob_gas = rng.randint(0, int(10e10)) + + return execution_payload_header + + def build_empty_post_eip7732_execution_payload_header(spec, state): if not is_post_eip7732(spec): return @@ -351,6 +418,15 @@ def build_randomized_execution_payload(spec, state, rng): get_random_tx(rng) for _ in range(num_transactions) ] + if is_post_capella(spec): + num_withdrawals = rng.randint(0, spec.MAX_WITHDRAWALS_PER_PAYLOAD) + execution_payload.withdrawals = [ + get_random_withdrawal(spec, state, rng) + for _ in range(num_withdrawals) + ] + if is_post_deneb(spec): + execution_payload.blob_gas_used = rng.randint(0, int(10e10)) + execution_payload.excess_blob_gas = rng.randint(0, int(10e10)) execution_payload.block_hash = compute_el_block_hash(spec, execution_payload, state) diff --git a/tests/core/pyspec/eth2spec/test/helpers/random.py b/tests/core/pyspec/eth2spec/test/helpers/random.py index eb280076f6..de0eb5c800 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/random.py +++ b/tests/core/pyspec/eth2spec/test/helpers/random.py @@ -4,6 +4,7 @@ from eth2spec.test.helpers.deposits import mock_deposit from eth2spec.test.helpers.forks import is_post_altair from eth2spec.test.helpers.state import next_epoch +from eth2spec.test.helpers.execution_payload import build_randomized_execution_payload_header def set_some_activations(spec, state, rng, activation_epoch=None): @@ -162,6 +163,10 @@ def randomize_attestation_participation(spec, state, rng=Random(8020)): randomize_epoch_participation(spec, state, spec.get_current_epoch(state), rng) +def randomize_execution_payload_header(spec, state, rng=Random(8020)): + state.latest_execution_payload_header = build_randomized_execution_payload_header(spec, state, rng) + + def randomize_state(spec, state, rng=Random(8020), exit_fraction=0.5, slash_fraction=0.5): set_some_new_deposits(spec, state, rng) exit_random_validators(spec, state, rng, fraction=exit_fraction) diff --git a/tests/core/pyspec/eth2spec/test/helpers/withdrawals.py b/tests/core/pyspec/eth2spec/test/helpers/withdrawals.py index 1c9dec0060..5fb9d031a0 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/withdrawals.py +++ b/tests/core/pyspec/eth2spec/test/helpers/withdrawals.py @@ -9,6 +9,20 @@ def get_expected_withdrawals(spec, state): return spec.get_expected_withdrawals(state) +def get_random_withdrawal(spec, state, rng): + if is_post_electra: + amount = rng.randint(0, spec.MAX_EFFECTIVE_BALANCE_ELECTRA) + else: + amount = rng.randint(0, spec.MAX_EFFECTIVE_BALANCE) + + return spec.Withdrawal( + index=rng.randrange(0, spec.MAX_WITHDRAWALS_PER_PAYLOAD), + validator_index=rng.randrange(0, len(state.validators)), + address=rng.getrandbits(160).to_bytes(20, 'big'), + amount=amount, + ) + + def set_validator_fully_withdrawable(spec, state, index, withdrawable_epoch=None): if withdrawable_epoch is None: withdrawable_epoch = spec.get_current_epoch(state) diff --git a/tests/core/pyspec/eth2spec/test/utils/randomized_block_tests.py b/tests/core/pyspec/eth2spec/test/utils/randomized_block_tests.py index df67872880..8b9d7b5bc6 100644 --- a/tests/core/pyspec/eth2spec/test/utils/randomized_block_tests.py +++ b/tests/core/pyspec/eth2spec/test/utils/randomized_block_tests.py @@ -24,7 +24,8 @@ from eth2spec.test.helpers.random import ( randomize_state as randomize_state_helper, patch_state_to_non_leaking, -) + randomize_execution_payload_header, + ) from eth2spec.test.helpers.blob import ( get_sample_blob_tx, ) @@ -76,7 +77,7 @@ def randomize_state_bellatrix(spec, state, stats, exit_fraction=0.1, slash_fract stats, exit_fraction=exit_fraction, slash_fraction=slash_fraction) - # TODO: randomize execution payload, merge status, etc. + randomize_execution_payload_header(spec, state) return scenario_state From e9c9a0a1b7c6bfde25c3700b817251430903e162 Mon Sep 17 00:00:00 2001 From: Katya Ryazantseva Date: Mon, 16 Dec 2024 14:11:05 +0100 Subject: [PATCH 2/4] delete `build_empy_execution_payload_header` --- .../test/helpers/execution_payload.py | 70 ++++++------------- .../eth2spec/test/helpers/withdrawals.py | 2 +- .../test/utils/randomized_block_tests.py | 2 +- 3 files changed, 23 insertions(+), 51 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py b/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py index cf3cd08b59..403100c3b1 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py +++ b/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py @@ -267,58 +267,30 @@ def compute_el_block_hash_for_block(spec, block): spec, block.body.execution_payload, block.parent_root, requests_hash) -def build_empty_execution_payload_header(spec, state): - latest = state.latest_execution_payload_header - timestamp = spec.compute_timestamp_at_slot(state, state.slot) - execution_payload = build_empty_execution_payload(spec, state) - - execution_payload_header = spec.ExecutionPayloadHeader( - parent_hash = latest.block_hash, - fee_recipient = spec.ExecutionAddress(), - state_root = latest.state_root, - receipts_root = spec.Bytes32(), - logs_bloom = spec.ByteVector[spec.BYTES_PER_LOGS_BLOOM](), - prev_randao = spec.Bytes32(), - block_number = 0, - gas_limit = 0, - gas_used = 0, - timestamp = timestamp, - extra_data = spec.ByteList[spec.MAX_EXTRA_DATA_BYTES](), - base_fee_per_gas = 0, - block_hash = compute_el_block_hash(spec, execution_payload, state), - transactions_root = spec.hash_tree_root(execution_payload.transactions), - ) - if is_post_capella(spec): - execution_payload_header.withdrawals_root = spec.Root() - - if is_post_deneb(spec): - execution_payload_header.blob_gas_used = 0 - execution_payload_header.excess_blob_gas = 0 - - return execution_payload_header - - def build_randomized_execution_payload_header(spec, state, rng=Random(10000)): - execution_payload_header = build_empty_execution_payload_header(spec, state) execution_payload = build_randomized_execution_payload(spec, state) - - execution_payload_header.fee_recipient = spec.ExecutionAddress(get_random_bytes_list(rng, 20)), - execution_payload_header.state_root = spec.Bytes32(get_random_bytes_list(rng, 32)), - execution_payload_header.receipts_root = spec.Bytes32(get_random_bytes_list(rng, 32)), - execution_payload_header.logs_bloom = spec.ByteVector[spec.BYTES_PER_LOGS_BLOOM]( - get_random_bytes_list(rng, spec.BYTES_PER_LOGS_BLOOM) - ), - execution_payload_header.prev_randao = spec.Bytes32(get_random_bytes_list(rng, 32)), - execution_payload_header.block_number = rng.randint(0, int(10e10)), - execution_payload_header.gas_limit = rng.randint(0, int(10e10)), - execution_payload_header.gas_used = rng.randint(0, int(10e10)), extra_data_length = rng.randint(0, spec.MAX_EXTRA_DATA_BYTES) - execution_payload_header.extra_data = spec.ByteList[spec.MAX_EXTRA_DATA_BYTES]( - get_random_bytes_list(rng, extra_data_length) - ), - execution_payload_header.base_fee_per_gas = rng.randint(0, int(10e10)), - execution_payload_header.block_hash = compute_el_block_hash(spec, execution_payload, state), - execution_payload_header.transactions_root = spec.hash_tree_root(execution_payload.transactions), + + execution_payload_header = spec.ExecutionPayloadHeader( + parent_hash=spec.Hash32(spec.hash(bytearray(rng.getrandbits(8) for _ in range(32)))), + fee_recipient=spec.ExecutionAddress(get_random_bytes_list(rng, 20)), + state_root=spec.Bytes32(get_random_bytes_list(rng, 32)), + receipts_root=spec.Bytes32(get_random_bytes_list(rng, 32)), + logs_bloom=spec.ByteVector[spec.BYTES_PER_LOGS_BLOOM]( + get_random_bytes_list(rng, spec.BYTES_PER_LOGS_BLOOM) + ), + prev_randao=spec.Bytes32(get_random_bytes_list(rng, 32)), + block_number=rng.randint(0, int(10e10)), + gas_limit=rng.randint(0, int(10e10)), + gas_used=rng.randint(0, int(10e10)), + timestamp=spec.compute_timestamp_at_slot(state, state.slot), + extra_data=spec.ByteList[spec.MAX_EXTRA_DATA_BYTES]( + get_random_bytes_list(rng, extra_data_length) + ), + base_fee_per_gas=rng.randint(0, int(10e10)), + block_hash=compute_el_block_hash(spec, execution_payload, state), + transactions_root=spec.hash_tree_root(execution_payload.transactions), + ) if is_post_capella(spec): execution_payload_header.withdrawals_root = spec.hash_tree_root(execution_payload.withdrawals) diff --git a/tests/core/pyspec/eth2spec/test/helpers/withdrawals.py b/tests/core/pyspec/eth2spec/test/helpers/withdrawals.py index 5fb9d031a0..95efe7c968 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/withdrawals.py +++ b/tests/core/pyspec/eth2spec/test/helpers/withdrawals.py @@ -10,7 +10,7 @@ def get_expected_withdrawals(spec, state): def get_random_withdrawal(spec, state, rng): - if is_post_electra: + if is_post_electra(spec): amount = rng.randint(0, spec.MAX_EFFECTIVE_BALANCE_ELECTRA) else: amount = rng.randint(0, spec.MAX_EFFECTIVE_BALANCE) diff --git a/tests/core/pyspec/eth2spec/test/utils/randomized_block_tests.py b/tests/core/pyspec/eth2spec/test/utils/randomized_block_tests.py index 62bac29f55..0f436f97ac 100644 --- a/tests/core/pyspec/eth2spec/test/utils/randomized_block_tests.py +++ b/tests/core/pyspec/eth2spec/test/utils/randomized_block_tests.py @@ -25,7 +25,7 @@ randomize_state as randomize_state_helper, patch_state_to_non_leaking, randomize_execution_payload_header, - ) +) from eth2spec.test.helpers.blob import ( get_sample_blob_tx, ) From 05a323e83a8b2a5c04725c9bcd83b6b53e61a2dc Mon Sep 17 00:00:00 2001 From: Katya Ryazantseva Date: Thu, 19 Dec 2024 18:42:30 +0100 Subject: [PATCH 3/4] fix random withdrawals --- .../test/helpers/execution_payload.py | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py b/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py index 403100c3b1..8b1e2bc553 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py +++ b/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py @@ -8,10 +8,7 @@ from eth2spec.test.helpers.keys import privkeys from eth2spec.utils.ssz.ssz_impl import hash_tree_root from eth2spec.debug.random_value import get_random_bytes_list -from eth2spec.test.helpers.withdrawals import ( - get_expected_withdrawals, - get_random_withdrawal, -) +from eth2spec.test.helpers.withdrawals import get_expected_withdrawals from eth2spec.test.helpers.forks import ( is_post_capella, is_post_deneb, @@ -369,6 +366,7 @@ def build_empty_execution_payload(spec, state, randao_mix=None): def build_randomized_execution_payload(spec, state, rng): + from eth2spec.test.helpers.random import exit_random_validators execution_payload = build_empty_execution_payload(spec, state) execution_payload.fee_recipient = spec.ExecutionAddress(get_random_bytes_list(rng, 20)) execution_payload.state_root = spec.Bytes32(get_random_bytes_list(rng, 32)) @@ -390,12 +388,19 @@ def build_randomized_execution_payload(spec, state, rng): get_random_tx(rng) for _ in range(num_transactions) ] + if is_post_capella(spec): - num_withdrawals = rng.randint(0, spec.MAX_WITHDRAWALS_PER_PAYLOAD) - execution_payload.withdrawals = [ - get_random_withdrawal(spec, state, rng) - for _ in range(num_withdrawals) - ] + current_epoch = spec.get_current_epoch(state) + exit_random_validators( + spec, + state, + rng, + exit_epoch=current_epoch, + withdrawable_epoch=current_epoch, + from_epoch=current_epoch + ) + execution_payload.withdrawals = get_expected_withdrawals(spec, state) + if is_post_deneb(spec): execution_payload.blob_gas_used = rng.randint(0, int(10e10)) execution_payload.excess_blob_gas = rng.randint(0, int(10e10)) From 67607a8769eba9439f4ae668947544b2186ed6f6 Mon Sep 17 00:00:00 2001 From: Katya Ryazantseva Date: Fri, 20 Dec 2024 12:41:08 +0100 Subject: [PATCH 4/4] delete TODO comments --- tests/core/pyspec/eth2spec/test/utils/randomized_block_tests.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/utils/randomized_block_tests.py b/tests/core/pyspec/eth2spec/test/utils/randomized_block_tests.py index 0f436f97ac..0bc55eefab 100644 --- a/tests/core/pyspec/eth2spec/test/utils/randomized_block_tests.py +++ b/tests/core/pyspec/eth2spec/test/utils/randomized_block_tests.py @@ -87,7 +87,6 @@ def randomize_state_capella(spec, state, stats, exit_fraction=0.1, slash_fractio stats, exit_fraction=exit_fraction, slash_fraction=slash_fraction) - # TODO: randomize withdrawals return scenario_state @@ -97,7 +96,6 @@ def randomize_state_deneb(spec, state, stats, exit_fraction=0.1, slash_fraction= stats, exit_fraction=exit_fraction, slash_fraction=slash_fraction) - # TODO: randomize execution payload return scenario_state