diff --git a/packages/testing/src/consensus_testing/keys.py b/packages/testing/src/consensus_testing/keys.py index 556efe87..4819408e 100755 --- a/packages/testing/src/consensus_testing/keys.py +++ b/packages/testing/src/consensus_testing/keys.py @@ -44,8 +44,10 @@ AttestationSignatures, ) from lean_spec.subspecs.containers.slot import Slot -from lean_spec.subspecs.containers.state.types import AttestationSignatureKey -from lean_spec.subspecs.xmss.aggregation import MultisigAggregatedSignature +from lean_spec.subspecs.xmss.aggregation import ( + AttestationSignatureKey, + MultisigAggregatedSignature, +) from lean_spec.subspecs.xmss.containers import KeyPair, PublicKey, Signature from lean_spec.subspecs.xmss.interface import ( PROD_SIGNATURE_SCHEME, diff --git a/packages/testing/src/consensus_testing/test_fixtures/fork_choice.py b/packages/testing/src/consensus_testing/test_fixtures/fork_choice.py index 38e30a07..3f62bec1 100644 --- a/packages/testing/src/consensus_testing/test_fixtures/fork_choice.py +++ b/packages/testing/src/consensus_testing/test_fixtures/fork_choice.py @@ -26,10 +26,10 @@ from lean_spec.subspecs.containers.slot import Slot from lean_spec.subspecs.containers.state import Validators from lean_spec.subspecs.containers.state.state import State -from lean_spec.subspecs.containers.state.types import AttestationSignatureKey from lean_spec.subspecs.forkchoice import Store from lean_spec.subspecs.koalabear import Fp from lean_spec.subspecs.ssz import hash_tree_root +from lean_spec.subspecs.xmss.aggregation import AttestationSignatureKey from lean_spec.subspecs.xmss.containers import Signature from lean_spec.subspecs.xmss.types import HashDigestList, HashTreeOpening, Randomness from lean_spec.types import Bytes32, Uint64 diff --git a/src/lean_spec/subspecs/containers/__init__.py b/src/lean_spec/subspecs/containers/__init__.py index 0cf54111..33ce84af 100644 --- a/src/lean_spec/subspecs/containers/__init__.py +++ b/src/lean_spec/subspecs/containers/__init__.py @@ -13,8 +13,7 @@ AggregationBits, Attestation, AttestationData, - NaiveAggregatedSignature, - SignedAggregatedAttestation, + AttestationsByValidator, SignedAttestation, ) from .block import ( @@ -31,19 +30,18 @@ __all__ = [ "AggregatedAttestation", - "NaiveAggregatedSignature", "AggregationBits", - "AttestationData", "Attestation", - "SignedAttestation", - "SignedAggregatedAttestation", + "AttestationData", + "AttestationsByValidator", "Block", - "BlockWithAttestation", "BlockBody", "BlockHeader", + "BlockWithAttestation", "Checkpoint", "Config", + "SignedAttestation", "SignedBlockWithAttestation", - "Validator", "State", + "Validator", ] diff --git a/src/lean_spec/subspecs/containers/attestation/__init__.py b/src/lean_spec/subspecs/containers/attestation/__init__.py index 7e05a530..615d2f4d 100644 --- a/src/lean_spec/subspecs/containers/attestation/__init__.py +++ b/src/lean_spec/subspecs/containers/attestation/__init__.py @@ -4,17 +4,15 @@ AggregatedAttestation, Attestation, AttestationData, - SignedAggregatedAttestation, SignedAttestation, ) -from .types import AggregationBits, NaiveAggregatedSignature +from .types import AggregationBits, AttestationsByValidator __all__ = [ - "AttestationData", - "Attestation", - "SignedAttestation", - "SignedAggregatedAttestation", "AggregatedAttestation", - "NaiveAggregatedSignature", "AggregationBits", + "Attestation", + "AttestationData", + "AttestationsByValidator", + "SignedAttestation", ] diff --git a/src/lean_spec/subspecs/containers/attestation/attestation.py b/src/lean_spec/subspecs/containers/attestation/attestation.py index dedc6f7d..be6acb34 100644 --- a/src/lean_spec/subspecs/containers/attestation/attestation.py +++ b/src/lean_spec/subspecs/containers/attestation/attestation.py @@ -22,7 +22,7 @@ from ...xmss.containers import Signature from ..checkpoint import Checkpoint -from .types import AggregationBits, NaiveAggregatedSignature +from .types import AggregationBits class AttestationData(Container): @@ -107,22 +107,3 @@ def aggregate_by_data( ) for data, validator_ids in data_to_validator_ids.items() ] - - -class SignedAggregatedAttestation(Container): - """Aggregated attestation bundled with aggregated signatures.""" - - message: AggregatedAttestation - """Aggregated attestation data.""" - - signature: NaiveAggregatedSignature - """Aggregated attestation plus its combined signature. - - Stores a naive list of validator signatures that mirrors the attestation - order. - - TODO: - - signatures will be replaced by MegaBytes in next PR to include leanVM proof. - - this will be replaced by a SNARK in future devnets. - - this will be aggregated by aggregators in future devnets. - """ diff --git a/src/lean_spec/subspecs/containers/attestation/types.py b/src/lean_spec/subspecs/containers/attestation/types.py index 8304db5f..0e34c6b6 100644 --- a/src/lean_spec/subspecs/containers/attestation/types.py +++ b/src/lean_spec/subspecs/containers/attestation/types.py @@ -2,11 +2,18 @@ from __future__ import annotations -from lean_spec.types import SSZList, Uint64 +from typing import TYPE_CHECKING + +from lean_spec.types import Uint64 from lean_spec.types.bitfields import BaseBitlist from ...chain.config import VALIDATOR_REGISTRY_LIMIT -from ...xmss.containers import Signature + +if TYPE_CHECKING: + from .attestation import AttestationData + +AttestationsByValidator = dict[Uint64, "AttestationData"] +"""Mapping from validator index to attestation data.""" class AggregationBits(BaseBitlist): @@ -57,10 +64,3 @@ def to_validator_indices(self) -> list[Uint64]: raise AssertionError("Aggregated attestation must reference at least one validator") return indices - - -class NaiveAggregatedSignature(SSZList[Signature]): - """Naive list of validator signatures used for aggregation placeholders.""" - - ELEMENT_TYPE = Signature - LIMIT = int(VALIDATOR_REGISTRY_LIMIT) diff --git a/src/lean_spec/subspecs/containers/block/__init__.py b/src/lean_spec/subspecs/containers/block/__init__.py index 4ed7dfa7..50f5299a 100644 --- a/src/lean_spec/subspecs/containers/block/__init__.py +++ b/src/lean_spec/subspecs/containers/block/__init__.py @@ -11,12 +11,14 @@ from .types import ( AggregatedAttestations, AttestationSignatures, + BlockLookup, ) __all__ = [ "Block", "BlockBody", "BlockHeader", + "BlockLookup", "BlockSignatures", "BlockWithAttestation", "SignedBlockWithAttestation", diff --git a/src/lean_spec/subspecs/containers/block/types.py b/src/lean_spec/subspecs/containers/block/types.py index 39fb4e03..e16a93d9 100644 --- a/src/lean_spec/subspecs/containers/block/types.py +++ b/src/lean_spec/subspecs/containers/block/types.py @@ -1,11 +1,21 @@ """Block-specific SSZ types for the Lean Ethereum consensus specification.""" +from __future__ import annotations + +from typing import TYPE_CHECKING + from lean_spec.subspecs.xmss.aggregation import MultisigAggregatedSignature -from lean_spec.types import SSZList +from lean_spec.types import Bytes32, SSZList from ...chain.config import VALIDATOR_REGISTRY_LIMIT from ..attestation import AggregatedAttestation +if TYPE_CHECKING: + from .block import Block + +BlockLookup = dict[Bytes32, "Block"] +"""Mapping from block root to Block objects.""" + class AggregatedAttestations(SSZList[AggregatedAttestation]): """List of aggregated attestations included in a block.""" diff --git a/src/lean_spec/subspecs/containers/state/__init__.py b/src/lean_spec/subspecs/containers/state/__init__.py index 8fe22bb6..4bda075e 100644 --- a/src/lean_spec/subspecs/containers/state/__init__.py +++ b/src/lean_spec/subspecs/containers/state/__init__.py @@ -2,11 +2,6 @@ from .state import State from .types import ( - AggregatedSignaturePayload, - AggregatedSignaturePayloads, - AttestationsByValidator, - AttestationSignatureKey, - BlockLookup, HistoricalBlockHashes, JustificationRoots, JustificationValidators, @@ -16,16 +11,11 @@ ) __all__ = [ - "State", - "AggregatedSignaturePayload", - "AggregatedSignaturePayloads", - "AttestationSignatureKey", - "AttestationsByValidator", - "BlockLookup", "HistoricalBlockHashes", "JustificationRoots", "JustificationValidators", "JustifiedSlots", + "State", "StateLookup", "Validators", ] diff --git a/src/lean_spec/subspecs/containers/state/state.py b/src/lean_spec/subspecs/containers/state/state.py index 0f6dc864..7eb33fb4 100644 --- a/src/lean_spec/subspecs/containers/state/state.py +++ b/src/lean_spec/subspecs/containers/state/state.py @@ -3,7 +3,11 @@ from typing import AbstractSet, Iterable from lean_spec.subspecs.ssz.hash import hash_tree_root -from lean_spec.subspecs.xmss.aggregation import MultisigAggregatedSignature +from lean_spec.subspecs.xmss.aggregation import ( + AggregatedSignaturePayloads, + AttestationSignatureKey, + MultisigAggregatedSignature, +) from lean_spec.subspecs.xmss.containers import PublicKey, Signature from lean_spec.types import ( ZERO_HASH, @@ -21,8 +25,6 @@ from ..config import Config from ..slot import Slot from .types import ( - AggregatedSignaturePayloads, - AttestationSignatureKey, HistoricalBlockHashes, JustificationRoots, JustificationValidators, diff --git a/src/lean_spec/subspecs/containers/state/types.py b/src/lean_spec/subspecs/containers/state/types.py index e081f969..33122848 100644 --- a/src/lean_spec/subspecs/containers/state/types.py +++ b/src/lean_spec/subspecs/containers/state/types.py @@ -5,36 +5,17 @@ from typing import TYPE_CHECKING from lean_spec.subspecs.chain.config import DEVNET_CONFIG -from lean_spec.subspecs.xmss.aggregation import MultisigAggregatedSignature -from lean_spec.types import Bytes32, SSZList, Uint64 +from lean_spec.types import Bytes32, SSZList from lean_spec.types.bitfields import BaseBitlist -from ..attestation import AggregationBits, AttestationData -from ..block import Block from ..validator import Validator if TYPE_CHECKING: from .state import State -# Type aliases for signature aggregation -AttestationSignatureKey = tuple[Uint64, bytes] -"""Key type for looking up signatures: (validator_id, attestation_data_root).""" - -AggregatedSignaturePayload = tuple[AggregationBits, MultisigAggregatedSignature] -"""Aggregated signature payload with its participant bitlist.""" - -AggregatedSignaturePayloads = list[AggregatedSignaturePayload] -"""List of aggregated signature payloads with their participant bitlists.""" - -BlockLookup = dict[Bytes32, Block] -"""Mapping from block root to Block objects.""" - StateLookup = dict[Bytes32, "State"] """Mapping from state root to State objects.""" -AttestationsByValidator = dict[Uint64, AttestationData] -"""Mapping from validator index to attestation data.""" - class HistoricalBlockHashes(SSZList[Bytes32]): """List of historical block root hashes up to historical_roots_limit.""" diff --git a/src/lean_spec/subspecs/forkchoice/store.py b/src/lean_spec/subspecs/forkchoice/store.py index 78eb08a2..bf0e07ac 100644 --- a/src/lean_spec/subspecs/forkchoice/store.py +++ b/src/lean_spec/subspecs/forkchoice/store.py @@ -25,6 +25,7 @@ AggregationBits, Attestation, AttestationData, + AttestationsByValidator, Block, Checkpoint, Config, @@ -32,16 +33,15 @@ SignedBlockWithAttestation, State, ) +from lean_spec.subspecs.containers.block import BlockLookup from lean_spec.subspecs.containers.slot import Slot -from lean_spec.subspecs.containers.state.types import ( +from lean_spec.subspecs.containers.state import StateLookup +from lean_spec.subspecs.ssz.hash import hash_tree_root +from lean_spec.subspecs.xmss.aggregation import ( AggregatedSignaturePayloads, - AttestationsByValidator, AttestationSignatureKey, - BlockLookup, - StateLookup, + MultisigAggregatedSignature, ) -from lean_spec.subspecs.ssz.hash import hash_tree_root -from lean_spec.subspecs.xmss.aggregation import MultisigAggregatedSignature from lean_spec.subspecs.xmss.containers import Signature from lean_spec.subspecs.xmss.interface import TARGET_SIGNATURE_SCHEME, GeneralizedXmssScheme from lean_spec.types import ( diff --git a/src/lean_spec/subspecs/xmss/aggregation.py b/src/lean_spec/subspecs/xmss/aggregation.py index 0da86fd2..9cbe813c 100644 --- a/src/lean_spec/subspecs/xmss/aggregation.py +++ b/src/lean_spec/subspecs/xmss/aggregation.py @@ -7,7 +7,7 @@ from __future__ import annotations -from typing import Self, Sequence +from typing import TYPE_CHECKING, Self, Sequence from lean_multisig_py import aggregate_signatures as aggregate_signatures_py from lean_multisig_py import setup_prover, setup_verifier @@ -18,6 +18,12 @@ from lean_spec.types import Uint64 from lean_spec.types.byte_arrays import ByteListMiB +if TYPE_CHECKING: + from lean_spec.subspecs.containers.attestation import AggregationBits + +AttestationSignatureKey = tuple[Uint64, bytes] +"""Key type for looking up signatures: (validator id, attestation data root).""" + class MultisigError(RuntimeError): """Base exception for multisig aggregation helpers.""" @@ -108,3 +114,10 @@ def verify_aggregated_payload( ) except Exception as exc: raise MultisigAggregationError(f"Multisig verification failed: {exc}") from exc + + +AggregatedSignaturePayload = tuple["AggregationBits", "MultisigAggregatedSignature"] +"""Aggregated signature payload with its participant bitlist.""" + +AggregatedSignaturePayloads = list[AggregatedSignaturePayload] +"""List of aggregated signature payloads with their participant bitlists."""