From fca5e3b06a1dc4caab54734502a8a53cc52521c1 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 27 Dec 2023 13:59:31 +0100 Subject: [PATCH] Use proper types when dealing with LC Merkle proofs --- specs/altair/light-client/full-node.md | 9 ++++++--- specs/altair/light-client/sync-protocol.md | 12 ++++++------ specs/capella/light-client/full-node.md | 5 +++-- specs/capella/light-client/sync-protocol.md | 4 ++-- specs/deneb/light-client/full-node.md | 5 +++-- specs/deneb/light-client/sync-protocol.md | 2 +- 6 files changed, 21 insertions(+), 16 deletions(-) diff --git a/specs/altair/light-client/full-node.md b/specs/altair/light-client/full-node.md index 27651af01..8ca58cfe5 100644 --- a/specs/altair/light-client/full-node.md +++ b/specs/altair/light-client/full-node.md @@ -75,7 +75,8 @@ def create_light_client_bootstrap(state: BeaconState, return LightClientBootstrap( header=block_to_light_client_header(block), current_sync_committee=state.current_sync_committee, - current_sync_committee_branch=compute_merkle_proof(state, CURRENT_SYNC_COMMITTEE_INDEX), + current_sync_committee_branch=CurrentSyncCommitteeBranch( + compute_merkle_proof(state, CURRENT_SYNC_COMMITTEE_INDEX)), ) ``` @@ -122,7 +123,8 @@ def create_light_client_update(state: BeaconState, # `next_sync_committee` is only useful if the message is signed by the current sync committee if update_attested_period == update_signature_period: update.next_sync_committee = attested_state.next_sync_committee - update.next_sync_committee_branch = compute_merkle_proof(attested_state, NEXT_SYNC_COMMITTEE_INDEX) + update.next_sync_committee_branch = NextSyncCommitteeBranch( + compute_merkle_proof(attested_state, NEXT_SYNC_COMMITTEE_INDEX)) # Indicate finality whenever possible if finalized_block is not None: @@ -131,7 +133,8 @@ def create_light_client_update(state: BeaconState, assert hash_tree_root(update.finalized_header.beacon) == attested_state.finalized_checkpoint.root else: assert attested_state.finalized_checkpoint.root == Bytes32() - update.finality_branch = compute_merkle_proof(attested_state, FINALIZED_ROOT_INDEX) + update.finality_branch = FinalityBranch( + compute_merkle_proof(attested_state, FINALIZED_ROOT_INDEX)) update.sync_aggregate = block.message.body.sync_aggregate update.signature_slot = block.message.slot diff --git a/specs/altair/light-client/sync-protocol.md b/specs/altair/light-client/sync-protocol.md index 6a1fc75d8..58a38d150 100644 --- a/specs/altair/light-client/sync-protocol.md +++ b/specs/altair/light-client/sync-protocol.md @@ -82,7 +82,7 @@ Additional documents describe how the light client sync protocol can be used: ### `FinalityBranch` ```python -class FinalityBranch(Vector[Bytes32, floorlog2(FINALIZED_ROOT_INDEX)]): +class FinalityBranch(Vector[Bytes32, floorlog2(FINALIZED_ROOT_INDEX)]): pass ``` @@ -201,14 +201,14 @@ def is_valid_light_client_header(header: LightClientHeader) -> bool: ```python def is_sync_committee_update(update: LightClientUpdate) -> bool: - return update.next_sync_committee_branch != [Bytes32() for _ in range(floorlog2(NEXT_SYNC_COMMITTEE_INDEX))] + return update.next_sync_committee_branch != NextSyncCommitteeBranch() ``` ### `is_finality_update` ```python def is_finality_update(update: LightClientUpdate) -> bool: - return update.finality_branch != [Bytes32() for _ in range(floorlog2(FINALIZED_ROOT_INDEX))] + return update.finality_branch != FinalityBranch() ``` ### `is_better_update` @@ -520,7 +520,7 @@ def process_light_client_finality_update(store: LightClientStore, update = LightClientUpdate( attested_header=finality_update.attested_header, next_sync_committee=SyncCommittee(), - next_sync_committee_branch=[Bytes32() for _ in range(floorlog2(NEXT_SYNC_COMMITTEE_INDEX))], + next_sync_committee_branch=NextSyncCommitteeBranch(), finalized_header=finality_update.finalized_header, finality_branch=finality_update.finality_branch, sync_aggregate=finality_update.sync_aggregate, @@ -539,9 +539,9 @@ def process_light_client_optimistic_update(store: LightClientStore, update = LightClientUpdate( attested_header=optimistic_update.attested_header, next_sync_committee=SyncCommittee(), - next_sync_committee_branch=[Bytes32() for _ in range(floorlog2(NEXT_SYNC_COMMITTEE_INDEX))], + next_sync_committee_branch=NextSyncCommitteeBranch(), finalized_header=LightClientHeader(), - finality_branch=[Bytes32() for _ in range(floorlog2(FINALIZED_ROOT_INDEX))], + finality_branch=FinalityBranch(), sync_aggregate=optimistic_update.sync_aggregate, signature_slot=optimistic_update.signature_slot, ) diff --git a/specs/capella/light-client/full-node.md b/specs/capella/light-client/full-node.md index c59af8ec7..1d2f677cf 100644 --- a/specs/capella/light-client/full-node.md +++ b/specs/capella/light-client/full-node.md @@ -46,14 +46,15 @@ def block_to_light_client_header(block: SignedBeaconBlock) -> LightClientHeader: transactions_root=hash_tree_root(payload.transactions), withdrawals_root=hash_tree_root(payload.withdrawals), ) - execution_branch = compute_merkle_proof(block.message.body, EXECUTION_PAYLOAD_INDEX) + execution_branch = ExecutionBranch( + compute_merkle_proof(block.message.body, EXECUTION_PAYLOAD_INDEX)) else: # Note that during fork transitions, `finalized_header` may still point to earlier forks. # While Bellatrix blocks also contain an `ExecutionPayload` (minus `withdrawals_root`), # it was not included in the corresponding light client data. To ensure compatibility # with legacy data going through `upgrade_lc_header_to_capella`, leave out execution data. execution_header = ExecutionPayloadHeader() - execution_branch = [Bytes32() for _ in range(floorlog2(EXECUTION_PAYLOAD_INDEX))] + execution_branch = ExecutionBranch() return LightClientHeader( beacon=BeaconBlockHeader( diff --git a/specs/capella/light-client/sync-protocol.md b/specs/capella/light-client/sync-protocol.md index c1281c459..057541bd3 100644 --- a/specs/capella/light-client/sync-protocol.md +++ b/specs/capella/light-client/sync-protocol.md @@ -41,7 +41,7 @@ Additional documents describes the impact of the upgrade on certain roles: ### `ExecutionBranch` ```python -class ExecutionBranch(Vector[Bytes32, floorlog2(EXECUTION_PAYLOAD_INDEX)]): +class ExecutionBranch(Vector[Bytes32, floorlog2(EXECUTION_PAYLOAD_INDEX)]): pass ``` @@ -81,7 +81,7 @@ def is_valid_light_client_header(header: LightClientHeader) -> bool: if epoch < CAPELLA_FORK_EPOCH: return ( header.execution == ExecutionPayloadHeader() - and header.execution_branch == [Bytes32() for _ in range(floorlog2(EXECUTION_PAYLOAD_INDEX))] + and header.execution_branch == ExecutionBranch() ) return is_valid_merkle_branch( diff --git a/specs/deneb/light-client/full-node.md b/specs/deneb/light-client/full-node.md index 18b97ae43..82814b346 100644 --- a/specs/deneb/light-client/full-node.md +++ b/specs/deneb/light-client/full-node.md @@ -52,14 +52,15 @@ def block_to_light_client_header(block: SignedBeaconBlock) -> LightClientHeader: execution_header.blob_gas_used = payload.blob_gas_used execution_header.excess_blob_gas = payload.excess_blob_gas - execution_branch = compute_merkle_proof(block.message.body, EXECUTION_PAYLOAD_INDEX) + execution_branch = ExecutionBranch( + compute_merkle_proof(block.message.body, EXECUTION_PAYLOAD_INDEX)) else: # Note that during fork transitions, `finalized_header` may still point to earlier forks. # While Bellatrix blocks also contain an `ExecutionPayload` (minus `withdrawals_root`), # it was not included in the corresponding light client data. To ensure compatibility # with legacy data going through `upgrade_lc_header_to_capella`, leave out execution data. execution_header = ExecutionPayloadHeader() - execution_branch = [Bytes32() for _ in range(floorlog2(EXECUTION_PAYLOAD_INDEX))] + execution_branch = ExecutionBranch() return LightClientHeader( beacon=BeaconBlockHeader( diff --git a/specs/deneb/light-client/sync-protocol.md b/specs/deneb/light-client/sync-protocol.md index 3b5663fa5..8f3972d32 100644 --- a/specs/deneb/light-client/sync-protocol.md +++ b/specs/deneb/light-client/sync-protocol.md @@ -74,7 +74,7 @@ def is_valid_light_client_header(header: LightClientHeader) -> bool: if epoch < CAPELLA_FORK_EPOCH: return ( header.execution == ExecutionPayloadHeader() - and header.execution_branch == [Bytes32() for _ in range(floorlog2(EXECUTION_PAYLOAD_INDEX))] + and header.execution_branch == ExecutionBranch() ) return is_valid_merkle_branch(