update light client to v1.1.10 spec (#3457)
Adopts the changes introduced in the v1.1.10 ETH consensus-specs: - Introduces `is_finality_update` helper - Ensures `optimistic_header` always >= `finalized_header` - Updates spec references
This commit is contained in:
parent
4c01b77773
commit
47d7814518
|
@ -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
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue