From 7a168be862294d580003126d881cc7f4ba4e2584 Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Tue, 4 May 2021 13:25:34 -0700 Subject: [PATCH 1/6] allow fault tolerance equal to threshold, not just above --- specs/altair/sync-protocol.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/altair/sync-protocol.md b/specs/altair/sync-protocol.md index 925c882ef..fba263bb1 100644 --- a/specs/altair/sync-protocol.md +++ b/specs/altair/sync-protocol.md @@ -185,7 +185,7 @@ def process_light_client_update(store: LightClientStore, update: LightClientUpda store.valid_updates.append(update) if ( - sum(update.sync_committee_bits) * 3 > len(update.sync_committee_bits) * 2 + sum(update.sync_committee_bits) * 3 >= len(update.sync_committee_bits) * 2 and update.finality_header != BeaconBlockHeader() ): # Apply update if (1) 2/3 quorum is reached and (2) we have a finality proof. From 3b803241193083696c2922f5983712a269d8d62b Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Tue, 4 May 2021 13:42:02 -0700 Subject: [PATCH 2/6] Compute `LIGHT_CLIENT_UPDATE_TIMEOUT` in lieu of maintaining a constant --- configs/mainnet/altair.yaml | 2 -- configs/minimal/altair.yaml | 2 -- specs/altair/sync-protocol.md | 10 ++-------- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/configs/mainnet/altair.yaml b/configs/mainnet/altair.yaml index 3cd4b8419..6db260cca 100644 --- a/configs/mainnet/altair.yaml +++ b/configs/mainnet/altair.yaml @@ -47,8 +47,6 @@ ALTAIR_FORK_EPOCH: 18446744073709551615 MIN_SYNC_COMMITTEE_PARTICIPANTS: 1 # 2**13 MAX_VALID_LIGHT_CLIENT_UPDATES: 8192 -# 2**13 (=8192) -LIGHT_CLIENT_UPDATE_TIMEOUT: 8192 # Validator diff --git a/configs/minimal/altair.yaml b/configs/minimal/altair.yaml index f9b30eea2..5c5781010 100644 --- a/configs/minimal/altair.yaml +++ b/configs/minimal/altair.yaml @@ -47,8 +47,6 @@ ALTAIR_FORK_EPOCH: 18446744073709551615 MIN_SYNC_COMMITTEE_PARTICIPANTS: 1 # [customized] MAX_VALID_LIGHT_CLIENT_UPDATES: 32 -# [customized] -LIGHT_CLIENT_UPDATE_TIMEOUT: 32 # Validator # --------------------------------------------------------------- diff --git a/specs/altair/sync-protocol.md b/specs/altair/sync-protocol.md index fba263bb1..ca55c92f7 100644 --- a/specs/altair/sync-protocol.md +++ b/specs/altair/sync-protocol.md @@ -12,7 +12,6 @@ - [Constants](#constants) - [Configuration](#configuration) - [Misc](#misc) - - [Time parameters](#time-parameters) - [Containers](#containers) - [`LightClientSnapshot`](#lightclientsnapshot) - [`LightClientUpdate`](#lightclientupdate) @@ -53,12 +52,6 @@ uses sync committees introduced in [this beacon chain extension](./beacon-chain. | `MIN_SYNC_COMMITTEE_PARTICIPANTS` | `1` | | `MAX_VALID_LIGHT_CLIENT_UPDATES` | `uint64(2**64 - 1)` | -### Time parameters - -| Name | Value | Unit | Duration | -| - | - | :-: | :-: | -| `LIGHT_CLIENT_UPDATE_TIMEOUT` | `Slot(2**13)` | slots | ~27 hours | - ## Containers ### `LightClientSnapshot` @@ -184,6 +177,7 @@ def process_light_client_update(store: LightClientStore, update: LightClientUpda validate_light_client_update(store.snapshot, update, genesis_validators_root) store.valid_updates.append(update) + update_timeout = SLOTS_PER_EPOCH * EPOCHS_PER_SYNC_COMMITTEE_PERIOD if ( sum(update.sync_committee_bits) * 3 >= len(update.sync_committee_bits) * 2 and update.finality_header != BeaconBlockHeader() @@ -193,7 +187,7 @@ def process_light_client_update(store: LightClientStore, update: LightClientUpda # It may be changed to re-organizable light client design. See the on-going issue eth2.0-specs#2182. apply_light_client_update(store.snapshot, update) store.valid_updates = [] - elif current_slot > store.snapshot.header.slot + LIGHT_CLIENT_UPDATE_TIMEOUT: + elif current_slot > store.snapshot.header.slot + update_timeout: # Forced best update when the update timeout has elapsed apply_light_client_update(store.snapshot, max(store.valid_updates, key=lambda update: sum(update.sync_committee_bits))) From 165c960cf15b63c30bed2dd2ce9b1a36c7734093 Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Tue, 4 May 2021 13:46:30 -0700 Subject: [PATCH 3/6] Update config value to reflect spec --- configs/mainnet/altair.yaml | 4 ++-- configs/minimal/altair.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configs/mainnet/altair.yaml b/configs/mainnet/altair.yaml index 6db260cca..b7b7603a2 100644 --- a/configs/mainnet/altair.yaml +++ b/configs/mainnet/altair.yaml @@ -45,8 +45,8 @@ ALTAIR_FORK_EPOCH: 18446744073709551615 # --------------------------------------------------------------- # 1 MIN_SYNC_COMMITTEE_PARTICIPANTS: 1 -# 2**13 -MAX_VALID_LIGHT_CLIENT_UPDATES: 8192 +# 2**64 - 1 +MAX_VALID_LIGHT_CLIENT_UPDATES: 18446744073709551615 # Validator diff --git a/configs/minimal/altair.yaml b/configs/minimal/altair.yaml index 5c5781010..5618af8ff 100644 --- a/configs/minimal/altair.yaml +++ b/configs/minimal/altair.yaml @@ -45,8 +45,8 @@ ALTAIR_FORK_EPOCH: 18446744073709551615 # --------------------------------------------------------------- # 1 MIN_SYNC_COMMITTEE_PARTICIPANTS: 1 -# [customized] -MAX_VALID_LIGHT_CLIENT_UPDATES: 32 +# 2**64 - 1 +MAX_VALID_LIGHT_CLIENT_UPDATES: 18446744073709551615 # Validator # --------------------------------------------------------------- From 4c73fec88e61e83240d0d45270e7afafb0d17d0f Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Thu, 6 May 2021 10:00:04 -0700 Subject: [PATCH 4/6] convert `LightClientStore` to python object instead of SSZ object this avoids the type overhead of having to define a max size for the object's data and skips the overhead of serialization/consensus for a type that does not need it --- configs/mainnet/altair.yaml | 2 -- configs/minimal/altair.yaml | 3 +-- setup.py | 2 +- specs/altair/sync-protocol.md | 12 ++++++------ .../test/altair/unittests/test_sync_protocol.py | 8 ++++---- 5 files changed, 12 insertions(+), 15 deletions(-) diff --git a/configs/mainnet/altair.yaml b/configs/mainnet/altair.yaml index b7b7603a2..eac4e1c14 100644 --- a/configs/mainnet/altair.yaml +++ b/configs/mainnet/altair.yaml @@ -45,8 +45,6 @@ ALTAIR_FORK_EPOCH: 18446744073709551615 # --------------------------------------------------------------- # 1 MIN_SYNC_COMMITTEE_PARTICIPANTS: 1 -# 2**64 - 1 -MAX_VALID_LIGHT_CLIENT_UPDATES: 18446744073709551615 # Validator diff --git a/configs/minimal/altair.yaml b/configs/minimal/altair.yaml index 5618af8ff..0300ff1b8 100644 --- a/configs/minimal/altair.yaml +++ b/configs/minimal/altair.yaml @@ -45,8 +45,7 @@ ALTAIR_FORK_EPOCH: 18446744073709551615 # --------------------------------------------------------------- # 1 MIN_SYNC_COMMITTEE_PARTICIPANTS: 1 -# 2**64 - 1 -MAX_VALID_LIGHT_CLIENT_UPDATES: 18446744073709551615 + # Validator # --------------------------------------------------------------- diff --git a/setup.py b/setup.py index 37fbd7795..aad834e2c 100644 --- a/setup.py +++ b/setup.py @@ -548,7 +548,7 @@ ignored_dependencies = [ 'Bytes1', 'Bytes4', 'Bytes20', 'Bytes32', 'Bytes48', 'Bytes96', 'Bitlist', 'Bitvector', 'uint8', 'uint16', 'uint32', 'uint64', 'uint128', 'uint256', 'bytes', 'byte', 'ByteList', 'ByteVector', - 'Dict', 'dict', 'field', 'ceillog2', 'floorlog2', + 'Dict', 'dict', 'field', 'ceillog2', 'floorlog2', 'Set' ] diff --git a/specs/altair/sync-protocol.md b/specs/altair/sync-protocol.md index ca55c92f7..784ea63b2 100644 --- a/specs/altair/sync-protocol.md +++ b/specs/altair/sync-protocol.md @@ -50,7 +50,6 @@ uses sync committees introduced in [this beacon chain extension](./beacon-chain. | Name | Value | | - | - | | `MIN_SYNC_COMMITTEE_PARTICIPANTS` | `1` | -| `MAX_VALID_LIGHT_CLIENT_UPDATES` | `uint64(2**64 - 1)` | ## Containers @@ -87,9 +86,10 @@ class LightClientUpdate(Container): ### `LightClientStore` ```python -class LightClientStore(Container): +@dataclass +class LightClientStore(object): snapshot: LightClientSnapshot - valid_updates: List[LightClientUpdate, MAX_VALID_LIGHT_CLIENT_UPDATES] + valid_updates: Set[LightClientUpdate] ``` ## Helper functions @@ -175,7 +175,7 @@ def apply_light_client_update(snapshot: LightClientSnapshot, update: LightClient def process_light_client_update(store: LightClientStore, update: LightClientUpdate, current_slot: Slot, genesis_validators_root: Root) -> None: validate_light_client_update(store.snapshot, update, genesis_validators_root) - store.valid_updates.append(update) + store.valid_updates.add(update) update_timeout = SLOTS_PER_EPOCH * EPOCHS_PER_SYNC_COMMITTEE_PERIOD if ( @@ -186,10 +186,10 @@ def process_light_client_update(store: LightClientStore, update: LightClientUpda # Note that (2) means that the current light client design needs finality. # It may be changed to re-organizable light client design. See the on-going issue eth2.0-specs#2182. apply_light_client_update(store.snapshot, update) - store.valid_updates = [] + store.valid_updates = set() elif current_slot > store.snapshot.header.slot + update_timeout: # Forced best update when the update timeout has elapsed apply_light_client_update(store.snapshot, max(store.valid_updates, key=lambda update: sum(update.sync_committee_bits))) - store.valid_updates = [] + store.valid_updates = set() ``` 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 9b8c35e76..932a46ca5 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 @@ -32,7 +32,7 @@ def test_process_light_client_update_not_updated(spec, state): ) store = spec.LightClientStore( snapshot=pre_snapshot, - valid_updates=[] + valid_updates=set(), ) # Block at slot 1 doesn't increase sync committee period, so it won't update snapshot @@ -76,7 +76,7 @@ def test_process_light_client_update_not_updated(spec, state): spec.process_light_client_update(store, update, state.slot, state.genesis_validators_root) assert len(store.valid_updates) == 1 - assert store.valid_updates[0] == update + assert store.valid_updates.pop() == update assert store.snapshot == pre_snapshot @@ -91,7 +91,7 @@ def test_process_light_client_update_timeout(spec, state): ) store = spec.LightClientStore( snapshot=pre_snapshot, - valid_updates=[] + valid_updates=set(), ) # Forward to next sync committee period @@ -156,7 +156,7 @@ def test_process_light_client_update_finality_updated(spec, state): ) store = spec.LightClientStore( snapshot=pre_snapshot, - valid_updates=[] + valid_updates=set(), ) # Change finality From 953b0278a10bbf98ed1f6e921a7accf9b87b62c8 Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Thu, 6 May 2021 10:23:50 -0700 Subject: [PATCH 5/6] whitespace --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index aad834e2c..aaed891c4 100644 --- a/setup.py +++ b/setup.py @@ -167,7 +167,7 @@ def get_spec(file_name: str) -> SpecObject: comment = _get_eth2_spec_comment(child) if comment == "skip": should_skip = True - + return SpecObject( functions=functions, custom_types=custom_types, From 4b27b076f6c2b3e90b69f6ace83e89c13f3f30fe Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Thu, 6 May 2021 12:36:08 -0600 Subject: [PATCH 6/6] add missing comma --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index aaed891c4..039e8ab63 100644 --- a/setup.py +++ b/setup.py @@ -548,7 +548,7 @@ ignored_dependencies = [ 'Bytes1', 'Bytes4', 'Bytes20', 'Bytes32', 'Bytes48', 'Bytes96', 'Bitlist', 'Bitvector', 'uint8', 'uint16', 'uint32', 'uint64', 'uint128', 'uint256', 'bytes', 'byte', 'ByteList', 'ByteVector', - 'Dict', 'dict', 'field', 'ceillog2', 'floorlog2', 'Set' + 'Dict', 'dict', 'field', 'ceillog2', 'floorlog2', 'Set', ]