Devnet4 Phase 1: dual-key Validator, SignedBlock, genesis config format#230
Devnet4 Phase 1: dual-key Validator, SignedBlock, genesis config format#230pablodeymo wants to merge 1 commit intodevnet4from
Conversation
Introduce the devnet4 type-level changes:
- Validator: single pubkey → attestation_pubkey + proposal_pubkey with
get_attestation_pubkey() and get_proposal_pubkey() methods
- SignedBlockWithAttestation → SignedBlock (message is Block directly)
- Delete BlockWithAttestation and BlockSignaturesWithAttestation wrappers
- Genesis config: GENESIS_VALIDATORS changes from list of hex strings to
list of {attestation_pubkey, proposal_pubkey} objects
- Test fixtures: Validator deserialization updated for dual pubkeys
NOTE: This is SSZ-breaking. Downstream crates will not compile until
subsequent phases update all call sites.
🤖 Kimi Code ReviewReview SummaryThis PR introduces dual-key validator structure (attestation + proposal keys) and refactors block signing accordingly. The changes are well-structured and address the OTS constraint issue. Issues Found
Positive Aspects
Minor Suggestions
impl Validator {
pub fn new(attestation_pubkey: ValidatorPubkeyBytes, proposal_pubkey: ValidatorPubkeyBytes, index: u64) -> Result<Self, DecodeError> {
// Validate both keys
let _ = ValidatorPublicKey::from_bytes(&attestation_pubkey)?;
let _ = ValidatorPublicKey::from_bytes(&proposal_pubkey)?;
Ok(Self { attestation_pubkey, proposal_pubkey, index })
}
}
Overall, the PR correctly implements the dual-key validator design and simplifies the block structure appropriately. Automated review by Kimi (Moonshot AI) · custom prompt |
🤖 Claude Code ReviewReview: Devnet4 Phase 1 — Dual-key Validator, SignedBlock, Genesis ConfigThis is a clean structural PR. The motivation (OTS key separation) is sound, and the deletions (removing the CorrectnessIncomplete test coverage in The test verifies // Missing:
assert_eq!(config.genesis_validators[1].proposal_pubkey, hex::decode(PROP_PUBKEY_B)...);
assert_eq!(config.genesis_validators[2].proposal_pubkey, hex::decode(PROP_PUBKEY_C)...);Duplicate constant values in test data (
Weakened state root pin ( Replacing the exact hash assertion with a non-zero check is understandable for a non-compiling PR. However, the comment says "Will be recomputed once we can run this test" without a tracking mechanism. A Minor / Non-blockingError message quality regression in The old What looks good
Automated review by Claude (Anthropic) · custom prompt |
🤖 Codex Code Review
I could not run Automated review by OpenAI Codex · custom prompt |
Motivation
First of 4 PRs implementing devnet4 (leanSpec#449). This PR introduces the SSZ-breaking type changes that all subsequent phases depend on.
Description
Validator struct: single pubkey → dual pubkeys
Each validator now has two independent XMSS keys — one for attestation signing and one for block proposal signing. This eliminates OTS conflicts when a proposer needs to sign both a block and an attestation in the same slot.
get_pubkey()→get_attestation_pubkey()+get_proposal_pubkey()Block types: remove proposer attestation wrapper
Genesis config format
Test fixtures
Validatordeserialization updated for dual pubkeys (attestationPubkey, proposalPubkey)PR chain
devnet4-phase2-proposal)devnet4-phase3-store)devnet4-phase4-network)How to Test
This PR alone does not compile (SSZ-breaking). Full compilation requires all 4 phases merged.