mirror of
https://github.com/status-im/eth2.0-specs.git
synced 2025-01-20 15:38:55 +00:00
Merge pull request #3149 from etan-status/lc-toheader
Add `block_to_light_client_header` helper
This commit is contained in:
commit
0777a52f55
@ -11,6 +11,7 @@
|
||||
- [Introduction](#introduction)
|
||||
- [Helper functions](#helper-functions)
|
||||
- [`compute_merkle_proof_for_state`](#compute_merkle_proof_for_state)
|
||||
- [`block_to_light_client_header`](#block_to_light_client_header)
|
||||
- [Deriving light client data](#deriving-light-client-data)
|
||||
- [`create_light_client_bootstrap`](#create_light_client_bootstrap)
|
||||
- [`create_light_client_update`](#create_light_client_update)
|
||||
@ -34,6 +35,19 @@ def compute_merkle_proof_for_state(state: BeaconState,
|
||||
...
|
||||
```
|
||||
|
||||
### `block_to_light_client_header`
|
||||
|
||||
```python
|
||||
def block_to_light_client_header(block: SignedBeaconBlock) -> BeaconBlockHeader:
|
||||
return BeaconBlockHeader(
|
||||
slot=block.message.slot,
|
||||
proposer_index=block.message.proposer_index,
|
||||
parent_root=block.message.parent_root,
|
||||
state_root=block.message.state_root,
|
||||
body_root=hash_tree_root(block.message.body),
|
||||
)
|
||||
```
|
||||
|
||||
## Deriving light client data
|
||||
|
||||
Full nodes are expected to derive light client data from historic blocks and states and provide it to other clients.
|
||||
@ -55,13 +69,7 @@ def create_light_client_bootstrap(state: BeaconState,
|
||||
assert hash_tree_root(header) == hash_tree_root(block.message)
|
||||
|
||||
return LightClientBootstrap(
|
||||
header=BeaconBlockHeader(
|
||||
slot=state.latest_block_header.slot,
|
||||
proposer_index=state.latest_block_header.proposer_index,
|
||||
parent_root=state.latest_block_header.parent_root,
|
||||
state_root=hash_tree_root(state),
|
||||
body_root=state.latest_block_header.body_root,
|
||||
),
|
||||
header=block_to_light_client_header(block),
|
||||
current_sync_committee=state.current_sync_committee,
|
||||
current_sync_committee_branch=compute_merkle_proof_for_state(state, CURRENT_SYNC_COMMITTEE_INDEX),
|
||||
)
|
||||
@ -103,42 +111,30 @@ def create_light_client_update(state: BeaconState,
|
||||
assert hash_tree_root(attested_header) == hash_tree_root(attested_block.message) == block.message.parent_root
|
||||
update_attested_period = compute_sync_committee_period_at_slot(attested_block.message.slot)
|
||||
|
||||
update = LightClientUpdate()
|
||||
|
||||
update.attested_header = block_to_light_client_header(attested_block)
|
||||
|
||||
# `next_sync_committee` is only useful if the message is signed by the current sync committee
|
||||
if update_attested_period == update_signature_period:
|
||||
next_sync_committee = attested_state.next_sync_committee
|
||||
next_sync_committee_branch = compute_merkle_proof_for_state(attested_state, NEXT_SYNC_COMMITTEE_INDEX)
|
||||
else:
|
||||
next_sync_committee = SyncCommittee()
|
||||
next_sync_committee_branch = [Bytes32() for _ in range(floorlog2(NEXT_SYNC_COMMITTEE_INDEX))]
|
||||
update.next_sync_committee = attested_state.next_sync_committee
|
||||
update.next_sync_committee_branch = compute_merkle_proof_for_state(
|
||||
attested_state, NEXT_SYNC_COMMITTEE_INDEX)
|
||||
|
||||
# Indicate finality whenever possible
|
||||
if finalized_block is not None:
|
||||
if finalized_block.message.slot != GENESIS_SLOT:
|
||||
finalized_header = BeaconBlockHeader(
|
||||
slot=finalized_block.message.slot,
|
||||
proposer_index=finalized_block.message.proposer_index,
|
||||
parent_root=finalized_block.message.parent_root,
|
||||
state_root=finalized_block.message.state_root,
|
||||
body_root=hash_tree_root(finalized_block.message.body),
|
||||
)
|
||||
assert hash_tree_root(finalized_header) == attested_state.finalized_checkpoint.root
|
||||
update.finalized_header = block_to_light_client_header(finalized_block)
|
||||
assert hash_tree_root(update.finalized_header) == attested_state.finalized_checkpoint.root
|
||||
else:
|
||||
assert attested_state.finalized_checkpoint.root == Bytes32()
|
||||
finalized_header = BeaconBlockHeader()
|
||||
finality_branch = compute_merkle_proof_for_state(attested_state, FINALIZED_ROOT_INDEX)
|
||||
else:
|
||||
finalized_header = BeaconBlockHeader()
|
||||
finality_branch = [Bytes32() for _ in range(floorlog2(FINALIZED_ROOT_INDEX))]
|
||||
update.finality_branch = compute_merkle_proof_for_state(
|
||||
attested_state, FINALIZED_ROOT_INDEX)
|
||||
|
||||
return LightClientUpdate(
|
||||
attested_header=attested_header,
|
||||
next_sync_committee=next_sync_committee,
|
||||
next_sync_committee_branch=next_sync_committee_branch,
|
||||
finalized_header=finalized_header,
|
||||
finality_branch=finality_branch,
|
||||
sync_aggregate=block.message.body.sync_aggregate,
|
||||
signature_slot=block.message.slot,
|
||||
)
|
||||
update.sync_aggregate = block.message.body.sync_aggregate
|
||||
update.signature_slot = block.message.slot
|
||||
|
||||
return update
|
||||
```
|
||||
|
||||
Full nodes SHOULD provide the best derivable `LightClientUpdate` (according to `is_better_update`) for each sync committee period covering any epochs in range `[max(ALTAIR_FORK_EPOCH, current_epoch - MIN_EPOCHS_FOR_BLOCK_REQUESTS), current_epoch]` where `current_epoch` is defined by the current wall-clock time. Full nodes MAY also provide `LightClientUpdate` for other sync committee periods.
|
||||
|
@ -10,8 +10,8 @@ from eth2spec.test.context import (
|
||||
@spec_state_test
|
||||
def test_current_sync_committee_merkle_proof(spec, state):
|
||||
yield "object", state
|
||||
current_sync_committee_branch = \
|
||||
spec.compute_merkle_proof_for_state(state, spec.CURRENT_SYNC_COMMITTEE_INDEX)
|
||||
current_sync_committee_branch = spec.compute_merkle_proof_for_state(
|
||||
state, spec.CURRENT_SYNC_COMMITTEE_INDEX)
|
||||
yield "proof", {
|
||||
"leaf": "0x" + state.current_sync_committee.hash_tree_root().hex(),
|
||||
"leaf_index": spec.CURRENT_SYNC_COMMITTEE_INDEX,
|
||||
@ -31,8 +31,8 @@ def test_current_sync_committee_merkle_proof(spec, state):
|
||||
@spec_state_test
|
||||
def test_next_sync_committee_merkle_proof(spec, state):
|
||||
yield "object", state
|
||||
next_sync_committee_branch = \
|
||||
spec.compute_merkle_proof_for_state(state, spec.NEXT_SYNC_COMMITTEE_INDEX)
|
||||
next_sync_committee_branch = spec.compute_merkle_proof_for_state(
|
||||
state, spec.NEXT_SYNC_COMMITTEE_INDEX)
|
||||
yield "proof", {
|
||||
"leaf": "0x" + state.next_sync_committee.hash_tree_root().hex(),
|
||||
"leaf_index": spec.NEXT_SYNC_COMMITTEE_INDEX,
|
||||
@ -52,8 +52,8 @@ def test_next_sync_committee_merkle_proof(spec, state):
|
||||
@spec_state_test
|
||||
def test_finality_root_merkle_proof(spec, state):
|
||||
yield "object", state
|
||||
finality_branch = \
|
||||
spec.compute_merkle_proof_for_state(state, spec.FINALIZED_ROOT_INDEX)
|
||||
finality_branch = spec.compute_merkle_proof_for_state(
|
||||
state, spec.FINALIZED_ROOT_INDEX)
|
||||
yield "proof", {
|
||||
"leaf": "0x" + state.finalized_checkpoint.root.hex(),
|
||||
"leaf_index": spec.FINALIZED_ROOT_INDEX,
|
||||
|
@ -9,45 +9,23 @@ from eth2spec.test.helpers.attestations import (
|
||||
)
|
||||
from eth2spec.test.helpers.constants import MINIMAL
|
||||
from eth2spec.test.helpers.light_client import (
|
||||
get_sync_aggregate,
|
||||
signed_block_to_header,
|
||||
create_update,
|
||||
)
|
||||
from eth2spec.test.helpers.state import (
|
||||
next_slots,
|
||||
)
|
||||
from math import floor
|
||||
|
||||
|
||||
def create_update(spec, test, with_next, with_finality, participation_rate):
|
||||
def create_test_update(spec, test, with_next, with_finality, participation_rate):
|
||||
attested_state, attested_block, finalized_block = test
|
||||
num_participants = floor(spec.SYNC_COMMITTEE_SIZE * participation_rate)
|
||||
|
||||
attested_header = signed_block_to_header(spec, attested_block)
|
||||
|
||||
if with_next:
|
||||
next_sync_committee = attested_state.next_sync_committee
|
||||
next_sync_committee_branch = spec.compute_merkle_proof_for_state(attested_state, spec.NEXT_SYNC_COMMITTEE_INDEX)
|
||||
else:
|
||||
next_sync_committee = spec.SyncCommittee()
|
||||
next_sync_committee_branch = [spec.Bytes32() for _ in range(spec.floorlog2(spec.NEXT_SYNC_COMMITTEE_INDEX))]
|
||||
|
||||
if with_finality:
|
||||
finalized_header = signed_block_to_header(spec, finalized_block)
|
||||
finality_branch = spec.compute_merkle_proof_for_state(attested_state, spec.FINALIZED_ROOT_INDEX)
|
||||
else:
|
||||
finalized_header = spec.BeaconBlockHeader()
|
||||
finality_branch = [spec.Bytes32() for _ in range(spec.floorlog2(spec.FINALIZED_ROOT_INDEX))]
|
||||
|
||||
sync_aggregate, signature_slot = get_sync_aggregate(spec, attested_state, num_participants)
|
||||
|
||||
return spec.LightClientUpdate(
|
||||
attested_header=attested_header,
|
||||
next_sync_committee=next_sync_committee,
|
||||
next_sync_committee_branch=next_sync_committee_branch,
|
||||
finalized_header=finalized_header,
|
||||
finality_branch=finality_branch,
|
||||
sync_aggregate=sync_aggregate,
|
||||
signature_slot=signature_slot,
|
||||
return create_update(
|
||||
spec,
|
||||
attested_state,
|
||||
attested_block,
|
||||
finalized_block,
|
||||
with_next,
|
||||
with_finality,
|
||||
participation_rate,
|
||||
)
|
||||
|
||||
|
||||
@ -84,76 +62,76 @@ def test_update_ranking(spec, state):
|
||||
# Create updates (in descending order of quality)
|
||||
updates = [
|
||||
# Updates with sync committee finality
|
||||
create_update(spec, fin, with_next=1, with_finality=1, participation_rate=1.0),
|
||||
create_update(spec, lat, with_next=1, with_finality=1, participation_rate=1.0),
|
||||
create_update(spec, fin, with_next=1, with_finality=1, participation_rate=0.8),
|
||||
create_update(spec, lat, with_next=1, with_finality=1, participation_rate=0.8),
|
||||
create_test_update(spec, fin, with_next=1, with_finality=1, participation_rate=1.0),
|
||||
create_test_update(spec, lat, with_next=1, with_finality=1, participation_rate=1.0),
|
||||
create_test_update(spec, fin, with_next=1, with_finality=1, participation_rate=0.8),
|
||||
create_test_update(spec, lat, with_next=1, with_finality=1, participation_rate=0.8),
|
||||
|
||||
# Updates without sync committee finality
|
||||
create_update(spec, att, with_next=1, with_finality=1, participation_rate=1.0),
|
||||
create_update(spec, att, with_next=1, with_finality=1, participation_rate=0.8),
|
||||
create_test_update(spec, att, with_next=1, with_finality=1, participation_rate=1.0),
|
||||
create_test_update(spec, att, with_next=1, with_finality=1, participation_rate=0.8),
|
||||
|
||||
# Updates without indication of any finality
|
||||
create_update(spec, att, with_next=1, with_finality=0, participation_rate=1.0),
|
||||
create_update(spec, fin, with_next=1, with_finality=0, participation_rate=1.0),
|
||||
create_update(spec, lat, with_next=1, with_finality=0, participation_rate=1.0),
|
||||
create_update(spec, att, with_next=1, with_finality=0, participation_rate=0.8),
|
||||
create_update(spec, fin, with_next=1, with_finality=0, participation_rate=0.8),
|
||||
create_update(spec, lat, with_next=1, with_finality=0, participation_rate=0.8),
|
||||
create_test_update(spec, att, with_next=1, with_finality=0, participation_rate=1.0),
|
||||
create_test_update(spec, fin, with_next=1, with_finality=0, participation_rate=1.0),
|
||||
create_test_update(spec, lat, with_next=1, with_finality=0, participation_rate=1.0),
|
||||
create_test_update(spec, att, with_next=1, with_finality=0, participation_rate=0.8),
|
||||
create_test_update(spec, fin, with_next=1, with_finality=0, participation_rate=0.8),
|
||||
create_test_update(spec, lat, with_next=1, with_finality=0, participation_rate=0.8),
|
||||
|
||||
# Updates with sync committee finality but no `next_sync_committee`
|
||||
create_update(spec, sig, with_next=0, with_finality=1, participation_rate=1.0),
|
||||
create_update(spec, fin, with_next=0, with_finality=1, participation_rate=1.0),
|
||||
create_update(spec, lat, with_next=0, with_finality=1, participation_rate=1.0),
|
||||
create_update(spec, sig, with_next=0, with_finality=1, participation_rate=0.8),
|
||||
create_update(spec, fin, with_next=0, with_finality=1, participation_rate=0.8),
|
||||
create_update(spec, lat, with_next=0, with_finality=1, participation_rate=0.8),
|
||||
create_test_update(spec, sig, with_next=0, with_finality=1, participation_rate=1.0),
|
||||
create_test_update(spec, fin, with_next=0, with_finality=1, participation_rate=1.0),
|
||||
create_test_update(spec, lat, with_next=0, with_finality=1, participation_rate=1.0),
|
||||
create_test_update(spec, sig, with_next=0, with_finality=1, participation_rate=0.8),
|
||||
create_test_update(spec, fin, with_next=0, with_finality=1, participation_rate=0.8),
|
||||
create_test_update(spec, lat, with_next=0, with_finality=1, participation_rate=0.8),
|
||||
|
||||
# Updates without sync committee finality and also no `next_sync_committee`
|
||||
create_update(spec, att, with_next=0, with_finality=1, participation_rate=1.0),
|
||||
create_update(spec, att, with_next=0, with_finality=1, participation_rate=0.8),
|
||||
create_test_update(spec, att, with_next=0, with_finality=1, participation_rate=1.0),
|
||||
create_test_update(spec, att, with_next=0, with_finality=1, participation_rate=0.8),
|
||||
|
||||
# Updates without indication of any finality nor `next_sync_committee`
|
||||
create_update(spec, sig, with_next=0, with_finality=0, participation_rate=1.0),
|
||||
create_update(spec, att, with_next=0, with_finality=0, participation_rate=1.0),
|
||||
create_update(spec, fin, with_next=0, with_finality=0, participation_rate=1.0),
|
||||
create_update(spec, lat, with_next=0, with_finality=0, participation_rate=1.0),
|
||||
create_update(spec, sig, with_next=0, with_finality=0, participation_rate=0.8),
|
||||
create_update(spec, att, with_next=0, with_finality=0, participation_rate=0.8),
|
||||
create_update(spec, fin, with_next=0, with_finality=0, participation_rate=0.8),
|
||||
create_update(spec, lat, with_next=0, with_finality=0, participation_rate=0.8),
|
||||
create_test_update(spec, sig, with_next=0, with_finality=0, participation_rate=1.0),
|
||||
create_test_update(spec, att, with_next=0, with_finality=0, participation_rate=1.0),
|
||||
create_test_update(spec, fin, with_next=0, with_finality=0, participation_rate=1.0),
|
||||
create_test_update(spec, lat, with_next=0, with_finality=0, participation_rate=1.0),
|
||||
create_test_update(spec, sig, with_next=0, with_finality=0, participation_rate=0.8),
|
||||
create_test_update(spec, att, with_next=0, with_finality=0, participation_rate=0.8),
|
||||
create_test_update(spec, fin, with_next=0, with_finality=0, participation_rate=0.8),
|
||||
create_test_update(spec, lat, with_next=0, with_finality=0, participation_rate=0.8),
|
||||
|
||||
# Updates with low sync committee participation
|
||||
create_update(spec, fin, with_next=1, with_finality=1, participation_rate=0.4),
|
||||
create_update(spec, lat, with_next=1, with_finality=1, participation_rate=0.4),
|
||||
create_update(spec, att, with_next=1, with_finality=1, participation_rate=0.4),
|
||||
create_update(spec, att, with_next=1, with_finality=0, participation_rate=0.4),
|
||||
create_update(spec, fin, with_next=1, with_finality=0, participation_rate=0.4),
|
||||
create_update(spec, lat, with_next=1, with_finality=0, participation_rate=0.4),
|
||||
create_update(spec, sig, with_next=0, with_finality=1, participation_rate=0.4),
|
||||
create_update(spec, fin, with_next=0, with_finality=1, participation_rate=0.4),
|
||||
create_update(spec, lat, with_next=0, with_finality=1, participation_rate=0.4),
|
||||
create_update(spec, att, with_next=0, with_finality=1, participation_rate=0.4),
|
||||
create_update(spec, sig, with_next=0, with_finality=0, participation_rate=0.4),
|
||||
create_update(spec, att, with_next=0, with_finality=0, participation_rate=0.4),
|
||||
create_update(spec, fin, with_next=0, with_finality=0, participation_rate=0.4),
|
||||
create_update(spec, lat, with_next=0, with_finality=0, participation_rate=0.4),
|
||||
create_test_update(spec, fin, with_next=1, with_finality=1, participation_rate=0.4),
|
||||
create_test_update(spec, lat, with_next=1, with_finality=1, participation_rate=0.4),
|
||||
create_test_update(spec, att, with_next=1, with_finality=1, participation_rate=0.4),
|
||||
create_test_update(spec, att, with_next=1, with_finality=0, participation_rate=0.4),
|
||||
create_test_update(spec, fin, with_next=1, with_finality=0, participation_rate=0.4),
|
||||
create_test_update(spec, lat, with_next=1, with_finality=0, participation_rate=0.4),
|
||||
create_test_update(spec, sig, with_next=0, with_finality=1, participation_rate=0.4),
|
||||
create_test_update(spec, fin, with_next=0, with_finality=1, participation_rate=0.4),
|
||||
create_test_update(spec, lat, with_next=0, with_finality=1, participation_rate=0.4),
|
||||
create_test_update(spec, att, with_next=0, with_finality=1, participation_rate=0.4),
|
||||
create_test_update(spec, sig, with_next=0, with_finality=0, participation_rate=0.4),
|
||||
create_test_update(spec, att, with_next=0, with_finality=0, participation_rate=0.4),
|
||||
create_test_update(spec, fin, with_next=0, with_finality=0, participation_rate=0.4),
|
||||
create_test_update(spec, lat, with_next=0, with_finality=0, participation_rate=0.4),
|
||||
|
||||
# Updates with very low sync committee participation
|
||||
create_update(spec, fin, with_next=1, with_finality=1, participation_rate=0.2),
|
||||
create_update(spec, lat, with_next=1, with_finality=1, participation_rate=0.2),
|
||||
create_update(spec, att, with_next=1, with_finality=1, participation_rate=0.2),
|
||||
create_update(spec, att, with_next=1, with_finality=0, participation_rate=0.2),
|
||||
create_update(spec, fin, with_next=1, with_finality=0, participation_rate=0.2),
|
||||
create_update(spec, lat, with_next=1, with_finality=0, participation_rate=0.2),
|
||||
create_update(spec, sig, with_next=0, with_finality=1, participation_rate=0.2),
|
||||
create_update(spec, fin, with_next=0, with_finality=1, participation_rate=0.2),
|
||||
create_update(spec, lat, with_next=0, with_finality=1, participation_rate=0.2),
|
||||
create_update(spec, att, with_next=0, with_finality=1, participation_rate=0.2),
|
||||
create_update(spec, sig, with_next=0, with_finality=0, participation_rate=0.2),
|
||||
create_update(spec, att, with_next=0, with_finality=0, participation_rate=0.2),
|
||||
create_update(spec, fin, with_next=0, with_finality=0, participation_rate=0.2),
|
||||
create_update(spec, lat, with_next=0, with_finality=0, participation_rate=0.2),
|
||||
create_test_update(spec, fin, with_next=1, with_finality=1, participation_rate=0.2),
|
||||
create_test_update(spec, lat, with_next=1, with_finality=1, participation_rate=0.2),
|
||||
create_test_update(spec, att, with_next=1, with_finality=1, participation_rate=0.2),
|
||||
create_test_update(spec, att, with_next=1, with_finality=0, participation_rate=0.2),
|
||||
create_test_update(spec, fin, with_next=1, with_finality=0, participation_rate=0.2),
|
||||
create_test_update(spec, lat, with_next=1, with_finality=0, participation_rate=0.2),
|
||||
create_test_update(spec, sig, with_next=0, with_finality=1, participation_rate=0.2),
|
||||
create_test_update(spec, fin, with_next=0, with_finality=1, participation_rate=0.2),
|
||||
create_test_update(spec, lat, with_next=0, with_finality=1, participation_rate=0.2),
|
||||
create_test_update(spec, att, with_next=0, with_finality=1, participation_rate=0.2),
|
||||
create_test_update(spec, sig, with_next=0, with_finality=0, participation_rate=0.2),
|
||||
create_test_update(spec, att, with_next=0, with_finality=0, participation_rate=0.2),
|
||||
create_test_update(spec, fin, with_next=0, with_finality=0, participation_rate=0.2),
|
||||
create_test_update(spec, lat, with_next=0, with_finality=0, participation_rate=0.2),
|
||||
]
|
||||
yield "updates", updates
|
||||
|
||||
|
@ -11,43 +11,44 @@ from eth2spec.test.helpers.attestations import (
|
||||
)
|
||||
from eth2spec.test.helpers.constants import MINIMAL
|
||||
from eth2spec.test.helpers.light_client import (
|
||||
get_sync_aggregate,
|
||||
initialize_light_client_store,
|
||||
signed_block_to_header,
|
||||
create_update,
|
||||
)
|
||||
from eth2spec.test.helpers.state import (
|
||||
next_slots,
|
||||
)
|
||||
|
||||
|
||||
def setup_test(spec, state):
|
||||
trusted_block = spec.SignedBeaconBlock()
|
||||
trusted_block.message.state_root = state.hash_tree_root()
|
||||
trusted_block_root = trusted_block.message.hash_tree_root()
|
||||
bootstrap = spec.create_light_client_bootstrap(state, trusted_block)
|
||||
store = spec.initialize_light_client_store(trusted_block_root, bootstrap)
|
||||
store.next_sync_committee = state.next_sync_committee
|
||||
|
||||
return (trusted_block, store)
|
||||
|
||||
|
||||
@with_altair_and_later
|
||||
@spec_state_test_with_matching_config
|
||||
def test_process_light_client_update_not_timeout(spec, state):
|
||||
store = initialize_light_client_store(spec, state)
|
||||
genesis_block, store = setup_test(spec, state)
|
||||
|
||||
# Block at slot 1 doesn't increase sync committee period, so it won't force update store.finalized_header
|
||||
attested_block = state_transition_with_full_block(spec, state, False, False)
|
||||
attested_header = signed_block_to_header(spec, attested_block)
|
||||
|
||||
# Sync committee signing the attested_header
|
||||
sync_aggregate, signature_slot = get_sync_aggregate(spec, state)
|
||||
next_sync_committee = spec.SyncCommittee()
|
||||
next_sync_committee_branch = [spec.Bytes32() for _ in range(spec.floorlog2(spec.NEXT_SYNC_COMMITTEE_INDEX))]
|
||||
signature_slot = state.slot + 1
|
||||
|
||||
# Ensure that finality checkpoint is genesis
|
||||
assert state.finalized_checkpoint.epoch == 0
|
||||
# Finality is unchanged
|
||||
finalized_header = spec.BeaconBlockHeader()
|
||||
finality_branch = [spec.Bytes32() for _ in range(spec.floorlog2(spec.FINALIZED_ROOT_INDEX))]
|
||||
|
||||
update = spec.LightClientUpdate(
|
||||
attested_header=attested_header,
|
||||
next_sync_committee=next_sync_committee,
|
||||
next_sync_committee_branch=next_sync_committee_branch,
|
||||
finalized_header=finalized_header,
|
||||
finality_branch=finality_branch,
|
||||
sync_aggregate=sync_aggregate,
|
||||
signature_slot=signature_slot,
|
||||
update = create_update(
|
||||
spec,
|
||||
attested_state=state,
|
||||
attested_block=attested_block,
|
||||
finalized_block=genesis_block,
|
||||
with_next=False,
|
||||
with_finality=False,
|
||||
participation_rate=1.0,
|
||||
)
|
||||
|
||||
pre_store = deepcopy(store)
|
||||
@ -64,7 +65,7 @@ def test_process_light_client_update_not_timeout(spec, state):
|
||||
@spec_state_test_with_matching_config
|
||||
@with_presets([MINIMAL], reason="too slow")
|
||||
def test_process_light_client_update_at_period_boundary(spec, state):
|
||||
store = initialize_light_client_store(spec, state)
|
||||
genesis_block, store = setup_test(spec, state)
|
||||
|
||||
# Forward to slot before next sync committee period so that next block is final one in period
|
||||
next_slots(spec, state, spec.UPDATE_TIMEOUT - 2)
|
||||
@ -73,25 +74,16 @@ def test_process_light_client_update_at_period_boundary(spec, state):
|
||||
assert store_period == update_period
|
||||
|
||||
attested_block = state_transition_with_full_block(spec, state, False, False)
|
||||
attested_header = signed_block_to_header(spec, attested_block)
|
||||
signature_slot = state.slot + 1
|
||||
|
||||
# Sync committee signing the attested_header
|
||||
sync_aggregate, signature_slot = get_sync_aggregate(spec, state)
|
||||
next_sync_committee = spec.SyncCommittee()
|
||||
next_sync_committee_branch = [spec.Bytes32() for _ in range(spec.floorlog2(spec.NEXT_SYNC_COMMITTEE_INDEX))]
|
||||
|
||||
# Finality is unchanged
|
||||
finalized_header = spec.BeaconBlockHeader()
|
||||
finality_branch = [spec.Bytes32() for _ in range(spec.floorlog2(spec.FINALIZED_ROOT_INDEX))]
|
||||
|
||||
update = spec.LightClientUpdate(
|
||||
attested_header=attested_header,
|
||||
next_sync_committee=next_sync_committee,
|
||||
next_sync_committee_branch=next_sync_committee_branch,
|
||||
finalized_header=finalized_header,
|
||||
finality_branch=finality_branch,
|
||||
sync_aggregate=sync_aggregate,
|
||||
signature_slot=signature_slot,
|
||||
update = create_update(
|
||||
spec,
|
||||
attested_state=state,
|
||||
attested_block=attested_block,
|
||||
finalized_block=genesis_block,
|
||||
with_next=False,
|
||||
with_finality=False,
|
||||
participation_rate=1.0,
|
||||
)
|
||||
|
||||
pre_store = deepcopy(store)
|
||||
@ -108,7 +100,7 @@ def test_process_light_client_update_at_period_boundary(spec, state):
|
||||
@spec_state_test_with_matching_config
|
||||
@with_presets([MINIMAL], reason="too slow")
|
||||
def test_process_light_client_update_timeout(spec, state):
|
||||
store = initialize_light_client_store(spec, state)
|
||||
genesis_block, store = setup_test(spec, state)
|
||||
|
||||
# Forward to next sync committee period
|
||||
next_slots(spec, state, spec.UPDATE_TIMEOUT)
|
||||
@ -117,26 +109,16 @@ def test_process_light_client_update_timeout(spec, state):
|
||||
assert store_period + 1 == update_period
|
||||
|
||||
attested_block = state_transition_with_full_block(spec, state, False, False)
|
||||
attested_header = signed_block_to_header(spec, attested_block)
|
||||
signature_slot = state.slot + 1
|
||||
|
||||
# Sync committee signing the attested_header
|
||||
sync_aggregate, signature_slot = get_sync_aggregate(spec, state)
|
||||
|
||||
# Sync committee is updated
|
||||
next_sync_committee = state.next_sync_committee
|
||||
next_sync_committee_branch = spec.compute_merkle_proof_for_state(state, spec.NEXT_SYNC_COMMITTEE_INDEX)
|
||||
# Finality is unchanged
|
||||
finalized_header = spec.BeaconBlockHeader()
|
||||
finality_branch = [spec.Bytes32() for _ in range(spec.floorlog2(spec.FINALIZED_ROOT_INDEX))]
|
||||
|
||||
update = spec.LightClientUpdate(
|
||||
attested_header=attested_header,
|
||||
next_sync_committee=next_sync_committee,
|
||||
next_sync_committee_branch=next_sync_committee_branch,
|
||||
finalized_header=finalized_header,
|
||||
finality_branch=finality_branch,
|
||||
sync_aggregate=sync_aggregate,
|
||||
signature_slot=signature_slot,
|
||||
update = create_update(
|
||||
spec,
|
||||
attested_state=state,
|
||||
attested_block=attested_block,
|
||||
finalized_block=genesis_block,
|
||||
with_next=True,
|
||||
with_finality=False,
|
||||
participation_rate=1.0,
|
||||
)
|
||||
|
||||
pre_store = deepcopy(store)
|
||||
@ -153,7 +135,7 @@ def test_process_light_client_update_timeout(spec, state):
|
||||
@spec_state_test_with_matching_config
|
||||
@with_presets([MINIMAL], reason="too slow")
|
||||
def test_process_light_client_update_finality_updated(spec, state):
|
||||
store = initialize_light_client_store(spec, state)
|
||||
_, store = setup_test(spec, state)
|
||||
|
||||
# Change finality
|
||||
blocks = []
|
||||
@ -169,28 +151,21 @@ def test_process_light_client_update_finality_updated(spec, state):
|
||||
assert store_period == update_period
|
||||
|
||||
attested_block = blocks[-1]
|
||||
attested_header = signed_block_to_header(spec, attested_block)
|
||||
signature_slot = state.slot + 1
|
||||
|
||||
# Sync committee signing the attested_header
|
||||
sync_aggregate, signature_slot = get_sync_aggregate(spec, state)
|
||||
|
||||
# Updated sync_committee and finality
|
||||
next_sync_committee = spec.SyncCommittee()
|
||||
next_sync_committee_branch = [spec.Bytes32() for _ in range(spec.floorlog2(spec.NEXT_SYNC_COMMITTEE_INDEX))]
|
||||
# Updated finality
|
||||
finalized_block = blocks[spec.SLOTS_PER_EPOCH - 1]
|
||||
finalized_header = signed_block_to_header(spec, finalized_block)
|
||||
assert finalized_header.slot == spec.compute_start_slot_at_epoch(state.finalized_checkpoint.epoch)
|
||||
assert finalized_header.hash_tree_root() == state.finalized_checkpoint.root
|
||||
finality_branch = spec.compute_merkle_proof_for_state(state, spec.FINALIZED_ROOT_INDEX)
|
||||
assert finalized_block.message.slot == spec.compute_start_slot_at_epoch(state.finalized_checkpoint.epoch)
|
||||
assert finalized_block.message.hash_tree_root() == state.finalized_checkpoint.root
|
||||
|
||||
update = spec.LightClientUpdate(
|
||||
attested_header=attested_header,
|
||||
next_sync_committee=next_sync_committee,
|
||||
next_sync_committee_branch=next_sync_committee_branch,
|
||||
finalized_header=finalized_header,
|
||||
finality_branch=finality_branch,
|
||||
sync_aggregate=sync_aggregate,
|
||||
signature_slot=signature_slot,
|
||||
update = create_update(
|
||||
spec,
|
||||
attested_state=state,
|
||||
attested_block=attested_block,
|
||||
finalized_block=finalized_block,
|
||||
with_next=False,
|
||||
with_finality=True,
|
||||
participation_rate=1.0,
|
||||
)
|
||||
|
||||
spec.process_light_client_update(store, update, signature_slot, state.genesis_validators_root)
|
||||
|
@ -5,28 +5,7 @@ from eth2spec.test.helpers.sync_committee import (
|
||||
compute_aggregate_sync_committee_signature,
|
||||
compute_committee_indices,
|
||||
)
|
||||
|
||||
|
||||
def signed_block_to_header(spec, block):
|
||||
return spec.BeaconBlockHeader(
|
||||
slot=block.message.slot,
|
||||
proposer_index=block.message.proposer_index,
|
||||
parent_root=block.message.parent_root,
|
||||
state_root=block.message.state_root,
|
||||
body_root=block.message.body.hash_tree_root(),
|
||||
)
|
||||
|
||||
|
||||
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,
|
||||
)
|
||||
from math import floor
|
||||
|
||||
|
||||
def get_sync_aggregate(spec, state, num_participants=None, signature_slot=None):
|
||||
@ -60,3 +39,32 @@ def get_sync_aggregate(spec, state, num_participants=None, signature_slot=None):
|
||||
sync_committee_signature=sync_committee_signature,
|
||||
)
|
||||
return sync_aggregate, signature_slot
|
||||
|
||||
|
||||
def create_update(spec,
|
||||
attested_state,
|
||||
attested_block,
|
||||
finalized_block,
|
||||
with_next,
|
||||
with_finality,
|
||||
participation_rate):
|
||||
num_participants = floor(spec.SYNC_COMMITTEE_SIZE * participation_rate)
|
||||
|
||||
update = spec.LightClientUpdate()
|
||||
|
||||
update.attested_header = spec.block_to_light_client_header(attested_block)
|
||||
|
||||
if with_next:
|
||||
update.next_sync_committee = attested_state.next_sync_committee
|
||||
update.next_sync_committee_branch = spec.compute_merkle_proof_for_state(
|
||||
attested_state, spec.NEXT_SYNC_COMMITTEE_INDEX)
|
||||
|
||||
if with_finality:
|
||||
update.finalized_header = spec.block_to_light_client_header(finalized_block)
|
||||
update.finality_branch = spec.compute_merkle_proof_for_state(
|
||||
attested_state, spec.FINALIZED_ROOT_INDEX)
|
||||
|
||||
update.sync_aggregate, update.signature_slot = get_sync_aggregate(
|
||||
spec, attested_state, num_participants)
|
||||
|
||||
return update
|
||||
|
Loading…
x
Reference in New Issue
Block a user