Skip to content

Commit ab5e8ce

Browse files
authored
simplify store mappings (#436)
1 parent 558a3cf commit ab5e8ce

File tree

14 files changed

+445
-724
lines changed

14 files changed

+445
-724
lines changed

packages/testing/src/consensus_testing/keys.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,7 @@
4646
)
4747
from lean_spec.subspecs.containers.slot import Slot
4848
from lean_spec.subspecs.koalabear import Fp
49-
from lean_spec.subspecs.xmss.aggregation import (
50-
AggregatedSignatureProof,
51-
SignatureKey,
52-
)
49+
from lean_spec.subspecs.xmss.aggregation import AggregatedSignatureProof
5350
from lean_spec.subspecs.xmss.constants import TARGET_CONFIG
5451
from lean_spec.subspecs.xmss.containers import KeyPair, PublicKey, Signature
5552
from lean_spec.subspecs.xmss.interface import (
@@ -333,7 +330,8 @@ def sign_attestation_data(
333330
def build_attestation_signatures(
334331
self,
335332
aggregated_attestations: AggregatedAttestations,
336-
signature_lookup: Mapping[SignatureKey, Signature] | None = None,
333+
signature_lookup: Mapping[AttestationData, Mapping[ValidatorIndex, Signature]]
334+
| None = None,
337335
) -> AttestationSignatures:
338336
"""
339337
Build attestation signatures for already-aggregated attestations.
@@ -349,12 +347,12 @@ def build_attestation_signatures(
349347
message = agg.data.data_root_bytes()
350348
slot = agg.data.slot
351349

350+
# Look up pre-computed signatures by attestation data and validator ID.
351+
sigs_for_data = lookup.get(agg.data, {})
352+
352353
public_keys: list[PublicKey] = [self.get_public_key(vid) for vid in validator_ids]
353354
signatures: list[Signature] = [
354-
(
355-
lookup.get(SignatureKey(vid, message))
356-
or self.sign_attestation_data(vid, agg.data)
357-
)
355+
sigs_for_data.get(vid) or self.sign_attestation_data(vid, agg.data)
358356
for vid in validator_ids
359357
]
360358

packages/testing/src/consensus_testing/test_fixtures/fork_choice.py

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from __future__ import annotations
99

10-
from typing import ClassVar, Self
10+
from typing import ClassVar, Mapping, Self
1111

1212
from pydantic import model_validator
1313

@@ -38,7 +38,6 @@
3838
from lean_spec.subspecs.containers.validator import ValidatorIndex
3939
from lean_spec.subspecs.forkchoice import Store
4040
from lean_spec.subspecs.ssz import hash_tree_root
41-
from lean_spec.subspecs.xmss.aggregation import SignatureKey
4241
from lean_spec.subspecs.xmss.containers import Signature
4342
from lean_spec.types import Bytes32, Uint64
4443

@@ -381,20 +380,23 @@ def _build_block_from_spec(
381380
#
382381
# Attestations vote for blocks and influence fork choice weight.
383382
# The spec may include attestations to include in this block.
384-
attestations, attestation_signatures, valid_signature_keys = (
385-
self._build_attestations_from_spec(
386-
spec, store, block_registry, parent_root, key_manager
387-
)
383+
(
384+
attestations,
385+
attestation_signatures,
386+
valid_attestations,
387+
) = self._build_attestations_from_spec(
388+
spec, store, block_registry, parent_root, key_manager
388389
)
389390

390-
# Merge per-attestation signatures into the Store's gossip signature cache.
391-
# Required so the Store can aggregate committee signatures later when building payloads.
391+
# Merge valid attestation signatures into the Store's gossip cache.
392+
# Only attestations with valid (non-dummy) signatures are merged.
392393
working_store = store
393-
for attestation in attestations:
394-
sig_key = SignatureKey(attestation.validator_id, attestation.data.data_root_bytes())
395-
if sig_key not in valid_signature_keys:
396-
continue
397-
if (signature := attestation_signatures.get(sig_key)) is None:
394+
for attestation in valid_attestations:
395+
sigs_for_data = attestation_signatures.get(attestation.data)
396+
if (
397+
sigs_for_data is None
398+
or (signature := sigs_for_data.get(attestation.validator_id)) is None
399+
):
398400
continue
399401
working_store = working_store.on_gossip_attestation(
400402
SignedAttestation(
@@ -564,7 +566,11 @@ def _build_attestations_from_spec(
564566
block_registry: dict[str, Block],
565567
parent_root: Bytes32,
566568
key_manager: XmssKeyManager,
567-
) -> tuple[list[Attestation], dict[SignatureKey, Signature], set[SignatureKey]]:
569+
) -> tuple[
570+
list[Attestation],
571+
Mapping[AttestationData, Mapping[ValidatorIndex, Signature]],
572+
set[Attestation],
573+
]:
568574
"""
569575
Build attestations and signatures from block specification.
570576
@@ -580,16 +586,16 @@ def _build_attestations_from_spec(
580586
key_manager: Key manager for signing.
581587
582588
Returns:
583-
Tuple of (attestations list, signature lookup dict, valid signature keys).
589+
Tuple of (attestations list, signature lookup by data, valid attestations).
584590
"""
585591
# No attestations specified means empty block body.
586592
if spec.attestations is None:
587593
return [], {}, set()
588594

589595
parent_state = store.states[parent_root]
590596
attestations = []
591-
signature_lookup: dict[SignatureKey, Signature] = {}
592-
valid_signature_keys: set[SignatureKey] = set()
597+
signature_lookup: Mapping[AttestationData, Mapping[ValidatorIndex, Signature]] = {}
598+
valid_attestations: set[Attestation] = set()
593599

594600
for aggregated_spec in spec.attestations:
595601
# Build attestation data once.
@@ -614,19 +620,19 @@ def _build_attestations_from_spec(
614620
validator_id,
615621
attestation_data,
616622
)
623+
valid_attestations.add(attestation)
617624
else:
618625
# Dummy signature for testing invalid signature handling.
619626
# The Store should reject attestations with bad signatures.
620627
signature = create_dummy_signature()
621628

622-
# Index signature by validator and data root.
623-
# This enables lookup during signature aggregation.
624-
sig_key = SignatureKey(validator_id, attestation_data.data_root_bytes())
625-
signature_lookup[sig_key] = signature
626-
if aggregated_spec.valid_signature:
627-
valid_signature_keys.add(sig_key)
629+
# Index signature by attestation data and validator ID.
630+
signature_lookup.setdefault(attestation_data, {}).setdefault(
631+
validator_id,
632+
signature,
633+
)
628634

629-
return attestations, signature_lookup, valid_signature_keys
635+
return attestations, signature_lookup, valid_attestations
630636

631637
def _build_attestation_data_from_spec(
632638
self,

0 commit comments

Comments
 (0)