Skip to content

Commit e545e14

Browse files
anshalshuklatcoratgerTomWambsgansclaude
authored
Update multisig bindings to support recursive aggregation (leanEthereum#496)
* cryptography: replace Poseidon2 by Poseidon1 * cleanup * add zk friendly encoding * fix constants * small changes (data ordering + replacement sponge) * update leanmultisig bindings * update bindings commit hash * update as per latest api * update bindings * fix ci * set gossipsub to v1.2.0 * try ci fix * address comments * use log_inv_rate=1 in test mode * tests: try to debug test fixtures * update lean-multisig-py * review: code quality fixes and compact aggregate refactor - Remove duplicate TYPE_CHECKING import in state.py - Add explicit parentheses for operator precedence in poseidon1 permutation - Alias TEST_POSEIDON to PROD_POSEIDON (identical params, misleading docstring) - Cache Poseidon1 engine in compress() consistently with sponge() - Fix Mapping -> dict annotation for mutated variable in fork_choice.py - Replace comments with docstrings for module constants (project convention) - Remove stale Poseidon2 reference in permutation.py - Add docstrings to PROD_CONFIG, TEST_CONFIG, PARAMS_16, PARAMS_24 - Refactor _extend_proofs_greedily -> _select_proofs_greedily: - Return values instead of mutating in place - Variadic *proof_sets for priority-ordered input - Remove attestation_data/attestations optional params - Simplify aggregate() method: - Remove redundant double-sort - Phase 2 as filtered comprehension - Dict key views without set() wrapping - Early return [] Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * cleanup: remove dead code after poseidon1 migration - Delete hypercube.py (no longer imported by message_hash.py) - Delete test_hypercube.py (tested only the deleted module) - Inline _calculate_layer_size into test_security_levels.py (sole consumer) - Update CONTRIBUTING.md: poseidon2 -> poseidon1 reference - Update README.md: poseidon2/ -> poseidon1/ directory tree Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: correct comment about sort ordering in aggregate The Rust aggregation bindings sort internally by public key, not by validator index. The sort here is for deterministic output. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Thomas Coratger <thomas.coratger@gmail.com> Co-authored-by: Tom Wambsgans <TomWambsgans@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent dbc2e77 commit e545e14

52 files changed

Lines changed: 2811 additions & 2490 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.codespell-ignore-words.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ subspecs
44
crate
55
crates
66
ethereum
7-
poseidon2
7+
poseidon1
88
keccak
99
blake
1010
merkle

.github/workflows/ci.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,10 @@ jobs:
119119
- name: Checkout leanSpec
120120
uses: actions/checkout@v4
121121

122-
- name: Set up Python 3.12
122+
- name: Set up Python 3.14
123123
uses: actions/setup-python@v5
124124
with:
125-
python-version: "3.12"
125+
python-version: "3.14"
126126

127127
- name: Install uv
128128
uses: astral-sh/setup-uv@v4
@@ -134,6 +134,7 @@ jobs:
134134
run: |
135135
uv run pytest tests/interop/ \
136136
-v \
137+
--no-cov \
137138
--timeout=120 \
138139
-x \
139140
--tb=short \

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
## Adding New Subspecifications
2828

29-
New subspecs belong in `src/lean_spec/subspecs/`. Follow the pattern of existing subspecs like `poseidon2`:
29+
New subspecs belong in `src/lean_spec/subspecs/`. Follow the pattern of existing subspecs like `poseidon1`:
3030

3131
```bash
3232
mkdir -p src/lean_spec/subspecs/my_new_subspec

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ uv run pytest
6868
│ └── lean_spec/ # Main specifications
6969
│ ├── __init__.py
7070
│ └── subspecs/ # Sub-specifications
71-
│ ├── poseidon2/
71+
│ ├── poseidon1/
7272
│ │ ├── __init__.py
73-
│ │ ├── poseidon2.py
74-
│ │ └── ...
73+
│ │ ├── permutation.py
74+
│ │ └── constants.py
7575
│ ├── ...
7676
│ └── ...
7777
├── tests/ # Test suite

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

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

88
from __future__ import annotations
99

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

1212
from pydantic import model_validator
1313

@@ -33,6 +33,7 @@
3333
)
3434
from lean_spec.subspecs.containers.block.types import (
3535
AggregatedAttestations,
36+
AttestationSignatures,
3637
)
3738
from lean_spec.subspecs.containers.checkpoint import Checkpoint
3839
from lean_spec.subspecs.containers.slot import Slot
@@ -456,23 +457,14 @@ def _build_block_from_spec(
456457
#
457458
# block_payloads contains explicit spec attestations only.
458459
parent_state = store.states[parent_root]
459-
final_block, post_state, _, _ = parent_state.build_block(
460+
final_block, post_state, _, block_proofs = parent_state.build_block(
460461
slot=spec.slot,
461462
proposer_index=proposer_index,
462463
parent_root=parent_root,
463464
known_block_roots=set(store.blocks.keys()),
464465
aggregated_payloads=merged_store.latest_known_aggregated_payloads,
465466
)
466467

467-
# Sign everything
468-
#
469-
# Aggregate signatures for attestations in the block body.
470-
# Sign the block root with the proposer's proposal key.
471-
attestation_signatures_blob = key_manager.build_attestation_signatures(
472-
final_block.body.attestations,
473-
attestation_signatures,
474-
)
475-
476468
proposer_signature = key_manager.sign_block_root(
477469
proposer_index,
478470
spec.slot,
@@ -483,7 +475,7 @@ def _build_block_from_spec(
483475
return SignedBlock(
484476
block=final_block,
485477
signature=BlockSignatures(
486-
attestation_signatures=attestation_signatures_blob,
478+
attestation_signatures=AttestationSignatures(data=block_proofs),
487479
proposer_signature=proposer_signature,
488480
),
489481
)
@@ -552,7 +544,7 @@ def _build_attestations_from_spec(
552544
key_manager: XmssKeyManager,
553545
) -> tuple[
554546
list[Attestation],
555-
Mapping[AttestationData, Mapping[ValidatorIndex, Signature]],
547+
dict[AttestationData, dict[ValidatorIndex, Signature]],
556548
set[Attestation],
557549
]:
558550
"""
@@ -578,7 +570,7 @@ def _build_attestations_from_spec(
578570

579571
parent_state = store.states[parent_root]
580572
attestations = []
581-
signature_lookup: Mapping[AttestationData, Mapping[ValidatorIndex, Signature]] = {}
573+
signature_lookup: dict[AttestationData, dict[ValidatorIndex, Signature]] = {}
582574
valid_attestations: set[Attestation] = set()
583575

584576
for aggregated_spec in spec.attestations:

packages/testing/src/consensus_testing/test_keys/test_scheme/0.json

Lines changed: 4 additions & 4 deletions
Large diffs are not rendered by default.

packages/testing/src/consensus_testing/test_keys/test_scheme/1.json

Lines changed: 4 additions & 4 deletions
Large diffs are not rendered by default.

packages/testing/src/consensus_testing/test_keys/test_scheme/10.json

Lines changed: 4 additions & 4 deletions
Large diffs are not rendered by default.

packages/testing/src/consensus_testing/test_keys/test_scheme/11.json

Lines changed: 4 additions & 4 deletions
Large diffs are not rendered by default.

packages/testing/src/consensus_testing/test_keys/test_scheme/2.json

Lines changed: 4 additions & 4 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)