diff --git a/specs/altair/light-client/sync-protocol.md b/specs/altair/light-client/sync-protocol.md index f85c55258d..6d212300f7 100644 --- a/specs/altair/light-client/sync-protocol.md +++ b/specs/altair/light-client/sync-protocol.md @@ -272,6 +272,8 @@ def is_better_update(new_update: LightClientUpdate, old_update: LightClientUpdat # Tiebreaker 2: Prefer older data (fewer changes to best) if new_update.attested_header.beacon.slot != old_update.attested_header.beacon.slot: return new_update.attested_header.beacon.slot < old_update.attested_header.beacon.slot + + # Tiebreaker 3: Prefer updates with earlier signature slots return new_update.signature_slot < old_update.signature_slot ``` diff --git a/tests/core/pyspec/eth2spec/test/altair/light_client/test_update_ranking.py b/tests/core/pyspec/eth2spec/test/altair/light_client/test_update_ranking.py index 5bca370ab5..4f8575bd50 100644 --- a/tests/core/pyspec/eth2spec/test/altair/light_client/test_update_ranking.py +++ b/tests/core/pyspec/eth2spec/test/altair/light_client/test_update_ranking.py @@ -16,7 +16,7 @@ ) -def create_test_update(spec, test, with_next, with_finality, participation_rate): +def create_test_update(spec, test, with_next, with_finality, participation_rate, signature_slot=None): attested_state, attested_block, finalized_block = test return create_update( spec, @@ -26,6 +26,7 @@ def create_test_update(spec, test, with_next, with_finality, participation_rate) with_next, with_finality, participation_rate, + signature_slot=signature_slot, ) @@ -132,6 +133,15 @@ def test_update_ranking(spec, state): 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), + # Test signature_slot tiebreaker: identical update but with later signature_slot + create_test_update( + spec, + lat, + with_next=0, + with_finality=0, + participation_rate=0.2, + signature_slot=lat_attested_state.slot + 2, + ), ] yield "updates", updates diff --git a/tests/core/pyspec/eth2spec/test/helpers/light_client.py b/tests/core/pyspec/eth2spec/test/helpers/light_client.py index c9334788ae..b3c1a914be 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/light_client.py +++ b/tests/core/pyspec/eth2spec/test/helpers/light_client.py @@ -86,7 +86,8 @@ def create_update(spec, finalized_block, with_next, with_finality, - participation_rate): + participation_rate, + signature_slot=None): num_participants = floor(spec.SYNC_COMMITTEE_SIZE * participation_rate) update = spec.LightClientUpdate() @@ -104,7 +105,7 @@ def create_update(spec, attested_state, latest_finalized_root_gindex(spec)) update.sync_aggregate, update.signature_slot = get_sync_aggregate( - spec, attested_state, num_participants) + spec, attested_state, num_participants, signature_slot=signature_slot) return update