diff --git a/setup.py b/setup.py index 9e5a546fa..f0befc8c7 100644 --- a/setup.py +++ b/setup.py @@ -451,9 +451,9 @@ def get_execution_state(execution_state_root: Bytes32) -> ExecutionState: def get_pow_chain_head() -> PowBlock: pass - +verify_execution_state_transition_ret_value = True def verify_execution_state_transition(execution_payload: ExecutionPayload) -> bool: - return True + return verify_execution_state_transition_ret_value def produce_execution_payload(parent_hash: Hash32, timestamp: uint64) -> ExecutionPayload: diff --git a/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py b/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py index 093b7cf2e..36e63dd33 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py +++ b/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py @@ -1,4 +1,3 @@ - def build_empty_execution_payload(spec, state): """ Assuming a pre-state of the same slot, build a valid ExecutionPayload without any transactions. @@ -24,3 +23,33 @@ def build_empty_execution_payload(spec, state): payload.block_hash = spec.Hash32(spec.hash(payload.hash_tree_root() + b"FAKE RLP HASH")) return payload + +def get_execution_payload_header(spec, execution_payload): + return spec.ExecutionPayloadHeader( + block_hash=execution_payload.block_hash, + parent_hash=execution_payload.parent_hash, + coinbase=execution_payload.coinbase, + state_root=execution_payload.state_root, + number=execution_payload.number, + gas_limit=execution_payload.gas_limit, + gas_used=execution_payload.gas_used, + timestamp=execution_payload.timestamp, + receipt_root=execution_payload.receipt_root, + logs_bloom=execution_payload.logs_bloom, + transactions_root=spec.hash_tree_root(execution_payload.transactions) + ) + +def build_state_with_incomplete_transition(spec, state): + return build_state_with_execution_payload_header(spec, state, spec.ExecutionPayloadHeader()) + +def build_state_with_complete_transition(spec, state): + pre_state_payload = build_empty_execution_payload(spec, state) + payload_header = get_execution_payload_header(spec, pre_state_payload) + + return build_state_with_execution_payload_header(spec, state, payload_header) + +def build_state_with_execution_payload_header(spec, state, execution_payload_header): + pre_state = state.copy() + pre_state.latest_execution_payload_header = execution_payload_header + + return pre_state diff --git a/tests/core/pyspec/eth2spec/test/merge/block_processing/test_process_execution_payload.py b/tests/core/pyspec/eth2spec/test/merge/block_processing/test_process_execution_payload.py index 6dbdc5e01..f1cd8ff25 100644 --- a/tests/core/pyspec/eth2spec/test/merge/block_processing/test_process_execution_payload.py +++ b/tests/core/pyspec/eth2spec/test/merge/block_processing/test_process_execution_payload.py @@ -1,4 +1,9 @@ -from eth2spec.test.helpers.execution_payload import build_empty_execution_payload +from eth2spec.test.helpers.execution_payload import ( + build_empty_execution_payload, + get_execution_payload_header, + build_state_with_incomplete_transition, + build_state_with_complete_transition, +) from eth2spec.test.context import spec_state_test, expect_assertion_error, with_merge_and_later from eth2spec.test.helpers.state import next_slot @@ -13,31 +18,36 @@ def run_execution_payload_processing(spec, state, execution_payload, valid=True, If ``valid == False``, run expecting ``AssertionError`` """ - pre_exec_header = state.latest_execution_payload_header.copy() - yield 'pre', state yield 'execution', {'execution_valid': execution_valid} yield 'execution_payload', execution_payload + + spec.verify_execution_state_transition_ret_value = execution_valid + if not valid: expect_assertion_error(lambda: spec.process_execution_payload(state, execution_payload)) yield 'post', None + spec.verify_execution_state_transition_ret_value = True return spec.process_execution_payload(state, execution_payload) yield 'post', state - assert pre_exec_header != state.latest_execution_payload_header - # TODO: any more assertions to make? + assert state.latest_execution_payload_header == get_execution_payload_header(spec, execution_payload) + + spec.verify_execution_state_transition_ret_value = True @with_merge_and_later @spec_state_test def test_success_first_payload(spec, state): + # pre-state + state = build_state_with_incomplete_transition(spec, state) next_slot(spec, state) - assert not spec.is_transition_completed(state) + # execution payload execution_payload = build_empty_execution_payload(spec, state) yield from run_execution_payload_processing(spec, state, execution_payload) @@ -46,11 +56,12 @@ def test_success_first_payload(spec, state): @with_merge_and_later @spec_state_test def test_success_regular_payload(spec, state): - # TODO: setup state - assert spec.is_transition_completed(state) + # pre-state + state = build_state_with_complete_transition(spec, state) + next_slot(spec, state) - # TODO: execution payload - execution_payload = spec.ExecutionPayload() + # execution payload + execution_payload = build_empty_execution_payload(spec, state) yield from run_execution_payload_processing(spec, state, execution_payload) @@ -58,12 +69,13 @@ def test_success_regular_payload(spec, state): @with_merge_and_later @spec_state_test def test_success_first_payload_with_gap_slot(spec, state): - # TODO: transition gap slot + # pre-state + state = build_state_with_incomplete_transition(spec, state) + next_slot(spec, state) + next_slot(spec, state) - assert not spec.is_transition_completed(state) - - # TODO: execution payload - execution_payload = spec.ExecutionPayload() + # execution payload + execution_payload = build_empty_execution_payload(spec, state) yield from run_execution_payload_processing(spec, state, execution_payload) @@ -71,12 +83,13 @@ def test_success_first_payload_with_gap_slot(spec, state): @with_merge_and_later @spec_state_test def test_success_regular_payload_with_gap_slot(spec, state): - # TODO: setup state - assert spec.is_transition_completed(state) - # TODO: transition gap slot + # pre-state + state = build_state_with_complete_transition(spec, state) + next_slot(spec, state) + next_slot(spec, state) - # TODO: execution payload - execution_payload = spec.ExecutionPayload() + # execution payload + execution_payload = build_empty_execution_payload(spec, state) yield from run_execution_payload_processing(spec, state, execution_payload) @@ -86,8 +99,12 @@ def test_success_regular_payload_with_gap_slot(spec, state): def test_bad_execution_first_payload(spec, state): # completely valid payload, but execution itself fails (e.g. block exceeds gas limit) - # TODO: execution payload. - execution_payload = spec.ExecutionPayload() + # pre-state + state = build_state_with_incomplete_transition(spec, state) + next_slot(spec, state) + + # execution payload + execution_payload = build_empty_execution_payload(spec, state) yield from run_execution_payload_processing(spec, state, execution_payload, valid=False, execution_valid=False) @@ -97,35 +114,55 @@ def test_bad_execution_first_payload(spec, state): def test_bad_execution_regular_payload(spec, state): # completely valid payload, but execution itself fails (e.g. block exceeds gas limit) - # TODO: execution payload - execution_payload = spec.ExecutionPayload() + # pre-state + state = build_state_with_complete_transition(spec, state) + next_slot(spec, state) + + # execution payload + execution_payload = build_empty_execution_payload(spec, state) yield from run_execution_payload_processing(spec, state, execution_payload, valid=False, execution_valid=False) @with_merge_and_later @spec_state_test -def test_bad_parent_hash_first_payload(spec, state): - # TODO: execution payload - execution_payload = spec.ExecutionPayload() +def test_bad_parent_hash_regular_payload(spec, state): + # pre-state + state = build_state_with_complete_transition(spec, state) + next_slot(spec, state) + + # execution payload + execution_payload = build_empty_execution_payload(spec, state) + execution_payload.parent_hash = spec.Hash32() yield from run_execution_payload_processing(spec, state, execution_payload, valid=False) @with_merge_and_later @spec_state_test -def test_bad_number_first_payload(spec, state): - # TODO: execution payload - execution_payload = spec.ExecutionPayload() +def test_bad_number_regular_payload(spec, state): + # pre-state + state = build_state_with_complete_transition(spec, state) + next_slot(spec, state) + + # execution payload + execution_payload = build_empty_execution_payload(spec, state) + execution_payload.number = execution_payload.number + 1 yield from run_execution_payload_processing(spec, state, execution_payload, valid=False) @with_merge_and_later @spec_state_test -def test_bad_everything_first_payload(spec, state): - # TODO: execution payload - execution_payload = spec.ExecutionPayload() +def test_bad_everything_regular_payload(spec, state): + # pre-state + state = build_state_with_complete_transition(spec, state) + next_slot(spec, state) + + # execution payload + execution_payload = build_empty_execution_payload(spec, state) + execution_payload.parent_hash = spec.Hash32() + execution_payload.number = execution_payload.number + 1 yield from run_execution_payload_processing(spec, state, execution_payload, valid=False) @@ -133,8 +170,13 @@ def test_bad_everything_first_payload(spec, state): @with_merge_and_later @spec_state_test def test_bad_timestamp_first_payload(spec, state): - # TODO: execution payload - execution_payload = spec.ExecutionPayload() + # pre-state + state = build_state_with_incomplete_transition(spec, state) + next_slot(spec, state) + + # execution payload + execution_payload = build_empty_execution_payload(spec, state) + execution_payload.timestamp = execution_payload.timestamp + 1 yield from run_execution_payload_processing(spec, state, execution_payload, valid=False) @@ -142,7 +184,12 @@ def test_bad_timestamp_first_payload(spec, state): @with_merge_and_later @spec_state_test def test_bad_timestamp_regular_payload(spec, state): - # TODO: execution payload - execution_payload = spec.ExecutionPayload() + # pre-state + state = build_state_with_complete_transition(spec, state) + next_slot(spec, state) + + # execution payload + execution_payload = build_empty_execution_payload(spec, state) + execution_payload.timestamp = execution_payload.timestamp + 1 yield from run_execution_payload_processing(spec, state, execution_payload, valid=False)