From 8319d070848c55bda44ddbbfe72020cbcaf39b8d Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Mon, 17 Jan 2022 17:38:24 +0100 Subject: [PATCH 01/10] Consistently use `compute_sync_committee_period` There were a couple instances where a division was used on an epoch to derive the corresponding sync committee period instead of calling the `compute_sync_committee_period` function. These instances were changed to also use the function. --- specs/altair/sync-protocol.md | 8 ++++---- .../test_process_sync_committee_updates.py | 2 +- .../eth2spec/test/altair/unittests/test_sync_protocol.py | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/specs/altair/sync-protocol.md b/specs/altair/sync-protocol.md index fe7882ff9..09d75129c 100644 --- a/specs/altair/sync-protocol.md +++ b/specs/altair/sync-protocol.md @@ -157,8 +157,8 @@ def validate_light_client_update(store: LightClientStore, assert current_slot >= active_header.slot > store.finalized_header.slot # Verify update does not skip a sync committee period - finalized_period = compute_epoch_at_slot(store.finalized_header.slot) // EPOCHS_PER_SYNC_COMMITTEE_PERIOD - update_period = compute_epoch_at_slot(active_header.slot) // EPOCHS_PER_SYNC_COMMITTEE_PERIOD + finalized_period = compute_sync_committee_period(compute_epoch_at_slot(store.finalized_header.slot)) + update_period = compute_sync_committee_period(compute_epoch_at_slot(active_header.slot)) assert update_period in (finalized_period, finalized_period + 1) # Verify that the `finalized_header`, if present, actually is the finalized header saved in the @@ -208,8 +208,8 @@ def validate_light_client_update(store: LightClientStore, ```python def apply_light_client_update(store: LightClientStore, update: LightClientUpdate) -> None: active_header = get_active_header(update) - finalized_period = compute_epoch_at_slot(store.finalized_header.slot) // EPOCHS_PER_SYNC_COMMITTEE_PERIOD - update_period = compute_epoch_at_slot(active_header.slot) // EPOCHS_PER_SYNC_COMMITTEE_PERIOD + finalized_period = compute_sync_committee_period(compute_epoch_at_slot(store.finalized_header.slot)) + update_period = compute_sync_committee_period(compute_epoch_at_slot(active_header.slot)) if update_period == finalized_period + 1: store.current_sync_committee = store.next_sync_committee store.next_sync_committee = update.next_sync_committee diff --git a/tests/core/pyspec/eth2spec/test/altair/epoch_processing/test_process_sync_committee_updates.py b/tests/core/pyspec/eth2spec/test/altair/epoch_processing/test_process_sync_committee_updates.py index 1667a12b2..4b0cb70d5 100644 --- a/tests/core/pyspec/eth2spec/test/altair/epoch_processing/test_process_sync_committee_updates.py +++ b/tests/core/pyspec/eth2spec/test/altair/epoch_processing/test_process_sync_committee_updates.py @@ -24,7 +24,7 @@ def run_sync_committees_progress_test(spec, state): first_sync_committee = state.current_sync_committee.copy() second_sync_committee = state.next_sync_committee.copy() - current_period = spec.get_current_epoch(state) // spec.EPOCHS_PER_SYNC_COMMITTEE_PERIOD + current_period = spec.compute_sync_committee_period(spec.get_current_epoch(state)) next_period = current_period + 1 next_period_start_epoch = next_period * spec.EPOCHS_PER_SYNC_COMMITTEE_PERIOD next_period_start_slot = next_period_start_epoch * spec.SLOTS_PER_EPOCH diff --git a/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py b/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py index 120004654..df0b33421 100644 --- a/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py +++ b/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py @@ -98,8 +98,8 @@ def test_process_light_client_update_timeout(spec, state): # Forward to next sync committee period next_slots(spec, state, spec.UPDATE_TIMEOUT) - snapshot_period = spec.compute_epoch_at_slot(store.optimistic_header.slot) // spec.EPOCHS_PER_SYNC_COMMITTEE_PERIOD - update_period = spec.compute_epoch_at_slot(state.slot) // spec.EPOCHS_PER_SYNC_COMMITTEE_PERIOD + snapshot_period = spec.compute_sync_committee_period(spec.compute_epoch_at_slot(store.optimistic_header.slot)) + update_period = spec.compute_sync_committee_period(spec.compute_epoch_at_slot(state.slot)) assert snapshot_period + 1 == update_period block = build_empty_block_for_next_slot(spec, state) @@ -169,8 +169,8 @@ def test_process_light_client_update_finality_updated(spec, state): # Ensure that finality checkpoint has changed assert state.finalized_checkpoint.epoch == 3 # Ensure that it's same period - snapshot_period = spec.compute_epoch_at_slot(store.optimistic_header.slot) // spec.EPOCHS_PER_SYNC_COMMITTEE_PERIOD - update_period = spec.compute_epoch_at_slot(state.slot) // spec.EPOCHS_PER_SYNC_COMMITTEE_PERIOD + snapshot_period = spec.compute_sync_committee_period(spec.compute_epoch_at_slot(store.optimistic_header.slot)) + update_period = spec.compute_sync_committee_period(spec.compute_epoch_at_slot(state.slot)) assert snapshot_period == update_period # Updated sync_committee and finality From 0e9460b8ddb86d65f92a1a8b54ccc68906bbd77e Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Tue, 25 Jan 2022 10:09:10 +0100 Subject: [PATCH 02/10] Ensure light client `optimistic_header` to be at head When a light client updates its `finalized_header` using a forced update because of the timeout, and the new header was not signed by enough sync committee participants to pass `get_safety_threshold(store)`, it may occur that `store.finalized_header.slot > store.optimistic_header.slot`. This patch ensures that the `optimistic_header` is updated to the latest `finalized_header` if that happens, so that it always indicates the latest known and accepted head. --- specs/altair/sync-protocol.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specs/altair/sync-protocol.md b/specs/altair/sync-protocol.md index fe7882ff9..a4a57a91b 100644 --- a/specs/altair/sync-protocol.md +++ b/specs/altair/sync-protocol.md @@ -214,6 +214,8 @@ def apply_light_client_update(store: LightClientStore, update: LightClientUpdate store.current_sync_committee = store.next_sync_committee store.next_sync_committee = update.next_sync_committee store.finalized_header = active_header + if store.finalized_header.slot > store.optimistic_header.slot: + store.optimistic_header = store.finalized_header ``` #### `process_light_client_update` From 20c8d0d641eb62f869d03f6a8560db15ea55c397 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Thu, 27 Jan 2022 23:57:52 +0100 Subject: [PATCH 03/10] Update reserved libp2p error documentation The spec reserves the libp2p error code range `[3, 127]` for future use but actually defines error code `3` as `ResourceUnavailable`. This patch updates the reserved range to `[4, 127]`. --- specs/das/p2p-interface.md | 5 ----- specs/phase0/p2p-interface.md | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/specs/das/p2p-interface.md b/specs/das/p2p-interface.md index b4a0a9d2c..b1d96c718 100644 --- a/specs/das/p2p-interface.md +++ b/specs/das/p2p-interface.md @@ -196,11 +196,6 @@ This builds on top of the protocol identification and encoding spec which was in Note that DAS networking uses a different protocol prefix: `/eth2/das/req` -The result codes are extended with: -- 3: **ResourceUnavailable** -- when the request was valid but cannot be served at this point in time. - -TODO: unify with phase0? Lighthoue already defined this in their response codes enum. - ### Messages #### DASQuery diff --git a/specs/phase0/p2p-interface.md b/specs/phase0/p2p-interface.md index f5c138f99..4532feac8 100644 --- a/specs/phase0/p2p-interface.md +++ b/specs/phase0/p2p-interface.md @@ -569,11 +569,11 @@ The response code can have one of the following values, encoded as a single unsi The response payload adheres to the `ErrorMessage` schema (described below). - 3: **ResourceUnavailable** -- the responder does not have requested resource. The response payload adheres to the `ErrorMessage` schema (described below). - *Note*: This response code is only valid as a response to `BlocksByRange`. + *Note*: This response code is only valid as a response where specified. Clients MAY use response codes above `128` to indicate alternative, erroneous request-specific responses. -The range `[3, 127]` is RESERVED for future usages, and should be treated as error if not recognized expressly. +The range `[4, 127]` is RESERVED for future usages, and should be treated as error if not recognized expressly. The `ErrorMessage` schema is: From 3d7f3070208f98d6e9e8356d3acbe31474501046 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 4 Feb 2022 17:46:37 -0800 Subject: [PATCH 04/10] Refactor test_sync_protocol.py a bit --- .../altair/unittests/test_sync_protocol.py | 75 ++++--------------- .../eth2spec/test/helpers/light_client.py | 35 +++++++++ 2 files changed, 50 insertions(+), 60 deletions(-) create mode 100644 tests/core/pyspec/eth2spec/test/helpers/light_client.py diff --git a/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py b/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py index df0b33421..04553b3f8 100644 --- a/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py +++ b/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py @@ -5,38 +5,29 @@ from eth2spec.test.context import ( with_presets, with_altair_and_later, ) -from eth2spec.test.helpers.attestations import next_epoch_with_attestations +from eth2spec.test.helpers.attestations import ( + next_epoch_with_attestations, +) from eth2spec.test.helpers.block import ( build_empty_block, build_empty_block_for_next_slot, ) from eth2spec.test.helpers.constants import MINIMAL +from eth2spec.test.helpers.light_client import ( + get_sync_aggregate, + initialize_light_client_store, +) from eth2spec.test.helpers.state import ( next_slots, state_transition_and_sign_block, ) -from eth2spec.test.helpers.sync_committee import ( - compute_aggregate_sync_committee_signature, -) from eth2spec.test.helpers.merkle import build_proof -def _initialize_light_client_store(spec, state): - return spec.LightClientStore( - finalized_header=spec.BeaconBlockHeader(), - current_sync_committee=state.current_sync_committee, - next_sync_committee=state.next_sync_committee, - best_valid_update=None, - optimistic_header=spec.BeaconBlockHeader(), - previous_max_active_participants=0, - current_max_active_participants=0, - ) - - @with_altair_and_later @spec_state_test def test_process_light_client_update_not_timeout(spec, state): - store = _initialize_light_client_store(spec, state) + store = initialize_light_client_store(spec, state) # Block at slot 1 doesn't increase sync committee period, so it won't force update store.finalized_header block = build_empty_block_for_next_slot(spec, state) @@ -49,19 +40,7 @@ def test_process_light_client_update_not_timeout(spec, state): body_root=signed_block.message.body.hash_tree_root(), ) # Sync committee signing the header - all_pubkeys = [v.pubkey for v in state.validators] - committee = [all_pubkeys.index(pubkey) for pubkey in state.current_sync_committee.pubkeys] - sync_committee_bits = [True] * len(committee) - sync_committee_signature = compute_aggregate_sync_committee_signature( - spec, - state, - block_header.slot, - committee, - ) - sync_aggregate = spec.SyncAggregate( - sync_committee_bits=sync_committee_bits, - sync_committee_signature=sync_committee_signature, - ) + sync_aggregate = get_sync_aggregate(spec, state, block_header, block_root=None) next_sync_committee_branch = [spec.Bytes32() for _ in range(spec.floorlog2(spec.NEXT_SYNC_COMMITTEE_INDEX))] # Ensure that finality checkpoint is genesis @@ -94,7 +73,7 @@ def test_process_light_client_update_not_timeout(spec, state): @spec_state_test @with_presets([MINIMAL], reason="too slow") def test_process_light_client_update_timeout(spec, state): - store = _initialize_light_client_store(spec, state) + store = initialize_light_client_store(spec, state) # Forward to next sync committee period next_slots(spec, state, spec.UPDATE_TIMEOUT) @@ -113,20 +92,8 @@ def test_process_light_client_update_timeout(spec, state): ) # Sync committee signing the finalized_block_header - all_pubkeys = [v.pubkey for v in state.validators] - committee = [all_pubkeys.index(pubkey) for pubkey in state.current_sync_committee.pubkeys] - sync_committee_bits = [True] * len(committee) - sync_committee_signature = compute_aggregate_sync_committee_signature( - spec, - state, - block_header.slot, - committee, - block_root=spec.Root(block_header.hash_tree_root()), - ) - sync_aggregate = spec.SyncAggregate( - sync_committee_bits=sync_committee_bits, - sync_committee_signature=sync_committee_signature, - ) + sync_aggregate = get_sync_aggregate( + spec, state, block_header, block_root=spec.Root(block_header.hash_tree_root())) # Sync committee is updated next_sync_committee_branch = build_proof(state.get_backing(), spec.NEXT_SYNC_COMMITTEE_INDEX) @@ -158,7 +125,7 @@ def test_process_light_client_update_timeout(spec, state): @spec_state_test @with_presets([MINIMAL], reason="too slow") def test_process_light_client_update_finality_updated(spec, state): - store = _initialize_light_client_store(spec, state) + store = initialize_light_client_store(spec, state) # Change finality blocks = [] @@ -191,20 +158,8 @@ def test_process_light_client_update_finality_updated(spec, state): ) # Sync committee signing the finalized_block_header - all_pubkeys = [v.pubkey for v in state.validators] - committee = [all_pubkeys.index(pubkey) for pubkey in state.current_sync_committee.pubkeys] - sync_committee_bits = [True] * len(committee) - sync_committee_signature = compute_aggregate_sync_committee_signature( - spec, - state, - block_header.slot, - committee, - block_root=spec.Root(block_header.hash_tree_root()), - ) - sync_aggregate = spec.SyncAggregate( - sync_committee_bits=sync_committee_bits, - sync_committee_signature=sync_committee_signature, - ) + sync_aggregate = get_sync_aggregate( + spec, state, block_header, block_root=spec.Root(block_header.hash_tree_root())) update = spec.LightClientUpdate( attested_header=block_header, diff --git a/tests/core/pyspec/eth2spec/test/helpers/light_client.py b/tests/core/pyspec/eth2spec/test/helpers/light_client.py new file mode 100644 index 000000000..15c764fc4 --- /dev/null +++ b/tests/core/pyspec/eth2spec/test/helpers/light_client.py @@ -0,0 +1,35 @@ +from eth2spec.test.helpers.sync_committee import ( + compute_aggregate_sync_committee_signature, +) + + +def initialize_light_client_store(spec, state): + return spec.LightClientStore( + finalized_header=spec.BeaconBlockHeader(), + current_sync_committee=state.current_sync_committee, + next_sync_committee=state.next_sync_committee, + best_valid_update=None, + optimistic_header=spec.BeaconBlockHeader(), + previous_max_active_participants=0, + current_max_active_participants=0, + ) + + +def get_sync_aggregate(spec, state, block_header, block_root=None, signature_slot=None): + if signature_slot is None: + signature_slot = block_header.slot + + all_pubkeys = [v.pubkey for v in state.validators] + committee = [all_pubkeys.index(pubkey) for pubkey in state.current_sync_committee.pubkeys] + sync_committee_bits = [True] * len(committee) + sync_committee_signature = compute_aggregate_sync_committee_signature( + spec, + state, + block_header.slot, + committee, + block_root=block_root, + ) + return spec.SyncAggregate( + sync_committee_bits=sync_committee_bits, + sync_committee_signature=sync_committee_signature, + ) From 7c492ce4ce5043f1d8f32d8d02ab76642774fe87 Mon Sep 17 00:00:00 2001 From: terence tsao Date: Sun, 6 Feb 2022 13:32:21 -0800 Subject: [PATCH 05/10] Fix typo --- sync/optimistic.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sync/optimistic.md b/sync/optimistic.md index b44384d34..8e6acc442 100644 --- a/sync/optimistic.md +++ b/sync/optimistic.md @@ -82,9 +82,9 @@ def is_execution_block(block: BeaconBlock) -> bool: ```python def is_optimistic_candidate_block(opt_store: OptimisticStore, current_slot: Slot, block: BeaconBlock) -> bool: justified_root = opt_store.block_states[opt_store.head_block_root].current_justified_checkpoint.root - justifed_is_execution_block = is_execution_block(opt_store.blocks[justified_root]) + justified_is_execution_block = is_execution_block(opt_store.blocks[justified_root]) block_is_deep = block.slot + SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY <= current_slot - return justifed_is_execution_block or block_is_deep + return justified_is_execution_block or block_is_deep ``` Let only a node which returns `is_optimistic(opt_store, head) is True` be an *optimistic From 6d11d627f8b125166947d055d055c439baaa4aea Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Wed, 9 Feb 2022 18:06:10 -0700 Subject: [PATCH 06/10] Refactoring: add `is_finality_update` helper --- specs/altair/sync-protocol.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/specs/altair/sync-protocol.md b/specs/altair/sync-protocol.md index 36b634742..f6809eab5 100644 --- a/specs/altair/sync-protocol.md +++ b/specs/altair/sync-protocol.md @@ -16,6 +16,7 @@ - [`LightClientUpdate`](#lightclientupdate) - [`LightClientStore`](#lightclientstore) - [Helper functions](#helper-functions) + - [`is_finality_update`](#is_finality_update) - [`get_subtree_index`](#get_subtree_index) - [`get_active_header`](#get_active_header) - [`get_safety_threshold`](#get_safety_threshold) @@ -95,6 +96,13 @@ class LightClientStore(object): ## Helper functions +### `is_finality_update` + +```python +def is_finality_update(update: LightClientUpdate) -> bool: + return update.finalized_header != BeaconBlockHeader() +``` + ### `get_subtree_index` ```python @@ -109,7 +117,7 @@ def get_active_header(update: LightClientUpdate) -> BeaconBlockHeader: # The "active header" is the header that the update is trying to convince us # to accept. If a finalized header is present, it's the finalized header, # otherwise it's the attested header - if update.finalized_header != BeaconBlockHeader(): + if is_finality_update(update): return update.finalized_header else: return update.attested_header @@ -163,7 +171,7 @@ def validate_light_client_update(store: LightClientStore, # Verify that the `finalized_header`, if present, actually is the finalized header saved in the # state of the `attested header` - if update.finalized_header == BeaconBlockHeader(): + if not is_finality_update(update): assert update.finality_branch == [Bytes32() for _ in range(floorlog2(FINALIZED_ROOT_INDEX))] else: assert is_valid_merkle_branch( @@ -252,7 +260,7 @@ def process_light_client_update(store: LightClientStore, # Update finalized header if ( sum(sync_committee_bits) * 3 >= len(sync_committee_bits) * 2 - and update.finalized_header != BeaconBlockHeader() + and is_finality_update(update) ): # Normal update through 2/3 threshold apply_light_client_update(store, update) From 9fb2dd16c15279a53e0b9b3f51b7f7293a9293e0 Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Fri, 11 Feb 2022 17:12:13 +0100 Subject: [PATCH 07/10] Ignore attestations voting for the wrong finalized checkpoint When nodes are syncing but have not yet reached the canonical `head`, they cannot determine whether nodes they are connected to serve a valid history or are making bogus claims in their `Status` advertisement. Thus, the best course of action that a client can take is to vote for its "current" best synced head, regardless of whether it's connected to peers that claim to have other heads or not. However, in the p2p spec, we penalize such peers with a `REJECT` - this should be an `IGNORE` instead because this vote is correct per the spec, albeit "late" according to the validating clients' view of the chain. --- specs/phase0/p2p-interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/phase0/p2p-interface.md b/specs/phase0/p2p-interface.md index 4532feac8..344b417cf 100644 --- a/specs/phase0/p2p-interface.md +++ b/specs/phase0/p2p-interface.md @@ -424,7 +424,7 @@ The following validations MUST pass before forwarding the `attestation` on the s - _[REJECT]_ The block being voted for (`attestation.data.beacon_block_root`) passes validation. - _[REJECT]_ The attestation's target block is an ancestor of the block named in the LMD vote -- i.e. `get_ancestor(store, attestation.data.beacon_block_root, compute_start_slot_at_epoch(attestation.data.target.epoch)) == attestation.data.target.root` -- _[REJECT]_ The current `finalized_checkpoint` is an ancestor of the `block` defined by `attestation.data.beacon_block_root` -- i.e. +- _[IGNORE]_ The current `finalized_checkpoint` is an ancestor of the `block` defined by `attestation.data.beacon_block_root` -- i.e. `get_ancestor(store, attestation.data.beacon_block_root, compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)) == store.finalized_checkpoint.root` From 1280fe2a02d60b87dab108a8bfa5b3338528b7c4 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Tue, 22 Feb 2022 17:16:33 +0600 Subject: [PATCH 08/10] Bellatrix: random -> prev_randao --- specs/bellatrix/beacon-chain.md | 10 +++++----- specs/bellatrix/fork-choice.md | 2 +- specs/bellatrix/validator.md | 2 +- .../block_processing/test_process_execution_payload.py | 6 +++--- .../bellatrix/unittests/validator/test_validator.py | 2 +- .../pyspec/eth2spec/test/helpers/execution_payload.py | 4 ++-- tests/core/pyspec/eth2spec/test/helpers/genesis.py | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/specs/bellatrix/beacon-chain.md b/specs/bellatrix/beacon-chain.md index 63bad7f08..b37a8ab71 100644 --- a/specs/bellatrix/beacon-chain.md +++ b/specs/bellatrix/beacon-chain.md @@ -171,7 +171,7 @@ class ExecutionPayload(Container): state_root: Bytes32 receipts_root: Bytes32 logs_bloom: ByteVector[BYTES_PER_LOGS_BLOOM] - random: Bytes32 # 'difficulty' in the yellow paper + prev_randao: Bytes32 # 'difficulty' in the yellow paper block_number: uint64 # 'number' in the yellow paper gas_limit: uint64 gas_used: uint64 @@ -193,7 +193,7 @@ class ExecutionPayloadHeader(Container): state_root: Bytes32 receipts_root: Bytes32 logs_bloom: ByteVector[BYTES_PER_LOGS_BLOOM] - random: Bytes32 + prev_randao: Bytes32 block_number: uint64 gas_limit: uint64 gas_used: uint64 @@ -348,8 +348,8 @@ def process_execution_payload(state: BeaconState, payload: ExecutionPayload, exe # Verify consistency of the parent hash with respect to the previous execution payload header if is_merge_transition_complete(state): assert payload.parent_hash == state.latest_execution_payload_header.block_hash - # Verify random - assert payload.random == get_randao_mix(state, get_current_epoch(state)) + # Verify prev_randao + assert payload.prev_randao == get_randao_mix(state, get_current_epoch(state)) # Verify timestamp assert payload.timestamp == compute_timestamp_at_slot(state, state.slot) # Verify the execution payload is valid @@ -361,7 +361,7 @@ def process_execution_payload(state: BeaconState, payload: ExecutionPayload, exe state_root=payload.state_root, receipts_root=payload.receipts_root, logs_bloom=payload.logs_bloom, - random=payload.random, + prev_randao=payload.prev_randao, block_number=payload.block_number, gas_limit=payload.gas_limit, gas_used=payload.gas_used, diff --git a/specs/bellatrix/fork-choice.md b/specs/bellatrix/fork-choice.md index 91fda88bc..0f5a7b646 100644 --- a/specs/bellatrix/fork-choice.md +++ b/specs/bellatrix/fork-choice.md @@ -80,7 +80,7 @@ Used to signal to initiate the payload build process via `notify_forkchoice_upda @dataclass class PayloadAttributes(object): timestamp: uint64 - random: Bytes32 + prev_randao: Bytes32 suggested_fee_recipient: ExecutionAddress ``` diff --git a/specs/bellatrix/validator.md b/specs/bellatrix/validator.md index 7e0369a39..47de49ba6 100644 --- a/specs/bellatrix/validator.md +++ b/specs/bellatrix/validator.md @@ -143,7 +143,7 @@ def prepare_execution_payload(state: BeaconState, # Set the forkchoice head and initiate the payload build process payload_attributes = PayloadAttributes( timestamp=compute_timestamp_at_slot(state, state.slot), - random=get_randao_mix(state, get_current_epoch(state)), + prev_randao=get_randao_mix(state, get_current_epoch(state)), suggested_fee_recipient=suggested_fee_recipient, ) return execution_engine.notify_forkchoice_updated(parent_hash, finalized_block_hash, payload_attributes) diff --git a/tests/core/pyspec/eth2spec/test/bellatrix/block_processing/test_process_execution_payload.py b/tests/core/pyspec/eth2spec/test/bellatrix/block_processing/test_process_execution_payload.py index a24e3e199..cd7a74259 100644 --- a/tests/core/pyspec/eth2spec/test/bellatrix/block_processing/test_process_execution_payload.py +++ b/tests/core/pyspec/eth2spec/test/bellatrix/block_processing/test_process_execution_payload.py @@ -153,7 +153,7 @@ def test_bad_random_first_payload(spec, state): # execution payload execution_payload = build_empty_execution_payload(spec, state) - execution_payload.random = b'\x42' * 32 + execution_payload.prev_randao = b'\x42' * 32 yield from run_execution_payload_processing(spec, state, execution_payload, valid=False) @@ -167,7 +167,7 @@ def test_bad_random_regular_payload(spec, state): # execution payload execution_payload = build_empty_execution_payload(spec, state) - execution_payload.random = b'\x04' * 32 + execution_payload.prev_randao = b'\x04' * 32 yield from run_execution_payload_processing(spec, state, execution_payload, valid=False) @@ -182,7 +182,7 @@ def test_bad_everything_regular_payload(spec, state): # execution payload execution_payload = build_empty_execution_payload(spec, state) execution_payload.parent_hash = spec.Hash32() - execution_payload.random = spec.Bytes32() + execution_payload.prev_randao = spec.Bytes32() execution_payload.timestamp = 0 yield from run_execution_payload_processing(spec, state, execution_payload, valid=False) diff --git a/tests/core/pyspec/eth2spec/test/bellatrix/unittests/validator/test_validator.py b/tests/core/pyspec/eth2spec/test/bellatrix/unittests/validator/test_validator.py index 5e767d2cd..05a941dfe 100644 --- a/tests/core/pyspec/eth2spec/test/bellatrix/unittests/validator/test_validator.py +++ b/tests/core/pyspec/eth2spec/test/bellatrix/unittests/validator/test_validator.py @@ -103,7 +103,7 @@ def test_prepare_execution_payload(spec, state): # 1. Handle `is_merge_complete` if is_merge_complete: - state.latest_execution_payload_header = spec.ExecutionPayloadHeader(random=b'\x12' * 32) + state.latest_execution_payload_header = spec.ExecutionPayloadHeader(prev_randao=b'\x12' * 32) else: state.latest_execution_payload_header = spec.ExecutionPayloadHeader() diff --git a/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py b/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py index 49cec884a..14602a2cd 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py +++ b/tests/core/pyspec/eth2spec/test/helpers/execution_payload.py @@ -16,7 +16,7 @@ def build_empty_execution_payload(spec, state, randao_mix=None): receipts_root=b"no receipts here" + b"\x00" * 16, # TODO: root of empty MPT may be better. logs_bloom=spec.ByteVector[spec.BYTES_PER_LOGS_BLOOM](), # TODO: zeroed logs bloom for empty logs ok? block_number=latest.block_number + 1, - random=randao_mix, + prev_randao=randao_mix, gas_limit=latest.gas_limit, # retain same limit gas_used=0, # empty block, 0 gas timestamp=timestamp, @@ -38,7 +38,7 @@ def get_execution_payload_header(spec, execution_payload): state_root=execution_payload.state_root, receipts_root=execution_payload.receipts_root, logs_bloom=execution_payload.logs_bloom, - random=execution_payload.random, + prev_randao=execution_payload.prev_randao, block_number=execution_payload.block_number, gas_limit=execution_payload.gas_limit, gas_used=execution_payload.gas_used, diff --git a/tests/core/pyspec/eth2spec/test/helpers/genesis.py b/tests/core/pyspec/eth2spec/test/helpers/genesis.py index 0539a5d74..d0e470893 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/genesis.py +++ b/tests/core/pyspec/eth2spec/test/helpers/genesis.py @@ -30,7 +30,7 @@ def get_sample_genesis_execution_payload_header(spec, state_root=b'\x20' * 32, receipts_root=b'\x20' * 32, logs_bloom=b'\x35' * spec.BYTES_PER_LOGS_BLOOM, - random=eth1_block_hash, + prev_randao=eth1_block_hash, block_number=0, gas_limit=30000000, base_fee_per_gas=1000000000, From 03f0f6762a66a3091b0a2fdfc9c334a77ae474e0 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 25 Feb 2022 10:22:07 -0700 Subject: [PATCH 09/10] revert removal of aggregate deduplication condition from #2183 --- specs/phase0/p2p-interface.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specs/phase0/p2p-interface.md b/specs/phase0/p2p-interface.md index 4532feac8..092037e72 100644 --- a/specs/phase0/p2p-interface.md +++ b/specs/phase0/p2p-interface.md @@ -337,6 +337,8 @@ The following validations MUST pass before forwarding the `signed_aggregate_and_ (a client MAY queue future aggregates for processing at the appropriate slot). - _[REJECT]_ The aggregate attestation's epoch matches its target -- i.e. `aggregate.data.target.epoch == compute_epoch_at_slot(aggregate.data.slot)` +- _[IGNORE]_ The valid aggregate attestation defined by `hash_tree_root(aggregate)` has _not_ already been seen + (via aggregate gossip, within a verified block, or through the creation of an equivalent aggregate locally). - _[IGNORE]_ The `aggregate` is the first valid aggregate received for the aggregator with index `aggregate_and_proof.aggregator_index` for the epoch `aggregate.data.target.epoch`. - _[REJECT]_ The attestation has participants -- From 1fb7a953293d6cf4a26f8587bc5db827a9cc5002 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 25 Feb 2022 11:23:15 -0700 Subject: [PATCH 10/10] bump VERSION.txt to 1.1.10 --- tests/core/pyspec/eth2spec/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/pyspec/eth2spec/VERSION.txt b/tests/core/pyspec/eth2spec/VERSION.txt index a5e428299..9695327b3 100644 --- a/tests/core/pyspec/eth2spec/VERSION.txt +++ b/tests/core/pyspec/eth2spec/VERSION.txt @@ -1 +1 @@ -1.1.9 \ No newline at end of file +1.1.10 \ No newline at end of file