diff --git a/packages/testing/src/consensus_testing/__init__.py b/packages/testing/src/consensus_testing/__init__.py index 3f2544a0f..b0c31f99c 100644 --- a/packages/testing/src/consensus_testing/__init__.py +++ b/packages/testing/src/consensus_testing/__init__.py @@ -2,9 +2,9 @@ from typing import Type -from . import forks -from .genesis import build_anchor, generate_pre_state -from .test_fixtures import ( +from consensus_testing import forks +from consensus_testing.genesis import build_anchor, generate_pre_state +from consensus_testing.test_fixtures import ( ApiEndpointTest, BaseConsensusFixture, DropComponentMessageBinding, @@ -28,7 +28,7 @@ VerifySignaturesTest, VerifySingleMessageProofsTest, ) -from .test_types import ( +from consensus_testing.test_types import ( AggregatedAttestationCheck, AggregatedAttestationSpec, AttestationCheck, diff --git a/packages/testing/src/consensus_testing/forks/__init__.py b/packages/testing/src/consensus_testing/forks/__init__.py index 99b3a817d..289fa89bf 100644 --- a/packages/testing/src/consensus_testing/forks/__init__.py +++ b/packages/testing/src/consensus_testing/forks/__init__.py @@ -4,8 +4,8 @@ from framework.forks import BaseFork, BaseForkMeta, ForkRegistry -from . import forks as _forks_module -from .forks import Lstar +from consensus_testing.forks import forks as _forks_module +from consensus_testing.forks.forks import Lstar Fork = Type[BaseFork] diff --git a/packages/testing/src/consensus_testing/genesis.py b/packages/testing/src/consensus_testing/genesis.py index 930143711..ccd66281e 100644 --- a/packages/testing/src/consensus_testing/genesis.py +++ b/packages/testing/src/consensus_testing/genesis.py @@ -1,5 +1,6 @@ """Consensus layer pre-state generation.""" +from consensus_testing.keys import XmssKeyManager from lean_spec.spec.crypto.merkleization import hash_tree_root from lean_spec.spec.forks import Slot, ValidatorIndex from lean_spec.spec.forks.lstar.containers import ( @@ -13,8 +14,6 @@ from lean_spec.spec.forks.lstar.spec import LstarSpec from lean_spec.spec.ssz import Bytes52, Uint64 -from .keys import XmssKeyManager - _DEFAULT_GENESIS_TIME = Uint64(0) diff --git a/packages/testing/src/consensus_testing/test_fixtures/__init__.py b/packages/testing/src/consensus_testing/test_fixtures/__init__.py index a11046180..42fb8e21d 100644 --- a/packages/testing/src/consensus_testing/test_fixtures/__init__.py +++ b/packages/testing/src/consensus_testing/test_fixtures/__init__.py @@ -1,17 +1,17 @@ """Consensus test fixture format definitions (Pydantic models).""" -from .api_endpoint import ApiEndpointTest -from .base import BaseConsensusFixture -from .fork_choice import ForkChoiceTest -from .gossipsub_handler import GossipsubHandlerTest -from .justifiability import JustifiabilityTest -from .networking_codec import NetworkingCodecTest -from .poseidon_permutation import PoseidonPermutationTest -from .slot_clock import SlotClockTest -from .ssz import SSZTest -from .state_transition import StateTransitionTest -from .sync import SyncTest -from .verify_multi_message_proofs import ( +from consensus_testing.test_fixtures.api_endpoint import ApiEndpointTest +from consensus_testing.test_fixtures.base import BaseConsensusFixture +from consensus_testing.test_fixtures.fork_choice import ForkChoiceTest +from consensus_testing.test_fixtures.gossipsub_handler import GossipsubHandlerTest +from consensus_testing.test_fixtures.justifiability import JustifiabilityTest +from consensus_testing.test_fixtures.networking_codec import NetworkingCodecTest +from consensus_testing.test_fixtures.poseidon_permutation import PoseidonPermutationTest +from consensus_testing.test_fixtures.slot_clock import SlotClockTest +from consensus_testing.test_fixtures.ssz import SSZTest +from consensus_testing.test_fixtures.state_transition import StateTransitionTest +from consensus_testing.test_fixtures.sync import SyncTest +from consensus_testing.test_fixtures.verify_multi_message_proofs import ( DropComponentMessageBinding, IncrementComponentSlot, RebindComponentToAlternateHeadRoot, @@ -19,8 +19,8 @@ SwapComponentParticipantPublicKey, VerifyMultiMessageProofsTest, ) -from .verify_signatures import VerifySignaturesTest -from .verify_single_message_proofs import ( +from consensus_testing.test_fixtures.verify_signatures import VerifySignaturesTest +from consensus_testing.test_fixtures.verify_single_message_proofs import ( IncrementEmittedSlot, RebindToAlternateHeadRoot, SwapParticipantPublicKey, diff --git a/packages/testing/src/consensus_testing/test_fixtures/api_endpoint.py b/packages/testing/src/consensus_testing/test_fixtures/api_endpoint.py index 8477a1db3..35eea7b19 100644 --- a/packages/testing/src/consensus_testing/test_fixtures/api_endpoint.py +++ b/packages/testing/src/consensus_testing/test_fixtures/api_endpoint.py @@ -3,6 +3,8 @@ from collections.abc import Callable from typing import Any, ClassVar +from consensus_testing.genesis import build_anchor, generate_pre_state +from consensus_testing.test_fixtures.base import BaseConsensusFixture from lean_spec.spec.crypto.merkleization import hash_tree_root from lean_spec.spec.forks import Slot, ValidatorIndex from lean_spec.spec.forks.lstar import Store @@ -10,9 +12,6 @@ from lean_spec.spec.forks.lstar.spec import LstarSpec from lean_spec.spec.ssz import Bytes32, Uint64 -from ..genesis import build_anchor, generate_pre_state -from .base import BaseConsensusFixture - EndpointHandler = Callable[[Store, "ApiEndpointTest"], dict[str, Any]] """Uniform signature for all endpoint response builders. 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 7a0817658..c4b7fd313 100644 --- a/packages/testing/src/consensus_testing/test_fixtures/fork_choice.py +++ b/packages/testing/src/consensus_testing/test_fixtures/fork_choice.py @@ -11,6 +11,15 @@ from pydantic import Field, model_validator +from consensus_testing.keys import XmssKeyManager +from consensus_testing.test_fixtures.base import BaseConsensusFixture +from consensus_testing.test_types import ( + AttestationStep, + BlockStep, + ForkChoiceStep, + GossipAggregatedAttestationStep, + TickStep, +) from lean_spec.node.chain.clock import SlotClock from lean_spec.spec.crypto.merkleization import hash_tree_root from lean_spec.spec.forks import Interval, Slot, ValidatorIndex @@ -23,18 +32,6 @@ ) from lean_spec.spec.forks.lstar.spec import LstarSpec -from ..keys import ( - XmssKeyManager, -) -from ..test_types import ( - AttestationStep, - BlockStep, - ForkChoiceStep, - GossipAggregatedAttestationStep, - TickStep, -) -from .base import BaseConsensusFixture - class ForkChoiceTest(BaseConsensusFixture): """ diff --git a/packages/testing/src/consensus_testing/test_fixtures/gossipsub_handler.py b/packages/testing/src/consensus_testing/test_fixtures/gossipsub_handler.py index cd409bb02..a507dadda 100644 --- a/packages/testing/src/consensus_testing/test_fixtures/gossipsub_handler.py +++ b/packages/testing/src/consensus_testing/test_fixtures/gossipsub_handler.py @@ -13,6 +13,7 @@ from typing import Any, ClassVar from unittest.mock import patch +from consensus_testing.test_fixtures.base import BaseConsensusFixture from lean_spec.node.networking import PeerId from lean_spec.node.networking.gossipsub.behavior import GossipsubBehavior, PeerState from lean_spec.node.networking.gossipsub.message import GossipsubMessage @@ -29,8 +30,6 @@ ) from lean_spec.node.networking.gossipsub.types import MessageId, Timestamp, TopicId -from .base import BaseConsensusFixture - # Sentinel that satisfies `outbound_stream is not None` checks. # The patched _send_rpc never touches the stream, so any non-None value works. _FAKE_STREAM: Any = object() diff --git a/packages/testing/src/consensus_testing/test_fixtures/justifiability.py b/packages/testing/src/consensus_testing/test_fixtures/justifiability.py index 4c719bbe2..6fa483902 100644 --- a/packages/testing/src/consensus_testing/test_fixtures/justifiability.py +++ b/packages/testing/src/consensus_testing/test_fixtures/justifiability.py @@ -13,10 +13,9 @@ from typing import Any, ClassVar +from consensus_testing.test_fixtures.base import BaseConsensusFixture from lean_spec.spec.forks import Slot -from .base import BaseConsensusFixture - class JustifiabilityTest(BaseConsensusFixture): """Fixture for 3SF-mini justifiability conformance. diff --git a/packages/testing/src/consensus_testing/test_fixtures/networking_codec.py b/packages/testing/src/consensus_testing/test_fixtures/networking_codec.py index 4bfe3fd7c..6648e3c9f 100644 --- a/packages/testing/src/consensus_testing/test_fixtures/networking_codec.py +++ b/packages/testing/src/consensus_testing/test_fixtures/networking_codec.py @@ -2,6 +2,7 @@ from typing import Any, ClassVar +from consensus_testing.test_fixtures.base import BaseConsensusFixture from lean_spec.node.networking.enr.enr import ENR from lean_spec.node.networking.gossipsub.message import GossipsubMessage from lean_spec.node.networking.gossipsub.rpc import ( @@ -27,8 +28,6 @@ from lean_spec.node.snappy import compress, decompress, frame_compress, frame_decompress from lean_spec.spec.forks import SubnetId -from .base import BaseConsensusFixture - def _to_hex(data: bytes) -> str: """Format raw bytes as a 0x-prefixed hex string.""" diff --git a/packages/testing/src/consensus_testing/test_fixtures/poseidon_permutation.py b/packages/testing/src/consensus_testing/test_fixtures/poseidon_permutation.py index 2f2cc8baa..8286c33b1 100644 --- a/packages/testing/src/consensus_testing/test_fixtures/poseidon_permutation.py +++ b/packages/testing/src/consensus_testing/test_fixtures/poseidon_permutation.py @@ -7,11 +7,10 @@ from typing import Any, ClassVar +from consensus_testing.test_fixtures.base import BaseConsensusFixture from lean_spec.spec.crypto.koalabear import Fp from lean_spec.spec.crypto.poseidon import PARAMS_16, PARAMS_24, Poseidon -from .base import BaseConsensusFixture - class PoseidonPermutationTest(BaseConsensusFixture): """Fixture for Poseidon permutation conformance. diff --git a/packages/testing/src/consensus_testing/test_fixtures/slot_clock.py b/packages/testing/src/consensus_testing/test_fixtures/slot_clock.py index 691f0504b..911a22e56 100644 --- a/packages/testing/src/consensus_testing/test_fixtures/slot_clock.py +++ b/packages/testing/src/consensus_testing/test_fixtures/slot_clock.py @@ -7,6 +7,7 @@ from typing import Any, ClassVar +from consensus_testing.test_fixtures.base import BaseConsensusFixture from lean_spec.node.chain.clock import SlotClock from lean_spec.spec.forks import Interval, Slot from lean_spec.spec.forks.lstar.config import ( @@ -16,8 +17,6 @@ ) from lean_spec.spec.ssz import Uint64 -from .base import BaseConsensusFixture - class SlotClockTest(BaseConsensusFixture): """Fixture for slot clock timing conformance. diff --git a/packages/testing/src/consensus_testing/test_fixtures/ssz.py b/packages/testing/src/consensus_testing/test_fixtures/ssz.py index 99955094b..4f47bb0b8 100644 --- a/packages/testing/src/consensus_testing/test_fixtures/ssz.py +++ b/packages/testing/src/consensus_testing/test_fixtures/ssz.py @@ -4,14 +4,13 @@ from pydantic import field_serializer +from consensus_testing.test_fixtures.base import BaseConsensusFixture from lean_spec.base import CamelModel from lean_spec.spec.crypto.koalabear import Fp from lean_spec.spec.crypto.merkleization import hash_tree_root from lean_spec.spec.ssz.boolean import Boolean from lean_spec.spec.ssz.ssz_base import SSZType -from .base import BaseConsensusFixture - class SSZTest(BaseConsensusFixture): """Fixture for SSZ conformance testing. diff --git a/packages/testing/src/consensus_testing/test_fixtures/state_transition.py b/packages/testing/src/consensus_testing/test_fixtures/state_transition.py index 421218250..e0f20bf29 100644 --- a/packages/testing/src/consensus_testing/test_fixtures/state_transition.py +++ b/packages/testing/src/consensus_testing/test_fixtures/state_transition.py @@ -4,6 +4,9 @@ from pydantic import ConfigDict, PrivateAttr, field_serializer +from consensus_testing.keys import XmssKeyManager +from consensus_testing.test_fixtures.base import BaseConsensusFixture +from consensus_testing.test_types import AggregatedAttestationSpec, BlockSpec, StateExpectation from lean_spec.spec.crypto.merkleization import hash_tree_root from lean_spec.spec.forks import AggregationBits from lean_spec.spec.forks.lstar.containers import ( @@ -18,10 +21,6 @@ from lean_spec.spec.forks.lstar.spec import LstarSpec from lean_spec.spec.ssz import Bytes32 -from ..keys import XmssKeyManager -from ..test_types import AggregatedAttestationSpec, BlockSpec, StateExpectation -from .base import BaseConsensusFixture - class StateTransitionTest(BaseConsensusFixture): """ diff --git a/packages/testing/src/consensus_testing/test_fixtures/sync.py b/packages/testing/src/consensus_testing/test_fixtures/sync.py index e4227303b..58b54963a 100644 --- a/packages/testing/src/consensus_testing/test_fixtures/sync.py +++ b/packages/testing/src/consensus_testing/test_fixtures/sync.py @@ -7,14 +7,13 @@ from typing import Any, ClassVar +from consensus_testing.genesis import build_anchor, generate_pre_state +from consensus_testing.test_fixtures.base import BaseConsensusFixture from lean_spec.node.sync.checkpoint_sync import verify_checkpoint_state from lean_spec.spec.forks import Slot from lean_spec.spec.forks.lstar.spec import LstarSpec from lean_spec.spec.ssz import Uint64 -from ..genesis import build_anchor, generate_pre_state -from .base import BaseConsensusFixture - class SyncTest(BaseConsensusFixture): """Fixture for sync-layer conformance. diff --git a/packages/testing/src/consensus_testing/test_fixtures/verify_multi_message_proofs.py b/packages/testing/src/consensus_testing/test_fixtures/verify_multi_message_proofs.py index 12b517c0d..d069f3c37 100644 --- a/packages/testing/src/consensus_testing/test_fixtures/verify_multi_message_proofs.py +++ b/packages/testing/src/consensus_testing/test_fixtures/verify_multi_message_proofs.py @@ -6,6 +6,8 @@ from pydantic import BaseModel, Field +from consensus_testing.keys import XmssKeyManager +from consensus_testing.test_fixtures.base import BaseConsensusFixture from lean_spec.spec.crypto.merkleization import hash_tree_root from lean_spec.spec.crypto.xmss.containers import PublicKey from lean_spec.spec.forks import ( @@ -21,9 +23,6 @@ ) from lean_spec.spec.ssz import ByteList512KiB, Bytes32 -from ..keys import XmssKeyManager -from .base import BaseConsensusFixture - ALTERNATE_HEAD_ROOT: Bytes32 = Bytes32(b"\xee" * 32) """Sentinel head root used by the rebind tamper to bind one component off-target.""" diff --git a/packages/testing/src/consensus_testing/test_fixtures/verify_signatures.py b/packages/testing/src/consensus_testing/test_fixtures/verify_signatures.py index 11be0ec56..892cea2eb 100644 --- a/packages/testing/src/consensus_testing/test_fixtures/verify_signatures.py +++ b/packages/testing/src/consensus_testing/test_fixtures/verify_signatures.py @@ -6,6 +6,9 @@ from pydantic import Field +from consensus_testing.keys import XmssKeyManager +from consensus_testing.test_fixtures.base import BaseConsensusFixture +from consensus_testing.test_types import BlockSpec from lean_spec.spec.crypto.merkleization import hash_tree_root from lean_spec.spec.forks import AggregationBits, Checkpoint, Slot, ValidatorIndex from lean_spec.spec.forks.lstar.containers import ( @@ -19,10 +22,6 @@ from lean_spec.spec.forks.lstar.spec import LstarSpec from lean_spec.spec.ssz import Boolean, ByteList512KiB, Bytes32 -from ..keys import XmssKeyManager -from ..test_types import BlockSpec -from .base import BaseConsensusFixture - class VerifySignaturesTest(BaseConsensusFixture): """ diff --git a/packages/testing/src/consensus_testing/test_fixtures/verify_single_message_proofs.py b/packages/testing/src/consensus_testing/test_fixtures/verify_single_message_proofs.py index 1d20dd19f..a747efeeb 100644 --- a/packages/testing/src/consensus_testing/test_fixtures/verify_single_message_proofs.py +++ b/packages/testing/src/consensus_testing/test_fixtures/verify_single_message_proofs.py @@ -6,6 +6,8 @@ from pydantic import BaseModel, Field +from consensus_testing.keys import XmssKeyManager +from consensus_testing.test_fixtures.base import BaseConsensusFixture from lean_spec.spec.crypto.merkleization import hash_tree_root from lean_spec.spec.crypto.xmss.containers import PublicKey from lean_spec.spec.forks import ( @@ -20,9 +22,6 @@ ) from lean_spec.spec.ssz import ByteList512KiB, Bytes32 -from ..keys import XmssKeyManager -from .base import BaseConsensusFixture - ALTERNATE_HEAD_ROOT: Bytes32 = Bytes32(b"\xee" * 32) """Sentinel head root used by the rebind tamper to bind the proof off-target.""" diff --git a/packages/testing/src/consensus_testing/test_types/__init__.py b/packages/testing/src/consensus_testing/test_types/__init__.py index 75918b8c7..41007fb84 100644 --- a/packages/testing/src/consensus_testing/test_types/__init__.py +++ b/packages/testing/src/consensus_testing/test_types/__init__.py @@ -1,11 +1,13 @@ """Test types for consensus test fixtures.""" -from .aggregated_attestation_spec import AggregatedAttestationSpec -from .block_spec import BlockSpec -from .gossip_aggregated_attestation_spec import GossipAggregatedAttestationSpec -from .gossip_attestation_spec import GossipAttestationSpec -from .state_expectation import StateExpectation -from .step_types import ( +from consensus_testing.test_types.aggregated_attestation_spec import AggregatedAttestationSpec +from consensus_testing.test_types.block_spec import BlockSpec +from consensus_testing.test_types.gossip_aggregated_attestation_spec import ( + GossipAggregatedAttestationSpec, +) +from consensus_testing.test_types.gossip_attestation_spec import GossipAttestationSpec +from consensus_testing.test_types.state_expectation import StateExpectation +from consensus_testing.test_types.step_types import ( AttestationStep, BaseForkChoiceStep, BlockStep, @@ -13,7 +15,11 @@ GossipAggregatedAttestationStep, TickStep, ) -from .store_checks import AggregatedAttestationCheck, AttestationCheck, StoreChecks +from consensus_testing.test_types.store_checks import ( + AggregatedAttestationCheck, + AttestationCheck, + StoreChecks, +) __all__ = [ "AggregatedAttestationSpec", diff --git a/packages/testing/src/consensus_testing/test_types/aggregated_attestation_spec.py b/packages/testing/src/consensus_testing/test_types/aggregated_attestation_spec.py index fdb2e0b22..3afacdac2 100644 --- a/packages/testing/src/consensus_testing/test_types/aggregated_attestation_spec.py +++ b/packages/testing/src/consensus_testing/test_types/aggregated_attestation_spec.py @@ -2,6 +2,8 @@ from __future__ import annotations +from consensus_testing.keys import XmssKeyManager +from consensus_testing.test_types.utils import resolve_checkpoint from lean_spec.base import CamelModel from lean_spec.spec.forks import AggregationBits, Checkpoint, Slot, ValidatorIndex from lean_spec.spec.forks.lstar.containers import ( @@ -14,9 +16,6 @@ ) from lean_spec.spec.ssz import ByteList512KiB, Bytes32 -from ..keys import XmssKeyManager -from .utils import resolve_checkpoint - class AggregatedAttestationSpec(CamelModel): """ diff --git a/packages/testing/src/consensus_testing/test_types/block_spec.py b/packages/testing/src/consensus_testing/test_types/block_spec.py index 4f1f9075d..1e9c4a69a 100644 --- a/packages/testing/src/consensus_testing/test_types/block_spec.py +++ b/packages/testing/src/consensus_testing/test_types/block_spec.py @@ -5,6 +5,8 @@ import copy from collections import defaultdict +from consensus_testing.keys import XmssKeyManager, create_dummy_signature +from consensus_testing.test_types.aggregated_attestation_spec import AggregatedAttestationSpec from lean_spec.base import CamelModel from lean_spec.spec.crypto.merkleization import hash_tree_root from lean_spec.spec.crypto.xmss.containers import Signature @@ -26,9 +28,6 @@ from lean_spec.spec.forks.lstar.spec import LstarSpec from lean_spec.spec.ssz import ByteList512KiB, Bytes32 -from ..keys import XmssKeyManager, create_dummy_signature -from .aggregated_attestation_spec import AggregatedAttestationSpec - class BlockSpec(CamelModel): """ diff --git a/packages/testing/src/consensus_testing/test_types/gossip_aggregated_attestation_spec.py b/packages/testing/src/consensus_testing/test_types/gossip_aggregated_attestation_spec.py index 64a573dee..05af1c6da 100644 --- a/packages/testing/src/consensus_testing/test_types/gossip_aggregated_attestation_spec.py +++ b/packages/testing/src/consensus_testing/test_types/gossip_aggregated_attestation_spec.py @@ -2,6 +2,8 @@ from __future__ import annotations +from consensus_testing.keys import XmssKeyManager +from consensus_testing.test_types.utils import resolve_checkpoint from lean_spec.base import CamelModel from lean_spec.spec.forks import AggregationBits, Checkpoint, Slot, ValidatorIndex from lean_spec.spec.forks.lstar.containers import ( @@ -13,9 +15,6 @@ ) from lean_spec.spec.ssz import ByteList512KiB, Bytes32 -from ..keys import XmssKeyManager -from .utils import resolve_checkpoint - class GossipAggregatedAttestationSpec(CamelModel): """ diff --git a/packages/testing/src/consensus_testing/test_types/gossip_attestation_spec.py b/packages/testing/src/consensus_testing/test_types/gossip_attestation_spec.py index a2b7f4e31..68af09b07 100644 --- a/packages/testing/src/consensus_testing/test_types/gossip_attestation_spec.py +++ b/packages/testing/src/consensus_testing/test_types/gossip_attestation_spec.py @@ -2,6 +2,8 @@ from __future__ import annotations +from consensus_testing.keys import XmssKeyManager, create_dummy_signature +from consensus_testing.test_types.utils import resolve_checkpoint from lean_spec.base import CamelModel from lean_spec.spec.crypto.merkleization import hash_tree_root from lean_spec.spec.forks import Checkpoint, Slot, ValidatorIndex @@ -9,9 +11,6 @@ from lean_spec.spec.forks.lstar.spec import LstarSpec from lean_spec.spec.ssz import Bytes32 -from ..keys import XmssKeyManager, create_dummy_signature -from .utils import resolve_checkpoint - class GossipAttestationSpec(CamelModel): """ diff --git a/packages/testing/src/consensus_testing/test_types/state_expectation.py b/packages/testing/src/consensus_testing/test_types/state_expectation.py index 70e93015b..d96f223db 100644 --- a/packages/testing/src/consensus_testing/test_types/state_expectation.py +++ b/packages/testing/src/consensus_testing/test_types/state_expectation.py @@ -3,6 +3,7 @@ from collections.abc import Callable from typing import Any, ClassVar +from consensus_testing.test_types.utils import resolve_block_root from lean_spec.base import CamelModel from lean_spec.spec.forks import Slot from lean_spec.spec.forks.lstar.containers import ( @@ -15,8 +16,6 @@ ) from lean_spec.spec.ssz import Bytes32 -from .utils import resolve_block_root - class StateExpectation(CamelModel): """ diff --git a/packages/testing/src/consensus_testing/test_types/step_types.py b/packages/testing/src/consensus_testing/test_types/step_types.py index ec9768f05..00f829e0e 100644 --- a/packages/testing/src/consensus_testing/test_types/step_types.py +++ b/packages/testing/src/consensus_testing/test_types/step_types.py @@ -4,6 +4,12 @@ from pydantic import ConfigDict, Field, PrivateAttr, field_serializer, model_validator +from consensus_testing.test_types.block_spec import BlockSpec +from consensus_testing.test_types.gossip_aggregated_attestation_spec import ( + GossipAggregatedAttestationSpec, +) +from consensus_testing.test_types.gossip_attestation_spec import GossipAttestationSpec +from consensus_testing.test_types.store_checks import StoreChecks from lean_spec.base import CamelModel from lean_spec.spec.forks.lstar.containers import ( Block, @@ -11,11 +17,6 @@ SignedAttestation, ) -from .block_spec import BlockSpec -from .gossip_aggregated_attestation_spec import GossipAggregatedAttestationSpec -from .gossip_attestation_spec import GossipAttestationSpec -from .store_checks import StoreChecks - class BaseForkChoiceStep(CamelModel): """ diff --git a/packages/testing/src/consensus_testing/test_types/store_checks.py b/packages/testing/src/consensus_testing/test_types/store_checks.py index e146af5da..5ada612db 100644 --- a/packages/testing/src/consensus_testing/test_types/store_checks.py +++ b/packages/testing/src/consensus_testing/test_types/store_checks.py @@ -2,6 +2,7 @@ from typing import Literal +from consensus_testing.test_types.utils import resolve_block_root from lean_spec.base import CamelModel from lean_spec.spec.crypto.merkleization import hash_tree_root from lean_spec.spec.forks import Interval, Slot, ValidatorIndex @@ -9,8 +10,6 @@ from lean_spec.spec.forks.lstar.spec import LstarSpec from lean_spec.spec.ssz import ZERO_HASH, Bytes32 -from .utils import resolve_block_root - def _ancestor_set(blocks: dict[Bytes32, Block], head: Bytes32) -> set[Bytes32]: """Walk parent links from head and collect every reachable block root.""" diff --git a/pyproject.toml b/pyproject.toml index 0e2146123..2849575e7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,13 +64,16 @@ line-length = 100 docstring-code-format = true [tool.ruff.lint] -select = ["E", "F", "B", "W", "I", "A", "N", "D", "C"] -fixable = ["I", "B", "E", "F", "W", "D", "C"] +select = ["E", "F", "B", "W", "I", "A", "N", "D", "C", "TID"] +fixable = ["I", "B", "E", "F", "W", "D", "C", "TID"] ignore = ["D205", "D203", "D212", "D415", "C901", "A005", "C420"] [tool.ruff.lint.pydocstyle] convention = "google" +[tool.ruff.lint.flake8-tidy-imports] +ban-relative-imports = "all" + [tool.ruff.lint.isort] combine-as-imports = true force-single-line = false diff --git a/src/lean_spec/cli/__init__.py b/src/lean_spec/cli/__init__.py index 581302206..efb6b5c25 100644 --- a/src/lean_spec/cli/__init__.py +++ b/src/lean_spec/cli/__init__.py @@ -1,9 +1,9 @@ """Lean consensus node CLI package.""" -from .args import CliArgs, parse_args -from .bootstrap import CliValidationError, NodeBootstrap -from .main import main -from .run import run_node +from lean_spec.cli.args import CliArgs, parse_args +from lean_spec.cli.bootstrap import CliValidationError, NodeBootstrap +from lean_spec.cli.main import main +from lean_spec.cli.run import run_node __all__ = [ "CliArgs", diff --git a/src/lean_spec/cli/bootstrap.py b/src/lean_spec/cli/bootstrap.py index f3d93bbc9..11fb6d2d3 100644 --- a/src/lean_spec/cli/bootstrap.py +++ b/src/lean_spec/cli/bootstrap.py @@ -10,6 +10,7 @@ import logging from dataclasses import dataclass, field +from lean_spec.cli.args import CliArgs from lean_spec.node.anchor import Anchor from lean_spec.node.api import ApiServerConfig from lean_spec.node.genesis import GenesisConfig @@ -17,8 +18,6 @@ from lean_spec.node.validator import ValidatorRegistry from lean_spec.spec.forks import DEFAULT_REGISTRY, ForkProtocol, SubnetId -from .args import CliArgs - logger = logging.getLogger(__name__) diff --git a/src/lean_spec/cli/main.py b/src/lean_spec/cli/main.py index e927c6d6e..63989f205 100644 --- a/src/lean_spec/cli/main.py +++ b/src/lean_spec/cli/main.py @@ -7,12 +7,11 @@ import os import sys +from lean_spec.cli.args import parse_args +from lean_spec.cli.bootstrap import CliValidationError, NodeBootstrap +from lean_spec.cli.run import run_node from lean_spec.log import setup_logging -from .args import parse_args -from .bootstrap import CliValidationError, NodeBootstrap -from .run import run_node - logger = logging.getLogger(__name__) diff --git a/src/lean_spec/cli/run.py b/src/lean_spec/cli/run.py index 2b8fccd40..ddac5cf3e 100644 --- a/src/lean_spec/cli/run.py +++ b/src/lean_spec/cli/run.py @@ -17,6 +17,7 @@ import logging +from lean_spec.cli.bootstrap import NodeBootstrap from lean_spec.node.metrics import PrometheusObserver, registry as metrics from lean_spec.node.networking.client import LiveNetworkEventSource from lean_spec.node.networking.gossipsub import GossipTopic @@ -25,8 +26,6 @@ from lean_spec.spec.forks import SubnetId from lean_spec.spec.forks.lstar.config import ATTESTATION_COMMITTEE_COUNT -from .bootstrap import NodeBootstrap - logger = logging.getLogger(__name__) diff --git a/src/lean_spec/node/api/__init__.py b/src/lean_spec/node/api/__init__.py index 2e4c868e5..26db171d6 100644 --- a/src/lean_spec/node/api/__init__.py +++ b/src/lean_spec/node/api/__init__.py @@ -1,7 +1,7 @@ """API server module for various API endpoints.""" -from .aggregator_controller import AggregatorController -from .server import ApiServer, ApiServerConfig +from lean_spec.node.api.aggregator_controller import AggregatorController +from lean_spec.node.api.server import ApiServer, ApiServerConfig __all__ = [ "AggregatorController", diff --git a/src/lean_spec/node/api/routes.py b/src/lean_spec/node/api/routes.py index ffdc7f8f7..1f03bd3d9 100644 --- a/src/lean_spec/node/api/routes.py +++ b/src/lean_spec/node/api/routes.py @@ -6,7 +6,14 @@ from aiohttp import web -from .endpoints import aggregator, checkpoints, fork_choice, health, metrics, states +from lean_spec.node.api.endpoints import ( + aggregator, + checkpoints, + fork_choice, + health, + metrics, + states, +) Handler = Callable[[web.Request], Awaitable[web.Response]] """Type alias for aiohttp request handlers.""" diff --git a/src/lean_spec/node/api/server.py b/src/lean_spec/node/api/server.py index c549068ee..321408991 100644 --- a/src/lean_spec/node/api/server.py +++ b/src/lean_spec/node/api/server.py @@ -14,11 +14,10 @@ from aiohttp import web +from lean_spec.node.api.aggregator_controller import AggregatorController +from lean_spec.node.api.routes import ADMIN_ROUTES, ROUTES from lean_spec.spec.forks import LstarSpec, Store -from .aggregator_controller import AggregatorController -from .routes import ADMIN_ROUTES, ROUTES - logger = logging.getLogger(__name__) diff --git a/src/lean_spec/node/chain/__init__.py b/src/lean_spec/node/chain/__init__.py index 17059c101..45fe29119 100644 --- a/src/lean_spec/node/chain/__init__.py +++ b/src/lean_spec/node/chain/__init__.py @@ -1,6 +1,6 @@ """Specifications for chain and consensus parameters.""" -from .clock import SlotClock +from lean_spec.node.chain.clock import SlotClock __all__ = [ "SlotClock", diff --git a/src/lean_spec/node/chain/service.py b/src/lean_spec/node/chain/service.py index 5acc99081..0848eea16 100644 --- a/src/lean_spec/node/chain/service.py +++ b/src/lean_spec/node/chain/service.py @@ -26,12 +26,11 @@ import logging from dataclasses import dataclass, field +from lean_spec.node.chain.clock import SlotClock from lean_spec.node.sync import SyncService from lean_spec.spec.forks import Interval, LstarSpec, SignedAggregatedAttestation from lean_spec.spec.forks.lstar.config import INTERVALS_PER_SLOT -from .clock import SlotClock - logger = logging.getLogger(__name__) diff --git a/src/lean_spec/node/genesis/__init__.py b/src/lean_spec/node/genesis/__init__.py index 415aa84d6..9c381c401 100644 --- a/src/lean_spec/node/genesis/__init__.py +++ b/src/lean_spec/node/genesis/__init__.py @@ -1,5 +1,5 @@ """Genesis configuration and state initialization.""" -from .config import GenesisConfig +from lean_spec.node.genesis.config import GenesisConfig __all__ = ["GenesisConfig"] diff --git a/src/lean_spec/node/metrics/__init__.py b/src/lean_spec/node/metrics/__init__.py index ad318c664..b6e8ed978 100644 --- a/src/lean_spec/node/metrics/__init__.py +++ b/src/lean_spec/node/metrics/__init__.py @@ -5,8 +5,8 @@ https://github.com/leanEthereum/leanMetrics/blob/main/metrics.md """ -from .registry import get_metrics_output, registry -from .spec_observer import PrometheusObserver +from lean_spec.node.metrics.registry import get_metrics_output, registry +from lean_spec.node.metrics.spec_observer import PrometheusObserver __all__ = [ "PrometheusObserver", diff --git a/src/lean_spec/node/networking/__init__.py b/src/lean_spec/node/networking/__init__.py index 08fa3f3d8..31e36bb3a 100644 --- a/src/lean_spec/node/networking/__init__.py +++ b/src/lean_spec/node/networking/__init__.py @@ -1,7 +1,7 @@ """Exports the networking subspec components.""" -from .service import NetworkService -from .transport import PeerId +from lean_spec.node.networking.service import NetworkService +from lean_spec.node.networking.transport import PeerId __all__ = [ "NetworkService", diff --git a/src/lean_spec/node/networking/client/__init__.py b/src/lean_spec/node/networking/client/__init__.py index 1b3a0e787..373f54b7e 100644 --- a/src/lean_spec/node/networking/client/__init__.py +++ b/src/lean_spec/node/networking/client/__init__.py @@ -13,7 +13,7 @@ Bridges connection events to NetworkService events. """ -from .event_source import LiveNetworkEventSource +from lean_spec.node.networking.client.event_source import LiveNetworkEventSource __all__ = [ "LiveNetworkEventSource", diff --git a/src/lean_spec/node/networking/client/event_source/__init__.py b/src/lean_spec/node/networking/client/event_source/__init__.py index ff9e280d4..084b56b56 100644 --- a/src/lean_spec/node/networking/client/event_source/__init__.py +++ b/src/lean_spec/node/networking/client/event_source/__init__.py @@ -1,8 +1,12 @@ """Network event source bridging transport to sync service.""" -from .gossip import GossipHandler, read_gossip_message -from .live import LiveNetworkEventSource -from .protocol import SUPPORTED_PROTOCOLS, EventSource, GossipMessageError +from lean_spec.node.networking.client.event_source.gossip import GossipHandler, read_gossip_message +from lean_spec.node.networking.client.event_source.live import LiveNetworkEventSource +from lean_spec.node.networking.client.event_source.protocol import ( + SUPPORTED_PROTOCOLS, + EventSource, + GossipMessageError, +) __all__ = [ "SUPPORTED_PROTOCOLS", diff --git a/src/lean_spec/node/networking/client/event_source/gossip.py b/src/lean_spec/node/networking/client/event_source/gossip.py index ffc002c2b..a148163e8 100644 --- a/src/lean_spec/node/networking/client/event_source/gossip.py +++ b/src/lean_spec/node/networking/client/event_source/gossip.py @@ -38,6 +38,7 @@ from dataclasses import dataclass +from lean_spec.node.networking.client.event_source.protocol import GossipMessageError from lean_spec.node.networking.gossipsub.topic import ( ForkMismatchError, GossipTopic, @@ -49,8 +50,6 @@ from lean_spec.spec.forks import SignedAggregatedAttestation, SignedAttestation, SignedBlock from lean_spec.spec.ssz.exceptions import SSZSerializationError -from .protocol import GossipMessageError - @dataclass(slots=True) class GossipHandler: diff --git a/src/lean_spec/node/networking/client/event_source/live.py b/src/lean_spec/node/networking/client/event_source/live.py index 0824adc65..ec75c02c9 100644 --- a/src/lean_spec/node/networking/client/event_source/live.py +++ b/src/lean_spec/node/networking/client/event_source/live.py @@ -61,6 +61,12 @@ from collections.abc import Sequence from dataclasses import dataclass, field +from lean_spec.node.networking.client.event_source.gossip import GossipHandler +from lean_spec.node.networking.client.event_source.protocol import ( + SUPPORTED_PROTOCOLS, + GossipMessageError, +) +from lean_spec.node.networking.client.reqresp_client import ReqRespClient from lean_spec.node.networking.config import ( GOSSIPSUB_DEFAULT_PROTOCOL_ID, GOSSIPSUB_PROTOCOL_ID_V12, @@ -107,10 +113,6 @@ from lean_spec.spec.forks import SignedAggregatedAttestation, SignedAttestation, SignedBlock from lean_spec.spec.ssz.exceptions import SSZSerializationError -from ..reqresp_client import ReqRespClient -from .gossip import GossipHandler -from .protocol import SUPPORTED_PROTOCOLS, GossipMessageError - logger = logging.getLogger(__name__) diff --git a/src/lean_spec/node/networking/config.py b/src/lean_spec/node/networking/config.py index 884e6d5c7..6d181a3e7 100644 --- a/src/lean_spec/node/networking/config.py +++ b/src/lean_spec/node/networking/config.py @@ -4,7 +4,7 @@ from typing import Final -from .types import DomainType, ProtocolId +from lean_spec.node.networking.types import DomainType, ProtocolId MAX_REQUEST_BLOCKS: Final[int] = 2**10 """Maximum number of blocks in a single request (1024).""" diff --git a/src/lean_spec/node/networking/enr/__init__.py b/src/lean_spec/node/networking/enr/__init__.py index 6ec79a3eb..27d0887b7 100644 --- a/src/lean_spec/node/networking/enr/__init__.py +++ b/src/lean_spec/node/networking/enr/__init__.py @@ -5,10 +5,10 @@ - EIP-778: https://eips.ethereum.org/EIPS/eip-778 """ -from . import keys -from .enr import ENR -from .eth2 import FAR_FUTURE_EPOCH, AttestationSubnets, Eth2Data -from .keys import EnrKey +from lean_spec.node.networking.enr import keys +from lean_spec.node.networking.enr.enr import ENR +from lean_spec.node.networking.enr.eth2 import FAR_FUTURE_EPOCH, AttestationSubnets, Eth2Data +from lean_spec.node.networking.enr.keys import EnrKey __all__ = [ "ENR", diff --git a/src/lean_spec/node/networking/enr/enr.py b/src/lean_spec/node/networking/enr/enr.py index e3ae5818d..937eb7e6c 100644 --- a/src/lean_spec/node/networking/enr/enr.py +++ b/src/lean_spec/node/networking/enr/enr.py @@ -51,6 +51,10 @@ ) from lean_spec.base import StrictBaseModel +from lean_spec.node.networking.enr import keys +from lean_spec.node.networking.enr.eth2 import AttestationSubnets, Eth2Data +from lean_spec.node.networking.enr.keys import EnrKey +from lean_spec.node.networking.enr.rlp import RLPDecodingError, RLPItem, decode_rlp_list, encode_rlp from lean_spec.node.networking.types import ( ForkDigest, Multiaddr, @@ -61,11 +65,6 @@ ) from lean_spec.spec.ssz import Bytes33, Bytes64, Uint64 -from . import keys -from .eth2 import AttestationSubnets, Eth2Data -from .keys import EnrKey -from .rlp import RLPDecodingError, RLPItem, decode_rlp_list, encode_rlp - ENR_PREFIX: Final = "enr:" """Text prefix for ENR strings.""" diff --git a/src/lean_spec/node/networking/gossipsub/__init__.py b/src/lean_spec/node/networking/gossipsub/__init__.py index 2aacca32e..162210b19 100644 --- a/src/lean_spec/node/networking/gossipsub/__init__.py +++ b/src/lean_spec/node/networking/gossipsub/__init__.py @@ -19,10 +19,10 @@ - Ethereum P2P: https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/p2p-interface.md """ -from .behavior import GossipsubBehavior -from .message import GossipsubMessage -from .parameters import GossipsubParameters -from .topic import ( +from lean_spec.node.networking.gossipsub.behavior import GossipsubBehavior +from lean_spec.node.networking.gossipsub.message import GossipsubMessage +from lean_spec.node.networking.gossipsub.parameters import GossipsubParameters +from lean_spec.node.networking.gossipsub.topic import ( ForkMismatchError, GossipTopic, TopicKind, diff --git a/src/lean_spec/node/networking/gossipsub/mcache.py b/src/lean_spec/node/networking/gossipsub/mcache.py index 23a224d99..fef8c4fde 100644 --- a/src/lean_spec/node/networking/gossipsub/mcache.py +++ b/src/lean_spec/node/networking/gossipsub/mcache.py @@ -66,8 +66,8 @@ from dataclasses import dataclass, field from itertools import islice -from .message import GossipsubMessage -from .types import MessageId, Timestamp, TopicId +from lean_spec.node.networking.gossipsub.message import GossipsubMessage +from lean_spec.node.networking.gossipsub.types import MessageId, Timestamp, TopicId @dataclass(slots=True) diff --git a/src/lean_spec/node/networking/gossipsub/mesh.py b/src/lean_spec/node/networking/gossipsub/mesh.py index d9d17b06c..88e0a0d31 100644 --- a/src/lean_spec/node/networking/gossipsub/mesh.py +++ b/src/lean_spec/node/networking/gossipsub/mesh.py @@ -46,9 +46,9 @@ import time from dataclasses import dataclass, field -from ..transport import PeerId -from .parameters import GossipsubParameters -from .types import TopicId +from lean_spec.node.networking.gossipsub.parameters import GossipsubParameters +from lean_spec.node.networking.gossipsub.types import TopicId +from lean_spec.node.networking.transport import PeerId @dataclass(slots=True) diff --git a/src/lean_spec/node/networking/gossipsub/message.py b/src/lean_spec/node/networking/gossipsub/message.py index 800ca6be5..303effd61 100644 --- a/src/lean_spec/node/networking/gossipsub/message.py +++ b/src/lean_spec/node/networking/gossipsub/message.py @@ -58,8 +58,7 @@ from dataclasses import dataclass, field from lean_spec.node.networking.config import MESSAGE_DOMAIN_INVALID_SNAPPY - -from .types import MessageId +from lean_spec.node.networking.gossipsub.types import MessageId @dataclass(slots=True) diff --git a/src/lean_spec/node/networking/peer.py b/src/lean_spec/node/networking/peer.py index a7bf2b44f..8d9359d58 100644 --- a/src/lean_spec/node/networking/peer.py +++ b/src/lean_spec/node/networking/peer.py @@ -4,10 +4,10 @@ from dataclasses import dataclass -from .enr import ENR -from .reqresp import Status -from .transport import PeerId -from .types import ConnectionState, Direction, Multiaddr +from lean_spec.node.networking.enr import ENR +from lean_spec.node.networking.reqresp import Status +from lean_spec.node.networking.transport import PeerId +from lean_spec.node.networking.types import ConnectionState, Direction, Multiaddr @dataclass(slots=True) diff --git a/src/lean_spec/node/networking/reqresp/__init__.py b/src/lean_spec/node/networking/reqresp/__init__.py index ede4aa261..99f7b680e 100644 --- a/src/lean_spec/node/networking/reqresp/__init__.py +++ b/src/lean_spec/node/networking/reqresp/__init__.py @@ -1,12 +1,12 @@ """ReqResp specs for the Lean Ethereum consensus specification.""" -from .codec import ( +from lean_spec.node.networking.reqresp.codec import ( CodecError, ResponseCode, decode_request, encode_request, ) -from .handler import ( +from lean_spec.node.networking.reqresp.handler import ( REQRESP_PROTOCOL_IDS, AsyncBlockBySlotLookup, AsyncBlockLookup, @@ -14,7 +14,7 @@ RequestHandler, StreamResponseAdapter, ) -from .message import ( +from lean_spec.node.networking.reqresp.message import ( BLOCKS_BY_RANGE_PROTOCOL_V1, BLOCKS_BY_ROOT_PROTOCOL_V1, STATUS_PROTOCOL_V1, diff --git a/src/lean_spec/node/networking/reqresp/codec.py b/src/lean_spec/node/networking/reqresp/codec.py index 5984b9b36..24396a5b8 100644 --- a/src/lean_spec/node/networking/reqresp/codec.py +++ b/src/lean_spec/node/networking/reqresp/codec.py @@ -75,11 +75,10 @@ from enum import IntEnum +from lean_spec.node.networking.config import MAX_PAYLOAD_SIZE +from lean_spec.node.networking.varint import VarintError, decode_varint, encode_varint from lean_spec.node.snappy import SnappyDecompressionError, frame_compress, frame_decompress -from ..config import MAX_PAYLOAD_SIZE -from ..varint import VarintError, decode_varint, encode_varint - class CodecError(Exception): """Raised when encoding or decoding fails. diff --git a/src/lean_spec/node/networking/reqresp/handler.py b/src/lean_spec/node/networking/reqresp/handler.py index 6a1fe1522..142317243 100644 --- a/src/lean_spec/node/networking/reqresp/handler.py +++ b/src/lean_spec/node/networking/reqresp/handler.py @@ -69,15 +69,8 @@ MAX_REQUEST_BLOCKS, MIN_SLOTS_FOR_BLOCK_REQUESTS, ) -from lean_spec.node.networking.transport.protocols import InboundStreamProtocol -from lean_spec.node.networking.types import ProtocolId -from lean_spec.node.networking.varint import VarintError, decode_varint -from lean_spec.node.snappy import SnappyDecompressionError, frame_decompress -from lean_spec.spec.forks import SignedBlock, Slot -from lean_spec.spec.ssz import Bytes32, Uint64 - -from .codec import ResponseCode -from .message import ( +from lean_spec.node.networking.reqresp.codec import ResponseCode +from lean_spec.node.networking.reqresp.message import ( BLOCKS_BY_RANGE_PROTOCOL_V1, BLOCKS_BY_ROOT_PROTOCOL_V1, STATUS_PROTOCOL_V1, @@ -85,6 +78,12 @@ BlocksByRootRequest, Status, ) +from lean_spec.node.networking.transport.protocols import InboundStreamProtocol +from lean_spec.node.networking.types import ProtocolId +from lean_spec.node.networking.varint import VarintError, decode_varint +from lean_spec.node.snappy import SnappyDecompressionError, frame_decompress +from lean_spec.spec.forks import SignedBlock, Slot +from lean_spec.spec.ssz import Bytes32, Uint64 logger = logging.getLogger(__name__) diff --git a/src/lean_spec/node/networking/reqresp/message.py b/src/lean_spec/node/networking/reqresp/message.py index 6cd783862..1a0cc702e 100644 --- a/src/lean_spec/node/networking/reqresp/message.py +++ b/src/lean_spec/node/networking/reqresp/message.py @@ -7,13 +7,12 @@ from typing import ClassVar, Final +from lean_spec.node.networking.config import MAX_REQUEST_BLOCKS +from lean_spec.node.networking.types import ProtocolId from lean_spec.spec.forks import Checkpoint, Slot from lean_spec.spec.ssz import Bytes32, SSZList, Uint64 from lean_spec.spec.ssz.container import Container -from ..config import MAX_REQUEST_BLOCKS -from ..types import ProtocolId - STATUS_PROTOCOL_V1: Final = ProtocolId("/leanconsensus/req/status/1/ssz_snappy") """The protocol ID for the Status v1 request/response message.""" diff --git a/src/lean_spec/node/networking/service/__init__.py b/src/lean_spec/node/networking/service/__init__.py index d04c01948..7bdcb565f 100644 --- a/src/lean_spec/node/networking/service/__init__.py +++ b/src/lean_spec/node/networking/service/__init__.py @@ -4,7 +4,7 @@ This module provides the event routing layer between libp2p and consensus. """ -from .events import ( +from lean_spec.node.networking.service.events import ( GossipAttestationEvent, GossipBlockEvent, NetworkEvent, @@ -12,7 +12,7 @@ PeerDisconnectedEvent, PeerStatusEvent, ) -from .service import NetworkService +from lean_spec.node.networking.service.service import NetworkService __all__ = [ # Service diff --git a/src/lean_spec/node/networking/service/service.py b/src/lean_spec/node/networking/service/service.py index 7cf553ac0..63bb52990 100644 --- a/src/lean_spec/node/networking/service/service.py +++ b/src/lean_spec/node/networking/service/service.py @@ -28,6 +28,15 @@ from lean_spec.node.networking.client.event_source import EventSource from lean_spec.node.networking.gossipsub.topic import GossipTopic from lean_spec.node.networking.peer import PeerInfo +from lean_spec.node.networking.service.events import ( + GossipAggregatedAttestationEvent, + GossipAttestationEvent, + GossipBlockEvent, + NetworkEvent, + PeerConnectedEvent, + PeerDisconnectedEvent, + PeerStatusEvent, +) from lean_spec.node.networking.types import ConnectionState from lean_spec.node.snappy import compress from lean_spec.node.sync import SyncService @@ -38,16 +47,6 @@ SubnetId, ) -from .events import ( - GossipAggregatedAttestationEvent, - GossipAttestationEvent, - GossipBlockEvent, - NetworkEvent, - PeerConnectedEvent, - PeerDisconnectedEvent, - PeerStatusEvent, -) - logger = logging.getLogger(__name__) diff --git a/src/lean_spec/node/networking/transport/__init__.py b/src/lean_spec/node/networking/transport/__init__.py index 4533713b0..93af14411 100644 --- a/src/lean_spec/node/networking/transport/__init__.py +++ b/src/lean_spec/node/networking/transport/__init__.py @@ -22,15 +22,22 @@ - libp2p/specs quic, tls, multistream-select """ -from .identity import IdentityKeypair, Secp256k1PublicKey -from .peer_id import Base58, KeyType, Multihash, MultihashCode, PeerId, PublicKeyProtobuf -from .quic import ( +from lean_spec.node.networking.transport.identity import IdentityKeypair, Secp256k1PublicKey +from lean_spec.node.networking.transport.peer_id import ( + Base58, + KeyType, + Multihash, + MultihashCode, + PeerId, + PublicKeyProtobuf, +) +from lean_spec.node.networking.transport.quic import ( NegotiationError, QuicConnection, QuicConnectionManager, generate_libp2p_certificate, ) -from .quic.stream_adapter import QuicStreamAdapter +from lean_spec.node.networking.transport.quic.stream_adapter import QuicStreamAdapter __all__ = [ # QUIC transport diff --git a/src/lean_spec/node/networking/transport/identity/__init__.py b/src/lean_spec/node/networking/transport/identity/__init__.py index 14ff77b22..b6f2db163 100644 --- a/src/lean_spec/node/networking/transport/identity/__init__.py +++ b/src/lean_spec/node/networking/transport/identity/__init__.py @@ -4,7 +4,7 @@ Provides secp256k1 keypair management for peer identity (PeerId derivation). """ -from .keypair import IdentityKeypair, Secp256k1PublicKey +from lean_spec.node.networking.transport.identity.keypair import IdentityKeypair, Secp256k1PublicKey __all__ = [ "IdentityKeypair", diff --git a/src/lean_spec/node/networking/transport/identity/keypair.py b/src/lean_spec/node/networking/transport/identity/keypair.py index fe748bd56..f6861cc92 100644 --- a/src/lean_spec/node/networking/transport/identity/keypair.py +++ b/src/lean_spec/node/networking/transport/identity/keypair.py @@ -16,10 +16,9 @@ from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import ec +from lean_spec.node.networking.transport.peer_id import KeyType, PeerId, PublicKeyProtobuf from lean_spec.spec.ssz import Bytes33 -from ..peer_id import KeyType, PeerId, PublicKeyProtobuf - __all__ = [ "IdentityKeypair", "Secp256k1PublicKey", diff --git a/src/lean_spec/node/networking/transport/quic/__init__.py b/src/lean_spec/node/networking/transport/quic/__init__.py index abae882f0..80f980600 100644 --- a/src/lean_spec/node/networking/transport/quic/__init__.py +++ b/src/lean_spec/node/networking/transport/quic/__init__.py @@ -12,18 +12,18 @@ - libp2p TLS spec: https://github.com/libp2p/specs/blob/master/tls/tls.md """ -from .connection import ( +from lean_spec.node.networking.transport.quic.connection import ( QuicConnection, QuicConnectionManager, QuicStream, is_quic_multiaddr, ) -from .stream import ( - QuicStreamResetError, - QuicTransportError, +from lean_spec.node.networking.transport.quic.stream import QuicStreamResetError, QuicTransportError +from lean_spec.node.networking.transport.quic.stream_adapter import ( + NegotiationError, + QuicStreamAdapter, ) -from .stream_adapter import NegotiationError, QuicStreamAdapter -from .tls import generate_libp2p_certificate +from lean_spec.node.networking.transport.quic.tls import generate_libp2p_certificate __all__ = [ "NegotiationError", diff --git a/src/lean_spec/node/networking/transport/quic/connection.py b/src/lean_spec/node/networking/transport/quic/connection.py index 9083cc800..92c6d02b8 100644 --- a/src/lean_spec/node/networking/transport/quic/connection.py +++ b/src/lean_spec/node/networking/transport/quic/connection.py @@ -40,14 +40,13 @@ ) from lean_spec.node.networking.config import LIBP2P_ALPN_PROTOCOL +from lean_spec.node.networking.transport.identity import IdentityKeypair +from lean_spec.node.networking.transport.peer_id import PeerId +from lean_spec.node.networking.transport.quic.stream import QuicStream, QuicTransportError +from lean_spec.node.networking.transport.quic.stream_adapter import QuicStreamAdapter +from lean_spec.node.networking.transport.quic.tls import generate_libp2p_certificate from lean_spec.node.networking.types import ProtocolId -from ..identity import IdentityKeypair -from ..peer_id import PeerId -from .stream import QuicStream, QuicTransportError -from .stream_adapter import QuicStreamAdapter -from .tls import generate_libp2p_certificate - logger = logging.getLogger(__name__) diff --git a/src/lean_spec/node/networking/transport/quic/stream_adapter.py b/src/lean_spec/node/networking/transport/quic/stream_adapter.py index 78294474e..d54e46269 100644 --- a/src/lean_spec/node/networking/transport/quic/stream_adapter.py +++ b/src/lean_spec/node/networking/transport/quic/stream_adapter.py @@ -31,11 +31,10 @@ import asyncio from typing import Final +from lean_spec.node.networking.transport.quic.stream import QuicStream from lean_spec.node.networking.types import ProtocolId from lean_spec.node.networking.varint import decode_varint, encode_varint -from .stream import QuicStream - MULTISTREAM_PROTOCOL_ID: Final[str] = "/multistream/1.0.0" """Protocol identifier for multistream-select 1.0.""" diff --git a/src/lean_spec/node/networking/transport/quic/tls.py b/src/lean_spec/node/networking/transport/quic/tls.py index c71240646..08fc09631 100644 --- a/src/lean_spec/node/networking/transport/quic/tls.py +++ b/src/lean_spec/node/networking/transport/quic/tls.py @@ -30,8 +30,8 @@ from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import ec -from ..identity import IdentityKeypair -from ..peer_id import KeyType +from lean_spec.node.networking.transport.identity import IdentityKeypair +from lean_spec.node.networking.transport.peer_id import KeyType LIBP2P_EXTENSION_OID: Final = x509.ObjectIdentifier("1.3.6.1.4.1.53594.1.1") """libp2p TLS extension OID (Protocol Labs assigned).""" diff --git a/src/lean_spec/node/observability/__init__.py b/src/lean_spec/node/observability/__init__.py index fb0eff7cf..e2672b34f 100644 --- a/src/lean_spec/node/observability/__init__.py +++ b/src/lean_spec/node/observability/__init__.py @@ -11,7 +11,7 @@ their own. """ -from .observer import ( +from lean_spec.node.observability.observer import ( SpecObserver, observe_on_attestation, observe_on_block, diff --git a/src/lean_spec/node/snappy/__init__.py b/src/lean_spec/node/snappy/__init__.py index 1e1ef3556..9e085c980 100644 --- a/src/lean_spec/node/snappy/__init__.py +++ b/src/lean_spec/node/snappy/__init__.py @@ -10,12 +10,9 @@ from __future__ import annotations -from .compress import compress, max_compressed_length -from .decompress import ( - SnappyDecompressionError, - decompress, -) -from .framing import frame_compress, frame_decompress +from lean_spec.node.snappy.compress import compress, max_compressed_length +from lean_spec.node.snappy.decompress import SnappyDecompressionError, decompress +from lean_spec.node.snappy.framing import frame_compress, frame_decompress __all__ = [ # Core API (raw block format) diff --git a/src/lean_spec/node/snappy/compress.py b/src/lean_spec/node/snappy/compress.py index ba7f3357f..7f1db09e9 100644 --- a/src/lean_spec/node/snappy/compress.py +++ b/src/lean_spec/node/snappy/compress.py @@ -64,8 +64,7 @@ from __future__ import annotations from lean_spec.node.networking.varint import encode_varint - -from .constants import ( +from lean_spec.node.snappy.constants import ( BLOCK_SIZE, HASH_MULTIPLIER, INPUT_MARGIN_BYTES, @@ -73,7 +72,7 @@ MIN_HASH_TABLE_BITS, SNAPPY_VARINT_MAX_BYTES, ) -from .encoding import encode_copy_tag, encode_literal_tag +from lean_spec.node.snappy.encoding import encode_copy_tag, encode_literal_tag def compress(data: bytes) -> bytes: diff --git a/src/lean_spec/node/snappy/decompress.py b/src/lean_spec/node/snappy/decompress.py index 4442e62b5..8c6c562c0 100644 --- a/src/lean_spec/node/snappy/decompress.py +++ b/src/lean_spec/node/snappy/decompress.py @@ -72,9 +72,8 @@ from __future__ import annotations from lean_spec.node.networking.varint import VarintError, decode_varint - -from .constants import SNAPPY_VARINT_MAX_BYTES -from .encoding import decode_tag +from lean_spec.node.snappy.constants import SNAPPY_VARINT_MAX_BYTES +from lean_spec.node.snappy.encoding import decode_tag class SnappyDecompressionError(Exception): diff --git a/src/lean_spec/node/snappy/encoding.py b/src/lean_spec/node/snappy/encoding.py index 6e222dccc..26b331766 100644 --- a/src/lean_spec/node/snappy/encoding.py +++ b/src/lean_spec/node/snappy/encoding.py @@ -18,7 +18,7 @@ from typing import Literal -from .constants import ( +from lean_spec.node.snappy.constants import ( COPY_1_BYTE_OFFSET, COPY_2_BYTE_OFFSET, COPY_4_BYTE_OFFSET, diff --git a/src/lean_spec/node/snappy/framing.py b/src/lean_spec/node/snappy/framing.py index b0592bb5a..4c06e87e6 100644 --- a/src/lean_spec/node/snappy/framing.py +++ b/src/lean_spec/node/snappy/framing.py @@ -89,8 +89,8 @@ from typing import Final -from .compress import compress as raw_compress -from .decompress import SnappyDecompressionError, decompress as raw_decompress +from lean_spec.node.snappy.compress import compress as raw_compress +from lean_spec.node.snappy.decompress import SnappyDecompressionError, decompress as raw_decompress STREAM_IDENTIFIER: Final = b"\xff\x06\x00\x00sNaPpY" """Stream identifier marking the start of a Snappy framed stream. diff --git a/src/lean_spec/node/storage/__init__.py b/src/lean_spec/node/storage/__init__.py index f9293477a..bf6d92c01 100644 --- a/src/lean_spec/node/storage/__init__.py +++ b/src/lean_spec/node/storage/__init__.py @@ -5,9 +5,13 @@ Uses SQLite for simplicity and correctness. """ -from .database import Database -from .exceptions import StorageCorruptionError, StorageReadError, StorageWriteError -from .sqlite import SQLiteDatabase +from lean_spec.node.storage.database import Database +from lean_spec.node.storage.exceptions import ( + StorageCorruptionError, + StorageReadError, + StorageWriteError, +) +from lean_spec.node.storage.sqlite import SQLiteDatabase __all__ = [ "Database", diff --git a/src/lean_spec/node/storage/sqlite.py b/src/lean_spec/node/storage/sqlite.py index 49eb12b7e..cd0efc55a 100644 --- a/src/lean_spec/node/storage/sqlite.py +++ b/src/lean_spec/node/storage/sqlite.py @@ -23,15 +23,12 @@ from contextlib import contextmanager from pathlib import Path -from lean_spec.spec.forks import Checkpoint, Slot -from lean_spec.spec.forks.protocol import ( - SpecBlockType, - SpecStateType, +from lean_spec.node.storage.exceptions import ( + StorageCorruptionError, + StorageReadError, + StorageWriteError, ) -from lean_spec.spec.ssz import Bytes32, Uint64 - -from .exceptions import StorageCorruptionError, StorageReadError, StorageWriteError -from .namespaces import ( +from lean_spec.node.storage.namespaces import ( BLOCKS_CREATE_INDEX, BLOCKS_CREATE_TABLE, BLOCKS_TABLE_NAME, @@ -49,6 +46,12 @@ STATES_CREATE_TABLE, STATES_TABLE_NAME, ) +from lean_spec.spec.forks import Checkpoint, Slot +from lean_spec.spec.forks.protocol import ( + SpecBlockType, + SpecStateType, +) +from lean_spec.spec.ssz import Bytes32, Uint64 class SQLiteDatabase: diff --git a/src/lean_spec/node/sync/__init__.py b/src/lean_spec/node/sync/__init__.py index 1a7eb69c0..6449c10ce 100644 --- a/src/lean_spec/node/sync/__init__.py +++ b/src/lean_spec/node/sync/__init__.py @@ -32,7 +32,7 @@ "PeerManager", ] -from .backfill_sync import NetworkRequester -from .block_cache import BlockCache -from .peer_manager import PeerManager -from .service import SyncService +from lean_spec.node.sync.backfill_sync import NetworkRequester +from lean_spec.node.sync.block_cache import BlockCache +from lean_spec.node.sync.peer_manager import PeerManager +from lean_spec.node.sync.service import SyncService diff --git a/src/lean_spec/node/sync/backfill_sync.py b/src/lean_spec/node/sync/backfill_sync.py index 021b9d0b1..6bbe2860b 100644 --- a/src/lean_spec/node/sync/backfill_sync.py +++ b/src/lean_spec/node/sync/backfill_sync.py @@ -44,13 +44,12 @@ from lean_spec.node.networking.config import MAX_REQUEST_BLOCKS from lean_spec.node.networking.transport.peer_id import PeerId +from lean_spec.node.sync.block_cache import BlockCache +from lean_spec.node.sync.config import MAX_BACKFILL_DEPTH, MAX_BLOCKS_PER_REQUEST +from lean_spec.node.sync.peer_manager import PeerManager from lean_spec.spec.forks import SignedBlock, Slot from lean_spec.spec.ssz import Bytes32, Uint64 -from .block_cache import BlockCache -from .config import MAX_BACKFILL_DEPTH, MAX_BLOCKS_PER_REQUEST -from .peer_manager import PeerManager - logger = logging.getLogger(__name__) diff --git a/src/lean_spec/node/sync/block_cache.py b/src/lean_spec/node/sync/block_cache.py index 57b27e557..6b29c44f4 100644 --- a/src/lean_spec/node/sync/block_cache.py +++ b/src/lean_spec/node/sync/block_cache.py @@ -43,12 +43,11 @@ from dataclasses import dataclass, field from lean_spec.node.networking.transport.peer_id import PeerId +from lean_spec.node.sync.config import MAX_CACHED_BLOCKS from lean_spec.spec.crypto.merkleization import hash_tree_root from lean_spec.spec.forks import SignedBlock, Slot, Store from lean_spec.spec.ssz import Bytes32 -from .config import MAX_CACHED_BLOCKS - @dataclass(slots=True) class PendingBlock: diff --git a/src/lean_spec/node/sync/head_sync.py b/src/lean_spec/node/sync/head_sync.py index a4cb17f37..aaae8ef8d 100644 --- a/src/lean_spec/node/sync/head_sync.py +++ b/src/lean_spec/node/sync/head_sync.py @@ -49,13 +49,12 @@ from dataclasses import dataclass, field from lean_spec.node.networking.transport.peer_id import PeerId +from lean_spec.node.sync.backfill_sync import BackfillSync +from lean_spec.node.sync.block_cache import BlockCache from lean_spec.spec.crypto.merkleization import hash_tree_root from lean_spec.spec.forks import SignedBlock, Slot, Store from lean_spec.spec.ssz import Bytes32, Uint64 -from .backfill_sync import BackfillSync -from .block_cache import BlockCache - logger = logging.getLogger(__name__) diff --git a/src/lean_spec/node/sync/peer_manager.py b/src/lean_spec/node/sync/peer_manager.py index 7345d4874..6db1fe036 100644 --- a/src/lean_spec/node/sync/peer_manager.py +++ b/src/lean_spec/node/sync/peer_manager.py @@ -14,10 +14,9 @@ from lean_spec.node.networking.peer import PeerInfo from lean_spec.node.networking.reqresp.message import Status from lean_spec.node.networking.transport.peer_id import PeerId +from lean_spec.node.sync.config import MAX_CONCURRENT_REQUESTS from lean_spec.spec.forks import Slot -from .config import MAX_CONCURRENT_REQUESTS - INITIAL_PEER_SCORE: Final = 100 """Starting score for newly added peers.""" diff --git a/src/lean_spec/node/sync/service.py b/src/lean_spec/node/sync/service.py index 9d73436d0..b76eb9533 100644 --- a/src/lean_spec/node/sync/service.py +++ b/src/lean_spec/node/sync/service.py @@ -16,6 +16,12 @@ from lean_spec.node.networking.reqresp.message import Status from lean_spec.node.networking.transport.peer_id import PeerId from lean_spec.node.storage import Database +from lean_spec.node.sync.backfill_sync import BackfillSync, NetworkRequester +from lean_spec.node.sync.block_cache import BlockCache +from lean_spec.node.sync.config import MAX_PENDING_ATTESTATIONS +from lean_spec.node.sync.head_sync import HeadSync +from lean_spec.node.sync.peer_manager import PeerManager +from lean_spec.node.sync.states import SyncState from lean_spec.spec.crypto.merkleization import hash_tree_root from lean_spec.spec.crypto.xmss.containers import PublicKey from lean_spec.spec.forks import ( @@ -34,13 +40,6 @@ ) from lean_spec.spec.ssz import Bytes32 -from .backfill_sync import BackfillSync, NetworkRequester -from .block_cache import BlockCache -from .config import MAX_PENDING_ATTESTATIONS -from .head_sync import HeadSync -from .peer_manager import PeerManager -from .states import SyncState - logger = logging.getLogger(__name__) diff --git a/src/lean_spec/node/validator/__init__.py b/src/lean_spec/node/validator/__init__.py index a4cf7e6a9..76979791c 100644 --- a/src/lean_spec/node/validator/__init__.py +++ b/src/lean_spec/node/validator/__init__.py @@ -15,8 +15,8 @@ 4. At interval 1, produce attestations for non-proposers """ -from .registry import ValidatorRegistry -from .service import ValidatorService +from lean_spec.node.validator.registry import ValidatorRegistry +from lean_spec.node.validator.service import ValidatorService __all__ = [ "ValidatorService", diff --git a/src/lean_spec/node/validator/service.py b/src/lean_spec/node/validator/service.py index f7bb95801..8aa2551c3 100644 --- a/src/lean_spec/node/validator/service.py +++ b/src/lean_spec/node/validator/service.py @@ -39,6 +39,12 @@ from lean_spec.node.chain.clock import SlotClock from lean_spec.node.sync import SyncService +from lean_spec.node.validator.constants import ( + HYSTERESIS_BAND, + NETWORK_STALL_THRESHOLD, + SYNC_LAG_THRESHOLD, +) +from lean_spec.node.validator.registry import ValidatorEntry, ValidatorRegistry from lean_spec.spec.crypto.merkleization import hash_tree_root from lean_spec.spec.crypto.xmss import TARGET_SIGNATURE_SCHEME from lean_spec.spec.crypto.xmss.containers import PublicKey, Signature @@ -55,9 +61,6 @@ from lean_spec.spec.forks.lstar.containers import MultiMessageAggregate, SingleMessageAggregate from lean_spec.spec.ssz import Bytes32, Uint64 -from .constants import HYSTERESIS_BAND, NETWORK_STALL_THRESHOLD, SYNC_LAG_THRESHOLD -from .registry import ValidatorEntry, ValidatorRegistry - logger = logging.getLogger(__name__) type BlockPublisher = Callable[[SignedBlock], Awaitable[None]] diff --git a/src/lean_spec/spec/crypto/poseidon.py b/src/lean_spec/spec/crypto/poseidon.py index 5b322196c..9faa584f2 100644 --- a/src/lean_spec/spec/crypto/poseidon.py +++ b/src/lean_spec/spec/crypto/poseidon.py @@ -15,8 +15,8 @@ from numpy.typing import NDArray from pydantic import Field, model_validator -from ...base import StrictBaseModel -from .koalabear import Fp, P +from lean_spec.base import StrictBaseModel +from lean_spec.spec.crypto.koalabear import Fp, P # For width 16: 28 rounds x 16 = 448 constants # Layout: initial_full (4 x 16) + partial (20 x 16) + terminal_full (4 x 16) diff --git a/src/lean_spec/spec/crypto/xmss/__init__.py b/src/lean_spec/spec/crypto/xmss/__init__.py index f1a027f7e..74f8507c5 100644 --- a/src/lean_spec/spec/crypto/xmss/__init__.py +++ b/src/lean_spec/spec/crypto/xmss/__init__.py @@ -10,9 +10,8 @@ from lean_multisig_py import setup_prover from lean_spec.config import LEAN_ENV - -from .containers import PublicKey, SecretKey -from .interface import TARGET_SIGNATURE_SCHEME, GeneralizedXmssScheme +from lean_spec.spec.crypto.xmss.containers import PublicKey, SecretKey +from lean_spec.spec.crypto.xmss.interface import TARGET_SIGNATURE_SCHEME, GeneralizedXmssScheme # Side effect: configures the Rust prover for the lifetime of the process. # One call covers every aggregation, verification, split, and merge. diff --git a/src/lean_spec/spec/crypto/xmss/constants.py b/src/lean_spec/spec/crypto/xmss/constants.py index 1632aea19..f662d9906 100644 --- a/src/lean_spec/spec/crypto/xmss/constants.py +++ b/src/lean_spec/spec/crypto/xmss/constants.py @@ -7,11 +7,10 @@ from lean_spec.base import StrictBaseModel from lean_spec.config import LEAN_ENV +from lean_spec.spec.crypto.koalabear import P_BYTES, P from lean_spec.spec.ssz import Uint64 from lean_spec.spec.ssz.ssz_base import BYTES_PER_LENGTH_OFFSET -from ..koalabear import P_BYTES, P - class XmssConfig(StrictBaseModel): """A model holding the configuration constants for an XMSS preset.""" diff --git a/src/lean_spec/spec/crypto/xmss/containers.py b/src/lean_spec/spec/crypto/xmss/containers.py index 539714325..671854e81 100644 --- a/src/lean_spec/spec/crypto/xmss/containers.py +++ b/src/lean_spec/spec/crypto/xmss/containers.py @@ -5,20 +5,19 @@ from pydantic import field_serializer, model_serializer from lean_spec.base import StrictBaseModel -from lean_spec.spec.forks.lstar.slot import Slot -from lean_spec.spec.ssz import Uint64 -from lean_spec.spec.ssz.container import Container - -from .constants import TARGET_CONFIG -from .merkle import HashSubTree -from .prf import PRFKey -from .types import ( +from lean_spec.spec.crypto.xmss.constants import TARGET_CONFIG +from lean_spec.spec.crypto.xmss.merkle import HashSubTree +from lean_spec.spec.crypto.xmss.prf import PRFKey +from lean_spec.spec.crypto.xmss.types import ( HashDigestList, HashDigestVector, HashTreeOpening, Parameter, Randomness, ) +from lean_spec.spec.forks.lstar.slot import Slot +from lean_spec.spec.ssz import Uint64 +from lean_spec.spec.ssz.container import Container class PublicKey(Container): diff --git a/src/lean_spec/spec/crypto/xmss/encoding.py b/src/lean_spec/spec/crypto/xmss/encoding.py index cf6b5205b..264a4f707 100644 --- a/src/lean_spec/spec/crypto/xmss/encoding.py +++ b/src/lean_spec/spec/crypto/xmss/encoding.py @@ -47,14 +47,13 @@ The decode rejects it, a rare event near 4.7e-10 that barely affects signing. """ +from lean_spec.spec.crypto.koalabear import Fp +from lean_spec.spec.crypto.xmss.constants import TWEAK_PREFIX_MESSAGE, XmssConfig +from lean_spec.spec.crypto.xmss.field import int_to_base_p +from lean_spec.spec.crypto.xmss.poseidon import PoseidonXmss +from lean_spec.spec.crypto.xmss.types import Parameter, Randomness from lean_spec.spec.ssz import Bytes32, Uint64 -from ..koalabear import Fp -from .constants import TWEAK_PREFIX_MESSAGE, XmssConfig -from .field import int_to_base_p -from .poseidon import PoseidonXmss -from .types import Parameter, Randomness - def encode_message(config: XmssConfig, message: Bytes32) -> list[Fp]: """Encode a 32-byte message into field elements via base-P decomposition. diff --git a/src/lean_spec/spec/crypto/xmss/field.py b/src/lean_spec/spec/crypto/xmss/field.py index 0c3fa0779..8171d75da 100644 --- a/src/lean_spec/spec/crypto/xmss/field.py +++ b/src/lean_spec/spec/crypto/xmss/field.py @@ -2,9 +2,9 @@ import secrets -from ..koalabear import Fp, P -from .constants import XmssConfig -from .types import HashDigestVector, Parameter +from lean_spec.spec.crypto.koalabear import Fp, P +from lean_spec.spec.crypto.xmss.constants import XmssConfig +from lean_spec.spec.crypto.xmss.types import HashDigestVector, Parameter def int_to_base_p(value: int, num_limbs: int) -> list[Fp]: diff --git a/src/lean_spec/spec/crypto/xmss/interface.py b/src/lean_spec/spec/crypto/xmss/interface.py index 4e189fa22..20ce0836c 100644 --- a/src/lean_spec/spec/crypto/xmss/interface.py +++ b/src/lean_spec/spec/crypto/xmss/interface.py @@ -2,18 +2,17 @@ from lean_spec.base import StrictBaseModel from lean_spec.config import LEAN_ENV +from lean_spec.spec.crypto.xmss.constants import PROD_CONFIG, TEST_CONFIG, XmssConfig +from lean_spec.spec.crypto.xmss.containers import KeyPair, PublicKey, SecretKey, Signature +from lean_spec.spec.crypto.xmss.encoding import target_sum_encode +from lean_spec.spec.crypto.xmss.field import random_parameter +from lean_spec.spec.crypto.xmss.merkle import HashSubTree, combined_path, verify_path +from lean_spec.spec.crypto.xmss.poseidon import PROD_POSEIDON, TEST_POSEIDON, PoseidonXmss +from lean_spec.spec.crypto.xmss.prf import PRFKey +from lean_spec.spec.crypto.xmss.types import HashDigestList, HashDigestVector from lean_spec.spec.forks.lstar.slot import Slot from lean_spec.spec.ssz import Bytes32, Uint64 -from .constants import PROD_CONFIG, TEST_CONFIG, XmssConfig -from .containers import KeyPair, PublicKey, SecretKey, Signature -from .encoding import target_sum_encode -from .field import random_parameter -from .merkle import HashSubTree, combined_path, verify_path -from .poseidon import PROD_POSEIDON, TEST_POSEIDON, PoseidonXmss -from .prf import PRFKey -from .types import HashDigestList, HashDigestVector - def _expand_activation_time( log_lifetime: int, desired_activation_slot: int, desired_num_active_slots: int diff --git a/src/lean_spec/spec/crypto/xmss/merkle.py b/src/lean_spec/spec/crypto/xmss/merkle.py index 26dd9ed1d..80fe00860 100644 --- a/src/lean_spec/spec/crypto/xmss/merkle.py +++ b/src/lean_spec/spec/crypto/xmss/merkle.py @@ -29,21 +29,20 @@ from itertools import batched from typing import Self -from lean_spec.spec.ssz import Uint64 -from lean_spec.spec.ssz.collections import SSZList -from lean_spec.spec.ssz.container import Container - -from .constants import TARGET_CONFIG, XmssConfig -from .field import random_domain -from .poseidon import PoseidonXmss -from .prf import PRFKey -from .types import ( +from lean_spec.spec.crypto.xmss.constants import TARGET_CONFIG, XmssConfig +from lean_spec.spec.crypto.xmss.field import random_domain +from lean_spec.spec.crypto.xmss.poseidon import PoseidonXmss +from lean_spec.spec.crypto.xmss.prf import PRFKey +from lean_spec.spec.crypto.xmss.types import ( HashDigestList, HashDigestVector, HashTreeOpening, Parameter, TreeTweak, ) +from lean_spec.spec.ssz import Uint64 +from lean_spec.spec.ssz.collections import SSZList +from lean_spec.spec.ssz.container import Container class HashTreeLayer(Container): diff --git a/src/lean_spec/spec/crypto/xmss/poseidon.py b/src/lean_spec/spec/crypto/xmss/poseidon.py index 2a2e59ce0..4f9f81b5d 100644 --- a/src/lean_spec/spec/crypto/xmss/poseidon.py +++ b/src/lean_spec/spec/crypto/xmss/poseidon.py @@ -5,19 +5,13 @@ from pydantic import PrivateAttr from lean_spec.base import StrictBaseModel +from lean_spec.spec.crypto.koalabear import Fp +from lean_spec.spec.crypto.poseidon import PARAMS_16, PARAMS_24, Poseidon, PoseidonParams +from lean_spec.spec.crypto.xmss.constants import TWEAK_PREFIX_CHAIN, TWEAK_PREFIX_TREE, XmssConfig +from lean_spec.spec.crypto.xmss.field import int_to_base_p +from lean_spec.spec.crypto.xmss.types import ChainTweak, HashDigestVector, Parameter, TreeTweak from lean_spec.spec.ssz import Uint64 -from ..koalabear import Fp -from ..poseidon import ( - PARAMS_16, - PARAMS_24, - Poseidon, - PoseidonParams, -) -from .constants import TWEAK_PREFIX_CHAIN, TWEAK_PREFIX_TREE, XmssConfig -from .field import int_to_base_p -from .types import ChainTweak, HashDigestVector, Parameter, TreeTweak - class PoseidonXmss(StrictBaseModel): """Poseidon hash engine wrapper used inside the XMSS scheme.""" diff --git a/src/lean_spec/spec/crypto/xmss/prf.py b/src/lean_spec/spec/crypto/xmss/prf.py index 3f375a32b..4b55833a3 100644 --- a/src/lean_spec/spec/crypto/xmss/prf.py +++ b/src/lean_spec/spec/crypto/xmss/prf.py @@ -5,13 +5,12 @@ from itertools import batched from typing import Final, Self +from lean_spec.spec.crypto.koalabear import Fp +from lean_spec.spec.crypto.xmss.constants import PRF_KEY_LENGTH, XmssConfig +from lean_spec.spec.crypto.xmss.types import HashDigestVector, Randomness from lean_spec.spec.ssz import Bytes16, Bytes32, Uint64 from lean_spec.spec.ssz.byte_arrays import BaseBytes -from ..koalabear import Fp -from .constants import PRF_KEY_LENGTH, XmssConfig -from .types import HashDigestVector, Randomness - PRF_DOMAIN_SEP: Final = Bytes16(b"\xae\xae\x22\xff\x00\x01\xfa\xff\x21\xaf\x12\x00\x01\x11\xff\x00") """ Fixed domain separator prefixed to every PRF call. diff --git a/src/lean_spec/spec/crypto/xmss/types.py b/src/lean_spec/spec/crypto/xmss/types.py index 575c63343..dec6c83eb 100644 --- a/src/lean_spec/spec/crypto/xmss/types.py +++ b/src/lean_spec/spec/crypto/xmss/types.py @@ -3,12 +3,11 @@ from typing import Final, NamedTuple from lean_spec.spec.crypto.koalabear import Fp +from lean_spec.spec.crypto.xmss.constants import TARGET_CONFIG from lean_spec.spec.ssz import Uint64 from lean_spec.spec.ssz.collections import SSZList, SSZVector from lean_spec.spec.ssz.container import Container -from .constants import TARGET_CONFIG - class TreeTweak(NamedTuple): """Tweak that domain-separates Merkle node hashes by their position.""" diff --git a/src/lean_spec/spec/forks/__init__.py b/src/lean_spec/spec/forks/__init__.py index c2bbb52fb..48fe6357a 100644 --- a/src/lean_spec/spec/forks/__init__.py +++ b/src/lean_spec/spec/forks/__init__.py @@ -1,6 +1,6 @@ """Multi-fork dispatch layer for leanSpec consensus specification.""" -from .lstar.containers import ( +from lean_spec.spec.forks.lstar.containers import ( IMMEDIATE_JUSTIFICATION_WINDOW, VALIDATOR_REGISTRY_LIMIT, AggregatedAttestation, @@ -14,6 +14,7 @@ BlockHeader, Checkpoint, Config, + Interval, SignedAggregatedAttestation, SignedAttestation, SignedBlock, @@ -25,10 +26,9 @@ ValidatorIndices, Validators, ) -from .lstar.interval import Interval -from .lstar.spec import LstarSpec, LstarStore -from .protocol import ForkProtocol, SpecStateType, SpecStoreType -from .registry import ForkRegistry +from lean_spec.spec.forks.lstar.spec import LstarSpec, LstarStore +from lean_spec.spec.forks.protocol import ForkProtocol, SpecStateType, SpecStoreType +from lean_spec.spec.forks.registry import ForkRegistry Store = LstarStore """Public alias resolving to the concrete LstarStore until other forks land.""" diff --git a/src/lean_spec/spec/forks/lstar/__init__.py b/src/lean_spec/spec/forks/lstar/__init__.py index f1378e077..97ac53d93 100644 --- a/src/lean_spec/spec/forks/lstar/__init__.py +++ b/src/lean_spec/spec/forks/lstar/__init__.py @@ -1,6 +1,6 @@ """Lstar fork""" -from .containers import AttestationSignatureEntry, State -from .spec import LstarStore as Store +from lean_spec.spec.forks.lstar.containers import AttestationSignatureEntry, State +from lean_spec.spec.forks.lstar.spec import LstarStore as Store __all__ = ["AttestationSignatureEntry", "State", "Store"] diff --git a/src/lean_spec/spec/forks/lstar/_contract.py b/src/lean_spec/spec/forks/lstar/_contract.py index 43aeb8744..8da448000 100644 --- a/src/lean_spec/spec/forks/lstar/_contract.py +++ b/src/lean_spec/spec/forks/lstar/_contract.py @@ -11,6 +11,7 @@ BlockBody, BlockHeader, Config, + Interval, SignedAggregatedAttestation, SignedBlock, SingleMessageAggregate, @@ -20,11 +21,9 @@ ValidatorIndex, Validators, ) +from lean_spec.spec.forks.protocol import ForkProtocol from lean_spec.spec.ssz import Bytes32 -from ..protocol import ForkProtocol -from .interval import Interval - LstarStore = Store[State, Block] """Concrete Store specialization owned by the lstar fork.""" diff --git a/src/lean_spec/spec/forks/lstar/aggregation.py b/src/lean_spec/spec/forks/lstar/aggregation.py index bbdeaf89a..224dffac8 100644 --- a/src/lean_spec/spec/forks/lstar/aggregation.py +++ b/src/lean_spec/spec/forks/lstar/aggregation.py @@ -1,14 +1,13 @@ """Lstar fork — attestation aggregation.""" from lean_spec.spec.crypto.merkleization import hash_tree_root +from lean_spec.spec.forks.lstar._contract import LstarSpecContract, LstarStore from lean_spec.spec.forks.lstar.aggregation_select import select_greedily from lean_spec.spec.forks.lstar.containers import ( SignedAggregatedAttestation, SingleMessageAggregate, ) -from ._contract import LstarSpecContract, LstarStore - class AggregationMixin(LstarSpecContract): """Attestation aggregation for the lstar fork.""" diff --git a/src/lean_spec/spec/forks/lstar/block_production.py b/src/lean_spec/spec/forks/lstar/block_production.py index cd8b33011..4797d5425 100644 --- a/src/lean_spec/spec/forks/lstar/block_production.py +++ b/src/lean_spec/spec/forks/lstar/block_production.py @@ -3,6 +3,7 @@ from collections.abc import Set as AbstractSet from lean_spec.spec.crypto.merkleization import hash_tree_root +from lean_spec.spec.forks.lstar._contract import LstarSpecContract from lean_spec.spec.forks.lstar.aggregation_select import select_greedily from lean_spec.spec.forks.lstar.config import ( MAX_ATTESTATIONS_DATA, @@ -17,11 +18,9 @@ State, ValidatorIndex, ) +from lean_spec.spec.forks.lstar.state_transition import attestation_data_matches_chain from lean_spec.spec.ssz import ZERO_HASH, Bytes32, Uint8 -from ._contract import LstarSpecContract -from .state_transition import attestation_data_matches_chain - class BlockProductionMixin(LstarSpecContract): """Proposer-side block building for the lstar fork.""" diff --git a/src/lean_spec/spec/forks/lstar/containers.py b/src/lean_spec/spec/forks/lstar/containers.py index 9fae72b97..3031f954f 100644 --- a/src/lean_spec/spec/forks/lstar/containers.py +++ b/src/lean_spec/spec/forks/lstar/containers.py @@ -15,13 +15,11 @@ from lean_spec.base import StrictBaseModel from lean_spec.config import LEAN_ENV from lean_spec.spec.crypto.xmss.containers import PublicKey, Signature -from lean_spec.spec.forks.lstar.config import HISTORICAL_ROOTS_LIMIT +from lean_spec.spec.forks.lstar.config import HISTORICAL_ROOTS_LIMIT, INTERVALS_PER_SLOT +from lean_spec.spec.forks.lstar.slot import IMMEDIATE_JUSTIFICATION_WINDOW, Slot from lean_spec.spec.ssz import Boolean, ByteList512KiB, Bytes32, Bytes52, Container, SSZList, Uint64 from lean_spec.spec.ssz.bitfields import BaseBitlist -from .interval import Interval -from .slot import IMMEDIATE_JUSTIFICATION_WINDOW, Slot - __all__ = [ # Re-exports from the slot module so downstream callers can keep # importing these names from .containers. @@ -40,6 +38,29 @@ """ +class Interval(Uint64): + """Interval count since genesis.""" + + @classmethod + def from_slot(cls, slot: Slot) -> "Interval": + """ + Convert a slot number to the interval at that slot's start. + + Each slot spans a fixed number of intervals. + This gives the first interval of the given slot. + + Args: + slot: Slot number since genesis. + + Returns: + Interval count at the start of the given slot. + """ + # Slot boundaries fall on exact multiples of the interval count. + # + # The two values are distinct unsigned types, so drop to plain ints to multiply. + return cls(int(slot) * int(INTERVALS_PER_SLOT)) + + class SubnetId(Uint64): """Subnet identifier (0-63) for attestation subnet partitioning.""" diff --git a/src/lean_spec/spec/forks/lstar/fork_choice.py b/src/lean_spec/spec/forks/lstar/fork_choice.py index deaa3ed13..eab9e5f09 100644 --- a/src/lean_spec/spec/forks/lstar/fork_choice.py +++ b/src/lean_spec/spec/forks/lstar/fork_choice.py @@ -9,6 +9,7 @@ ) from lean_spec.spec.crypto.merkleization import hash_tree_root from lean_spec.spec.crypto.xmss.interface import TARGET_SIGNATURE_SCHEME +from lean_spec.spec.forks.lstar._contract import LstarSpecContract, LstarStore from lean_spec.spec.forks.lstar.config import ( GOSSIP_DISPARITY_INTERVALS, MAX_ATTESTATIONS_DATA, @@ -19,6 +20,7 @@ AttestationSignatureEntry, Block, Checkpoint, + Interval, SignedAggregatedAttestation, SignedAttestation, SignedBlock, @@ -27,12 +29,9 @@ State, ValidatorIndex, ) +from lean_spec.spec.forks.protocol import SpecBlockType, SpecStateType from lean_spec.spec.ssz import Bytes32, Uint64 -from ..protocol import SpecBlockType, SpecStateType -from ._contract import LstarSpecContract, LstarStore -from .interval import Interval - class ForkChoiceMixin(LstarSpecContract): """Fork choice and store maintenance for the lstar fork.""" diff --git a/src/lean_spec/spec/forks/lstar/interval.py b/src/lean_spec/spec/forks/lstar/interval.py deleted file mode 100644 index 8baff8bd7..000000000 --- a/src/lean_spec/spec/forks/lstar/interval.py +++ /dev/null @@ -1,31 +0,0 @@ -"""Interval time unit.""" - -from __future__ import annotations - -from lean_spec.spec.ssz import Uint64 - -from .config import INTERVALS_PER_SLOT -from .slot import Slot - - -class Interval(Uint64): - """Interval count since genesis.""" - - @classmethod - def from_slot(cls, slot: Slot) -> Interval: - """ - Convert a slot number to the interval at that slot's start. - - Each slot spans a fixed number of intervals. - This gives the first interval of the given slot. - - Args: - slot: Slot number since genesis. - - Returns: - Interval count at the start of the given slot. - """ - # Slot boundaries fall on exact multiples of the interval count. - # - # The two values are distinct unsigned types, so drop to plain ints to multiply. - return cls(int(slot) * int(INTERVALS_PER_SLOT)) diff --git a/src/lean_spec/spec/forks/lstar/signatures.py b/src/lean_spec/spec/forks/lstar/signatures.py index 37c0805c6..89f847cdc 100644 --- a/src/lean_spec/spec/forks/lstar/signatures.py +++ b/src/lean_spec/spec/forks/lstar/signatures.py @@ -2,6 +2,7 @@ from lean_spec.spec.crypto.merkleization import hash_tree_root from lean_spec.spec.crypto.xmss.containers import PublicKey +from lean_spec.spec.forks.lstar._contract import LstarSpecContract from lean_spec.spec.forks.lstar.containers import ( AggregationError, SignedBlock, @@ -10,8 +11,6 @@ ) from lean_spec.spec.ssz import Bytes32, Uint64 -from ._contract import LstarSpecContract - class SignatureMixin(LstarSpecContract): """Block signature verification for the lstar fork.""" diff --git a/src/lean_spec/spec/forks/lstar/spec.py b/src/lean_spec/spec/forks/lstar/spec.py index 605fdad70..007b52396 100644 --- a/src/lean_spec/spec/forks/lstar/spec.py +++ b/src/lean_spec/spec/forks/lstar/spec.py @@ -2,11 +2,10 @@ from typing import ClassVar -from ..protocol import ForkProtocol -from ._contract import LstarSpecContract, LstarStore -from .aggregation import AggregationMixin -from .block_production import BlockProductionMixin -from .containers import ( +from lean_spec.spec.forks.lstar._contract import LstarSpecContract, LstarStore +from lean_spec.spec.forks.lstar.aggregation import AggregationMixin +from lean_spec.spec.forks.lstar.block_production import BlockProductionMixin +from lean_spec.spec.forks.lstar.containers import ( AggregatedAttestation, AggregatedAttestations, AttestationData, @@ -16,11 +15,12 @@ Config, State, ) -from .fork_choice import ForkChoiceMixin -from .signatures import SignatureMixin -from .state_transition import StateTransitionMixin -from .timeline import TimelineMixin -from .validator_duties import ValidatorDutiesMixin +from lean_spec.spec.forks.lstar.fork_choice import ForkChoiceMixin +from lean_spec.spec.forks.lstar.signatures import SignatureMixin +from lean_spec.spec.forks.lstar.state_transition import StateTransitionMixin +from lean_spec.spec.forks.lstar.timeline import TimelineMixin +from lean_spec.spec.forks.lstar.validator_duties import ValidatorDutiesMixin +from lean_spec.spec.forks.protocol import ForkProtocol __all__ = ["LstarSpec", "LstarStore"] diff --git a/src/lean_spec/spec/forks/lstar/state_transition.py b/src/lean_spec/spec/forks/lstar/state_transition.py index 2e1d8d58d..f97b54676 100644 --- a/src/lean_spec/spec/forks/lstar/state_transition.py +++ b/src/lean_spec/spec/forks/lstar/state_transition.py @@ -8,6 +8,7 @@ observe_state_transition, ) from lean_spec.spec.crypto.merkleization import hash_tree_root +from lean_spec.spec.forks.lstar._contract import LstarSpecContract from lean_spec.spec.forks.lstar.containers import ( AggregatedAttestation, AttestationData, @@ -22,11 +23,9 @@ ValidatorIndex, Validators, ) +from lean_spec.spec.forks.protocol import SpecStateType from lean_spec.spec.ssz import ZERO_HASH, Boolean, Bytes32, SSZList, Uint64 -from ..protocol import SpecStateType -from ._contract import LstarSpecContract - def attestation_data_matches_chain( attestation_data: AttestationData, diff --git a/src/lean_spec/spec/forks/lstar/timeline.py b/src/lean_spec/spec/forks/lstar/timeline.py index 53a18894f..08ace3b3a 100644 --- a/src/lean_spec/spec/forks/lstar/timeline.py +++ b/src/lean_spec/spec/forks/lstar/timeline.py @@ -1,15 +1,14 @@ """Lstar fork — interval ticking and time progression.""" +from lean_spec.spec.forks.lstar._contract import LstarSpecContract, LstarStore from lean_spec.spec.forks.lstar.config import ( INTERVALS_PER_SLOT, ) from lean_spec.spec.forks.lstar.containers import ( + Interval, SignedAggregatedAttestation, ) -from ._contract import LstarSpecContract, LstarStore -from .interval import Interval - class TimelineMixin(LstarSpecContract): """Interval ticking and time progression for the lstar fork.""" diff --git a/src/lean_spec/spec/forks/lstar/validator_duties.py b/src/lean_spec/spec/forks/lstar/validator_duties.py index d64d0b756..2058dc95a 100644 --- a/src/lean_spec/spec/forks/lstar/validator_duties.py +++ b/src/lean_spec/spec/forks/lstar/validator_duties.py @@ -1,6 +1,7 @@ """Lstar fork — validator duties: proposal head and production.""" from lean_spec.spec.crypto.merkleization import hash_tree_root +from lean_spec.spec.forks.lstar._contract import LstarSpecContract, LstarStore from lean_spec.spec.forks.lstar.config import ( JUSTIFICATION_LOOKBACK_SLOTS, ) @@ -8,15 +9,13 @@ AttestationData, Block, Checkpoint, + Interval, SingleMessageAggregate, Slot, ValidatorIndex, ) from lean_spec.spec.ssz import Bytes32, Uint64 -from ._contract import LstarSpecContract, LstarStore -from .interval import Interval - class ValidatorDutiesMixin(LstarSpecContract): """Validator duties for the lstar fork.""" diff --git a/src/lean_spec/spec/forks/registry.py b/src/lean_spec/spec/forks/registry.py index 96355c378..d30d94155 100644 --- a/src/lean_spec/spec/forks/registry.py +++ b/src/lean_spec/spec/forks/registry.py @@ -2,7 +2,7 @@ from itertools import pairwise -from .protocol import ForkProtocol +from lean_spec.spec.forks.protocol import ForkProtocol class ForkRegistry: diff --git a/src/lean_spec/spec/ssz/__init__.py b/src/lean_spec/spec/ssz/__init__.py index 120d35b5c..4c2d5242a 100644 --- a/src/lean_spec/spec/ssz/__init__.py +++ b/src/lean_spec/spec/ssz/__init__.py @@ -1,8 +1,8 @@ """SSZ primitive types and (de)serialization for the Lean Ethereum specification.""" -from .bitfields import BaseBitlist, BaseBitvector -from .boolean import Boolean -from .byte_arrays import ( +from lean_spec.spec.ssz.bitfields import BaseBitlist, BaseBitvector +from lean_spec.spec.ssz.boolean import Boolean +from lean_spec.spec.ssz.byte_arrays import ( ZERO_HASH, BaseByteList, BaseBytes, @@ -17,16 +17,16 @@ Bytes64, Bytes65, ) -from .collections import SSZList, SSZVector -from .container import Container -from .exceptions import ( +from lean_spec.spec.ssz.collections import SSZList, SSZVector +from lean_spec.spec.ssz.container import Container +from lean_spec.spec.ssz.exceptions import ( SSZError, SSZSerializationError, SSZTypeError, SSZValueError, ) -from .ssz_base import SSZType -from .uint import Uint8, Uint16, Uint32, Uint64 +from lean_spec.spec.ssz.ssz_base import SSZType +from lean_spec.spec.ssz.uint import Uint8, Uint16, Uint32, Uint64 __all__ = [ "ZERO_HASH", diff --git a/src/lean_spec/spec/ssz/bitfields.py b/src/lean_spec/spec/ssz/bitfields.py index 1e221f1ae..f364ac5e1 100644 --- a/src/lean_spec/spec/ssz/bitfields.py +++ b/src/lean_spec/spec/ssz/bitfields.py @@ -25,9 +25,9 @@ from pydantic import Field, field_validator -from .boolean import Boolean -from .exceptions import SSZSerializationError, SSZTypeError, SSZValueError -from .ssz_base import SSZModel +from lean_spec.spec.ssz.boolean import Boolean +from lean_spec.spec.ssz.exceptions import SSZSerializationError, SSZTypeError, SSZValueError +from lean_spec.spec.ssz.ssz_base import SSZModel class BaseBitvector(SSZModel): diff --git a/src/lean_spec/spec/ssz/boolean.py b/src/lean_spec/spec/ssz/boolean.py index 7743b82d3..17d273963 100644 --- a/src/lean_spec/spec/ssz/boolean.py +++ b/src/lean_spec/spec/ssz/boolean.py @@ -7,8 +7,8 @@ from pydantic.annotated_handlers import GetCoreSchemaHandler from pydantic_core import CoreSchema, core_schema -from .exceptions import SSZSerializationError, SSZTypeError, SSZValueError -from .ssz_base import SSZType +from lean_spec.spec.ssz.exceptions import SSZSerializationError, SSZTypeError, SSZValueError +from lean_spec.spec.ssz.ssz_base import SSZType class Boolean(int, SSZType): diff --git a/src/lean_spec/spec/ssz/byte_arrays.py b/src/lean_spec/spec/ssz/byte_arrays.py index 57a005f79..a097160aa 100644 --- a/src/lean_spec/spec/ssz/byte_arrays.py +++ b/src/lean_spec/spec/ssz/byte_arrays.py @@ -18,8 +18,8 @@ from pydantic.annotated_handlers import GetCoreSchemaHandler from pydantic_core import core_schema -from .exceptions import SSZSerializationError, SSZTypeError, SSZValueError -from .ssz_base import SSZModel, SSZType +from lean_spec.spec.ssz.exceptions import SSZSerializationError, SSZTypeError, SSZValueError +from lean_spec.spec.ssz.ssz_base import SSZModel, SSZType class BaseBytes(bytes, SSZType): diff --git a/src/lean_spec/spec/ssz/collections.py b/src/lean_spec/spec/ssz/collections.py index 650721f73..ad2fd84a0 100644 --- a/src/lean_spec/spec/ssz/collections.py +++ b/src/lean_spec/spec/ssz/collections.py @@ -46,10 +46,10 @@ from pydantic import Field, field_serializer, field_validator -from .byte_arrays import BaseBytes -from .exceptions import SSZSerializationError, SSZTypeError, SSZValueError -from .ssz_base import BYTES_PER_LENGTH_OFFSET, SSZModel, SSZType -from .uint import Uint32 +from lean_spec.spec.ssz.byte_arrays import BaseBytes +from lean_spec.spec.ssz.exceptions import SSZSerializationError, SSZTypeError, SSZValueError +from lean_spec.spec.ssz.ssz_base import BYTES_PER_LENGTH_OFFSET, SSZModel, SSZType +from lean_spec.spec.ssz.uint import Uint32 def _validate_offsets(offsets: list[int], scope: int, type_name: str) -> None: diff --git a/src/lean_spec/spec/ssz/container.py b/src/lean_spec/spec/ssz/container.py index 67d72fe45..b67311686 100644 --- a/src/lean_spec/spec/ssz/container.py +++ b/src/lean_spec/spec/ssz/container.py @@ -7,9 +7,9 @@ from pydantic import model_validator from pydantic.functional_validators import ModelWrapValidatorHandler -from .exceptions import SSZError, SSZSerializationError, SSZTypeError -from .ssz_base import BYTES_PER_LENGTH_OFFSET, SSZModel, SSZType -from .uint import Uint32 +from lean_spec.spec.ssz.exceptions import SSZError, SSZSerializationError, SSZTypeError +from lean_spec.spec.ssz.ssz_base import BYTES_PER_LENGTH_OFFSET, SSZModel, SSZType +from lean_spec.spec.ssz.uint import Uint32 class Container(SSZModel): diff --git a/src/lean_spec/spec/ssz/ssz_base.py b/src/lean_spec/spec/ssz/ssz_base.py index 680f61288..7bd32b293 100644 --- a/src/lean_spec/spec/ssz/ssz_base.py +++ b/src/lean_spec/spec/ssz/ssz_base.py @@ -5,8 +5,7 @@ from typing import IO, Final, Self from lean_spec.base import StrictBaseModel - -from .exceptions import SSZSerializationError +from lean_spec.spec.ssz.exceptions import SSZSerializationError BYTES_PER_LENGTH_OFFSET: Final = 4 """Width of an SSZ offset prefixing each variable-size element. diff --git a/src/lean_spec/spec/ssz/uint.py b/src/lean_spec/spec/ssz/uint.py index a7d792d10..7d5b16503 100644 --- a/src/lean_spec/spec/ssz/uint.py +++ b/src/lean_spec/spec/ssz/uint.py @@ -7,8 +7,8 @@ from pydantic.annotated_handlers import GetCoreSchemaHandler from pydantic_core import core_schema -from .exceptions import SSZSerializationError, SSZTypeError, SSZValueError -from .ssz_base import SSZType +from lean_spec.spec.ssz.exceptions import SSZSerializationError, SSZTypeError, SSZValueError +from lean_spec.spec.ssz.ssz_base import SSZType class BaseUint(int, SSZType): diff --git a/tests/interop/conftest.py b/tests/interop/conftest.py index 3fe8342e0..aacb4e5d0 100644 --- a/tests/interop/conftest.py +++ b/tests/interop/conftest.py @@ -12,7 +12,7 @@ import pytest -from .helpers import NodeCluster, PortAllocator +from tests.interop.helpers import NodeCluster, PortAllocator logger = logging.getLogger(__name__) diff --git a/tests/interop/helpers/__init__.py b/tests/interop/helpers/__init__.py index 976497e56..622152417 100644 --- a/tests/interop/helpers/__init__.py +++ b/tests/interop/helpers/__init__.py @@ -1,14 +1,14 @@ """Helper utilities for interop tests.""" -from .assertions import ( +from tests.interop.helpers.assertions import ( assert_checkpoint_monotonicity, assert_heads_consistent, assert_peer_connections, ) -from .diagnostics import PipelineDiagnostics -from .node_runner import NodeCluster -from .port_allocator import PortAllocator -from .topology import full_mesh +from tests.interop.helpers.diagnostics import PipelineDiagnostics +from tests.interop.helpers.node_runner import NodeCluster +from tests.interop.helpers.port_allocator import PortAllocator +from tests.interop.helpers.topology import full_mesh __all__ = [ # Assertions diff --git a/tests/interop/helpers/assertions.py b/tests/interop/helpers/assertions.py index cd7a6d23f..25138b2f2 100644 --- a/tests/interop/helpers/assertions.py +++ b/tests/interop/helpers/assertions.py @@ -12,8 +12,8 @@ import logging import time -from .diagnostics import PipelineDiagnostics -from .node_runner import NodeCluster +from tests.interop.helpers.diagnostics import PipelineDiagnostics +from tests.interop.helpers.node_runner import NodeCluster logger = logging.getLogger(__name__) diff --git a/tests/interop/helpers/node_runner.py b/tests/interop/helpers/node_runner.py index c1da8fba3..c0d95ce74 100644 --- a/tests/interop/helpers/node_runner.py +++ b/tests/interop/helpers/node_runner.py @@ -28,9 +28,8 @@ from lean_spec.spec.forks.lstar.containers import Validator, Validators from lean_spec.spec.forks.lstar.spec import LstarSpec from lean_spec.spec.ssz import Bytes52, Uint64 - -from .diagnostics import PipelineDiagnostics -from .port_allocator import PortAllocator +from tests.interop.helpers.diagnostics import PipelineDiagnostics +from tests.interop.helpers.port_allocator import PortAllocator logger = logging.getLogger(__name__) diff --git a/tests/interop/test_consensus_lifecycle.py b/tests/interop/test_consensus_lifecycle.py index 2a7a26049..c642a1345 100644 --- a/tests/interop/test_consensus_lifecycle.py +++ b/tests/interop/test_consensus_lifecycle.py @@ -20,8 +20,7 @@ import pytest from lean_spec.spec.forks import ValidatorIndex - -from .helpers import ( +from tests.interop.helpers import ( NodeCluster, PipelineDiagnostics, assert_checkpoint_monotonicity, diff --git a/tests/lean_spec/helpers/__init__.py b/tests/lean_spec/helpers/__init__.py index d4821b7a8..beb572d04 100644 --- a/tests/lean_spec/helpers/__init__.py +++ b/tests/lean_spec/helpers/__init__.py @@ -3,8 +3,7 @@ from __future__ import annotations from lean_spec.spec.forks import ValidatorIndex - -from .builders import ( +from tests.lean_spec.helpers.builders import ( GenesisData, create_mock_sync_service, make_aggregated_attestation, @@ -32,7 +31,7 @@ make_validators, make_validators_from_key_manager, ) -from .mocks import ( +from tests.lean_spec.helpers.mocks import ( MockEventSource, MockForkchoiceStore, MockNetworkRequester, diff --git a/tests/lean_spec/helpers/builders.py b/tests/lean_spec/helpers/builders.py index 1922c3c70..886739601 100644 --- a/tests/lean_spec/helpers/builders.py +++ b/tests/lean_spec/helpers/builders.py @@ -48,8 +48,11 @@ ) from lean_spec.spec.forks.lstar.spec import LstarSpec from lean_spec.spec.ssz import ByteList512KiB, Bytes32, Bytes52, Uint64 - -from .mocks import MockForkchoiceStore, MockNetworkRequester, StoreInterceptingSpec +from tests.lean_spec.helpers.mocks import ( + MockForkchoiceStore, + MockNetworkRequester, + StoreInterceptingSpec, +) def make_bytes32(seed: int) -> Bytes32: diff --git a/tests/lean_spec/node/networking/gossipsub/integration/conftest.py b/tests/lean_spec/node/networking/gossipsub/integration/conftest.py index cc01d6944..7a9336e3b 100644 --- a/tests/lean_spec/node/networking/gossipsub/integration/conftest.py +++ b/tests/lean_spec/node/networking/gossipsub/integration/conftest.py @@ -8,9 +8,8 @@ import pytest from lean_spec.node.networking.gossipsub.parameters import GossipsubParameters - -from .network import GossipsubTestNetwork -from .node import GossipsubTestNode +from tests.lean_spec.node.networking.gossipsub.integration.network import GossipsubTestNetwork +from tests.lean_spec.node.networking.gossipsub.integration.node import GossipsubTestNode def fast_params(**overrides: int | float | str) -> GossipsubParameters: diff --git a/tests/lean_spec/node/networking/gossipsub/integration/network.py b/tests/lean_spec/node/networking/gossipsub/integration/network.py index 149688abf..22d6e665c 100644 --- a/tests/lean_spec/node/networking/gossipsub/integration/network.py +++ b/tests/lean_spec/node/networking/gossipsub/integration/network.py @@ -10,8 +10,7 @@ from lean_spec.node.networking.gossipsub.parameters import GossipsubParameters from lean_spec.node.networking.gossipsub.types import TopicId - -from .node import GossipsubTestNode +from tests.lean_spec.node.networking.gossipsub.integration.node import GossipsubTestNode # PeerId uses Base58 encoding, which excludes 0, O, I, and l to prevent # visual ambiguity. These names use only characters in the Base58 alphabet. diff --git a/tests/lean_spec/node/networking/gossipsub/integration/node.py b/tests/lean_spec/node/networking/gossipsub/integration/node.py index 1f93593be..ee1eeb8d3 100644 --- a/tests/lean_spec/node/networking/gossipsub/integration/node.py +++ b/tests/lean_spec/node/networking/gossipsub/integration/node.py @@ -17,8 +17,7 @@ ) from lean_spec.node.networking.gossipsub.parameters import GossipsubParameters from lean_spec.node.networking.gossipsub.types import TopicId - -from .stream import create_stream_pair +from tests.lean_spec.node.networking.gossipsub.integration.stream import create_stream_pair @dataclass diff --git a/tests/lean_spec/node/networking/gossipsub/integration/test_connectivity.py b/tests/lean_spec/node/networking/gossipsub/integration/test_connectivity.py index 3e2c8e348..a40f327dc 100644 --- a/tests/lean_spec/node/networking/gossipsub/integration/test_connectivity.py +++ b/tests/lean_spec/node/networking/gossipsub/integration/test_connectivity.py @@ -14,10 +14,9 @@ from lean_spec.node.networking.gossipsub.behavior import GossipsubMessageEvent from lean_spec.node.networking.gossipsub.message import GossipsubMessage from lean_spec.node.networking.gossipsub.types import TopicId - -from .conftest import fast_params -from .network import GossipsubTestNetwork -from .node import GossipsubTestNode +from tests.lean_spec.node.networking.gossipsub.integration.conftest import fast_params +from tests.lean_spec.node.networking.gossipsub.integration.network import GossipsubTestNetwork +from tests.lean_spec.node.networking.gossipsub.integration.node import GossipsubTestNode TOPIC = TopicId("test/connectivity") diff --git a/tests/lean_spec/node/networking/gossipsub/integration/test_heartbeat_integ.py b/tests/lean_spec/node/networking/gossipsub/integration/test_heartbeat_integ.py index 33ad9b5bf..0feccf133 100644 --- a/tests/lean_spec/node/networking/gossipsub/integration/test_heartbeat_integ.py +++ b/tests/lean_spec/node/networking/gossipsub/integration/test_heartbeat_integ.py @@ -15,9 +15,8 @@ from lean_spec.node.networking.gossipsub.behavior import IDONTWANT_SIZE_THRESHOLD from lean_spec.node.networking.gossipsub.message import GossipsubMessage from lean_spec.node.networking.gossipsub.types import TopicId - -from .conftest import fast_params -from .network import GossipsubTestNetwork +from tests.lean_spec.node.networking.gossipsub.integration.conftest import fast_params +from tests.lean_spec.node.networking.gossipsub.integration.network import GossipsubTestNetwork TOPIC = TopicId("test/heartbeat") diff --git a/tests/lean_spec/node/networking/gossipsub/integration/test_idontwant.py b/tests/lean_spec/node/networking/gossipsub/integration/test_idontwant.py index e87256011..49bc2e34f 100644 --- a/tests/lean_spec/node/networking/gossipsub/integration/test_idontwant.py +++ b/tests/lean_spec/node/networking/gossipsub/integration/test_idontwant.py @@ -18,9 +18,8 @@ ) from lean_spec.node.networking.gossipsub.message import GossipsubMessage from lean_spec.node.networking.gossipsub.types import TopicId - -from .conftest import fast_params -from .network import GossipsubTestNetwork +from tests.lean_spec.node.networking.gossipsub.integration.conftest import fast_params +from tests.lean_spec.node.networking.gossipsub.integration.network import GossipsubTestNetwork TOPIC = TopicId("test/idontwant") diff --git a/tests/lean_spec/node/networking/gossipsub/integration/test_mesh_formation.py b/tests/lean_spec/node/networking/gossipsub/integration/test_mesh_formation.py index 91f9e4ed6..78acb275f 100644 --- a/tests/lean_spec/node/networking/gossipsub/integration/test_mesh_formation.py +++ b/tests/lean_spec/node/networking/gossipsub/integration/test_mesh_formation.py @@ -18,9 +18,8 @@ import pytest from lean_spec.node.networking.gossipsub.types import TopicId - -from .conftest import fast_params -from .network import GossipsubTestNetwork +from tests.lean_spec.node.networking.gossipsub.integration.conftest import fast_params +from tests.lean_spec.node.networking.gossipsub.integration.network import GossipsubTestNetwork TOPIC = TopicId("test/mesh") diff --git a/tests/lean_spec/node/networking/gossipsub/integration/test_propagation.py b/tests/lean_spec/node/networking/gossipsub/integration/test_propagation.py index 0dff5835c..5cc72730d 100644 --- a/tests/lean_spec/node/networking/gossipsub/integration/test_propagation.py +++ b/tests/lean_spec/node/networking/gossipsub/integration/test_propagation.py @@ -9,9 +9,8 @@ from lean_spec.node.networking.gossipsub.behavior import GossipsubMessageEvent from lean_spec.node.networking.gossipsub.message import GossipsubMessage from lean_spec.node.networking.gossipsub.types import TopicId - -from .conftest import fast_params -from .network import GossipsubTestNetwork +from tests.lean_spec.node.networking.gossipsub.integration.conftest import fast_params +from tests.lean_spec.node.networking.gossipsub.integration.network import GossipsubTestNetwork TOPIC = TopicId("test/propagation") diff --git a/tests/lean_spec/node/networking/gossipsub/integration/test_stress.py b/tests/lean_spec/node/networking/gossipsub/integration/test_stress.py index 53773e3d6..796f03e4f 100644 --- a/tests/lean_spec/node/networking/gossipsub/integration/test_stress.py +++ b/tests/lean_spec/node/networking/gossipsub/integration/test_stress.py @@ -9,9 +9,8 @@ from lean_spec.node.networking.gossipsub.behavior import GossipsubMessageEvent from lean_spec.node.networking.gossipsub.message import GossipsubMessage from lean_spec.node.networking.gossipsub.types import TopicId - -from .conftest import fast_params -from .network import GossipsubTestNetwork +from tests.lean_spec.node.networking.gossipsub.integration.conftest import fast_params +from tests.lean_spec.node.networking.gossipsub.integration.network import GossipsubTestNetwork TOPIC = TopicId("test/stress") diff --git a/tests/lean_spec/node/networking/gossipsub/integration/test_subscription.py b/tests/lean_spec/node/networking/gossipsub/integration/test_subscription.py index 2cf960b07..04f319ca8 100644 --- a/tests/lean_spec/node/networking/gossipsub/integration/test_subscription.py +++ b/tests/lean_spec/node/networking/gossipsub/integration/test_subscription.py @@ -7,9 +7,8 @@ import pytest from lean_spec.node.networking.gossipsub.types import TopicId - -from .conftest import fast_params -from .network import GossipsubTestNetwork +from tests.lean_spec.node.networking.gossipsub.integration.conftest import fast_params +from tests.lean_spec.node.networking.gossipsub.integration.network import GossipsubTestNetwork TOPIC = TopicId("test/subscription") diff --git a/tests/lean_spec/node/networking/gossipsub/test_handlers.py b/tests/lean_spec/node/networking/gossipsub/test_handlers.py index 4dfc81143..a84e0bced 100644 --- a/tests/lean_spec/node/networking/gossipsub/test_handlers.py +++ b/tests/lean_spec/node/networking/gossipsub/test_handlers.py @@ -25,8 +25,7 @@ SubOpts, ) from lean_spec.node.networking.gossipsub.types import MessageId, Timestamp, TopicId - -from .conftest import add_peer, make_behavior, make_peer +from tests.lean_spec.node.networking.gossipsub.conftest import add_peer, make_behavior, make_peer class TestHandleGraft: diff --git a/tests/lean_spec/node/networking/gossipsub/test_heartbeat.py b/tests/lean_spec/node/networking/gossipsub/test_heartbeat.py index 989623e16..a9e0105c0 100644 --- a/tests/lean_spec/node/networking/gossipsub/test_heartbeat.py +++ b/tests/lean_spec/node/networking/gossipsub/test_heartbeat.py @@ -21,8 +21,7 @@ ControlPrune, ) from lean_spec.node.networking.gossipsub.types import MessageId, Timestamp, TopicId - -from .conftest import add_peer, make_behavior, make_peer +from tests.lean_spec.node.networking.gossipsub.conftest import add_peer, make_behavior, make_peer class TestMaintainMesh: diff --git a/tests/lean_spec/node/networking/gossipsub/test_publish.py b/tests/lean_spec/node/networking/gossipsub/test_publish.py index 177a45777..248a4a19c 100644 --- a/tests/lean_spec/node/networking/gossipsub/test_publish.py +++ b/tests/lean_spec/node/networking/gossipsub/test_publish.py @@ -18,8 +18,7 @@ SubOpts, ) from lean_spec.node.networking.gossipsub.types import TopicId - -from .conftest import add_peer, make_behavior +from tests.lean_spec.node.networking.gossipsub.conftest import add_peer, make_behavior class TestPublish: