diff --git a/beacon_chain/spec/datatypes/altair.nim b/beacon_chain/spec/datatypes/altair.nim index f7cd21efc..0098e6549 100644 --- a/beacon_chain/spec/datatypes/altair.nim +++ b/beacon_chain/spec/datatypes/altair.nim @@ -51,7 +51,7 @@ const TARGET_AGGREGATORS_PER_SYNC_SUBCOMMITTEE* = 16 SYNC_COMMITTEE_SUBNET_COUNT* = 4 - # https://github.com/ethereum/consensus-specs/blob/v1.1.9/specs/altair/sync-protocol.md#constants + # https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/altair/sync-protocol.md#constants # All of these indices are rooted in `BeaconState`. # The first member (`genesis_time`) is 32, subsequent members +1 each. # If there are ever more than 32 members in `BeaconState`, indices change! @@ -69,7 +69,7 @@ const INACTIVITY_SCORE_BIAS* = 4 INACTIVITY_SCORE_RECOVERY_RATE* = 16 - # https://github.com/ethereum/consensus-specs/blob/v1.1.9/specs/altair/sync-protocol.md#misc + # https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/altair/sync-protocol.md#misc # MIN_SYNC_COMMITTEE_PARTICIPANTS defined in presets UPDATE_TIMEOUT* = SLOTS_PER_EPOCH * EPOCHS_PER_SYNC_COMMITTEE_PERIOD @@ -157,7 +157,7 @@ type ### Modified/overloaded - # https://github.com/ethereum/consensus-specs/blob/v1.1.9/specs/altair/sync-protocol.md#lightclientupdate + # https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/altair/sync-protocol.md#lightclientupdate LightClientUpdate* = object attested_header*: BeaconBlockHeader ##\ ## The beacon block header that is attested to by the sync committee @@ -177,7 +177,7 @@ type fork_version*: Version ##\ ## Fork version for the aggregate signature - # https://github.com/ethereum/consensus-specs/blob/v1.1.9/specs/altair/sync-protocol.md#lightclientstore + # https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/altair/sync-protocol.md#lightclientstore LightClientStore* = object finalized_header*: BeaconBlockHeader ##\ ## Beacon block header that is finalized diff --git a/beacon_chain/spec/helpers.nim b/beacon_chain/spec/helpers.nim index 1d1728f2d..232f7eb10 100644 --- a/beacon_chain/spec/helpers.nim +++ b/beacon_chain/spec/helpers.nim @@ -475,7 +475,7 @@ func has_flag*(flags: ParticipationFlags, flag_index: int): bool = let flag = ParticipationFlags(1'u8 shl flag_index) (flags and flag) == flag -# https://github.com/ethereum/consensus-specs/blob/v1.1.9/specs/altair/sync-protocol.md#get_subtree_index +# https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/altair/sync-protocol.md#get_subtree_index func get_subtree_index*(idx: GeneralizedIndex): uint64 = doAssert idx > 0 uint64(idx mod (type(idx)(1) shl log2trunc(idx))) diff --git a/beacon_chain/spec/light_client_sync.nim b/beacon_chain/spec/light_client_sync.nim index 8f0bd2e82..5a672758c 100644 --- a/beacon_chain/spec/light_client_sync.nim +++ b/beacon_chain/spec/light_client_sync.nim @@ -12,24 +12,28 @@ import datatypes/altair, helpers -# https://github.com/ethereum/consensus-specs/blob/v1.1.9/specs/altair/sync-protocol.md#get_active_header +# https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/altair/sync-protocol.md#get_active_header +func is_finality_update(update: altair.LightClientUpdate): bool = + not update.finalized_header.isZeroMemory + +# https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/altair/sync-protocol.md#get_active_header func get_active_header(update: altair.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 not update.finalized_header.isZeroMemory: + if update.is_finality_update: update.finalized_header else: update.attested_header -# https://github.com/ethereum/consensus-specs/blob/v1.1.9/specs/altair/sync-protocol.md#get_safety_threshold +# https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/altair/sync-protocol.md#get_safety_threshold func get_safety_threshold(store: LightClientStore): uint64 = max( store.previous_max_active_participants, store.current_max_active_participants ) div 2 -# https://github.com/ethereum/consensus-specs/blob/v1.1.9/specs/altair/sync-protocol.md#validate_light_client_update +# https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/altair/sync-protocol.md#validate_light_client_update proc validate_light_client_update*( store: LightClientStore, update: altair.LightClientUpdate, @@ -51,7 +55,7 @@ proc validate_light_client_update*( # Verify that the `finalized_header`, if present, actually is the finalized # header saved in the state of the `attested header` - if update.finalized_header.isZeroMemory: + if not update.is_finality_update: if not update.finality_branch.isZeroMemory: return false else: @@ -100,7 +104,7 @@ proc validate_light_client_update*( blsFastAggregateVerify( participant_pubkeys, signing_root.data, sync_aggregate.sync_committee_signature) -# https://github.com/ethereum/consensus-specs/blob/v1.1.9/specs/altair/sync-protocol.md#apply_light_client_update +# https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/altair/sync-protocol.md#apply_light_client_update func apply_light_client_update( store: var LightClientStore, update: altair.LightClientUpdate) = @@ -112,8 +116,10 @@ func apply_light_client_update( 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 -# https://github.com/ethereum/consensus-specs/blob/v1.1.9/specs/altair/sync-protocol.md#process_light_client_update +# https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/altair/sync-protocol.md#process_light_client_update proc process_light_client_update*( store: var LightClientStore, update: altair.LightClientUpdate, @@ -147,7 +153,7 @@ proc process_light_client_update*( # Update finalized header if sum_sync_committee_bits * 3 >= len(sync_committee_bits) * 2 and - not update.finalized_header.isZeroMemory: + update.is_finality_update: # Normal update through 2/3 threshold apply_light_client_update(store, update) store.best_valid_update = none(altair.LightClientUpdate) diff --git a/tests/consensus_spec/altair/test_fixture_sync_protocol.nim b/tests/consensus_spec/altair/test_fixture_sync_protocol.nim index 548f0564e..244449abb 100644 --- a/tests/consensus_spec/altair/test_fixture_sync_protocol.nim +++ b/tests/consensus_spec/altair/test_fixture_sync_protocol.nim @@ -74,7 +74,7 @@ let full_sync_committee_bits = block: res.bytes.fill(byte.high) res -# https://github.com/ethereum/consensus-specs/blob/v1.1.9/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py#L24-L33 +# https://github.com/ethereum/consensus-specs/blob/v1.1.10/tests/core/pyspec/eth2spec/test/helpers/light_client.py#L6-L15 func initialize_light_client_store(state: auto): LightClientStore = LightClientStore( finalized_header: BeaconBlockHeader(), @@ -94,7 +94,7 @@ suite "EF - Altair - Unittests - Sync protocol" & preset(): res genesisState = newClone(initGenesisState(cfg = cfg)) - # https://github.com/ethereum/consensus-specs/blob/v1.1.9/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py#L36-L90 + # https://github.com/ethereum/consensus-specs/blob/v1.1.10/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py#L27-L69 test "test_process_light_client_update_not_timeout": let forked = assignClone(genesisState[]) template state: untyped {.inject.} = forked[].altairData.data @@ -151,7 +151,7 @@ suite "EF - Altair - Unittests - Sync protocol" & preset(): store.finalized_header == pre_store_finalized_header store.best_valid_update.get == update - # https://github.com/ethereum/consensus-specs/blob/v1.1.9/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py#L93-L154 + # https://github.com/ethereum/consensus-specs/blob/v1.1.10/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py#L72-L121 test "process_light_client_update_timeout": let forked = assignClone(genesisState[]) template state: untyped {.inject.} = forked[].altairData.data @@ -215,7 +215,7 @@ suite "EF - Altair - Unittests - Sync protocol" & preset(): store.finalized_header == pre_store_finalized_header store.best_valid_update.get == update - # https://github.com/ethereum/consensus-specs/blob/v1.1.9/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py#L157-L224 + # https://github.com/ethereum/consensus-specs/blob/v1.1.10/tests/core/pyspec/eth2spec/test/altair/unittests/test_sync_protocol.py#L124-L179 test "process_light_client_update_finality_updated": let forked = assignClone(genesisState[]) template state: untyped {.inject.} = forked[].altairData.data