Skip to content

feat(parsigex): add eth2-based partial signature verifier#511

Merged
emlautarom1 merged 4 commits into
mainfrom
emlautarom1/parsigex-eth2-verifier
Jul 1, 2026
Merged

feat(parsigex): add eth2-based partial signature verifier#511
emlautarom1 merged 4 commits into
mainfrom
emlautarom1/parsigex-eth2-verifier

Conversation

@emlautarom1-agent

@emlautarom1-agent emlautarom1-agent Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements eth2 signature verification for inbound partial signatures in parsigex, so a peer's partial signatures are cryptographically validated before they are accepted into the partial-signature database.

What it implements

  • parsigex::new_eth2_verifier(eth2_cl, pub_shares_by_key) -> Verifier — for each inbound partial signature received for a validator, looks up the sender's public share by the signature's share index and verifies the eth2 BLS signature via pluto_core::verify_eth2_signed_data. Partial signatures with an unknown validator public key or an unknown share index are rejected.
  • Adds pluto-eth2api and promotes pluto-crypto to runtime dependencies of parsigex, to name the beacon node client and the public-share type.

Ports Charon's core/parsigex/parsigex.go NewEth2Verifier. Part of #402.

Testing

Accept/reject unit tests using a mocked beacon node and threshold BLS shares: a valid partial signature against the correct share verifies, while a wrong share, an unknown public key, and a missing share index are each rejected.

Adds parsigex::new_eth2_verifier built on pluto_core::verify_eth2_signed_data (core/eth2signeddata, #501), porting Charon's parsigex.NewEth2Verifier: each inbound partial signature is verified against the sender's public share, looked up by the partial sig's share index. Adds pluto-eth2api and promotes pluto-crypto to a runtime dependency of parsigex (to name the beacon client + pubshare type).
@emlautarom1-agent emlautarom1-agent Bot force-pushed the emlautarom1/parsigex-eth2-verifier branch from e51cdf5 to e8b009e Compare June 30, 2026 20:44
@emlautarom1-agent emlautarom1-agent Bot changed the base branch from emlautarom1/core-eth2-verify to main June 30, 2026 20:44
- Use qualified imports
- Simplify docs
@emlautarom1 emlautarom1 marked this pull request as ready for review June 30, 2026 22:09
- Preserves duty information
@NethermindEth NethermindEth deleted a comment from claude Bot Jun 30, 2026
The function lives in the `eth2signeddata` module, which is only in
scope as a module path, so the bare link did not resolve. Qualify it
with the module path.
@emlautarom1

Copy link
Copy Markdown
Collaborator

@claude

@claude

claude Bot commented Jun 30, 2026

Copy link
Copy Markdown

Claude finished @emlautarom1's task in 1m 55s —— View job


Code Review — eth2-based partial signature verifier

  • Read the PR diff and changed files
  • Compare against Charon NewEth2Verifier
  • Review correctness, error handling, tests
  • Post review feedback

Overall this is a clean, faithful port of Charon's core/parsigex/parsigex.go NewEth2Verifier. The check ordering (unknown pubkey → invalid share index → eth2 type assertion → BLS verification) matches the Go source exactly, the type mapping is sound (Index = u64 and ParSignedData::share_idx: u64 line up with Go's map[int]), and the error model is a genuine improvement over the original Other(String) placeholder. Nice work. A few notes below — all minor.

Correctness — looks good ✅

  • crates/parsigex/src/behaviour.rs:71-89 mirrors Charon 1:1. The as_eth2_signed_data upcast correctly stands in for Go's data.(core.Eth2SignedData) type assertion, and the comment explaining that mapping is appreciated.
  • Dropping the fallible constructor return (Go returns (func, error) but never errors) is the right call.
  • Arc-cloning eth2_cl and pub_shares_by_key per invocation is correct and cheap.

Suggestions (non-blocking)

  1. Missing test for the InvalidSignedDataFamily path. The tests cover accept / wrong-share / unknown-pubkey / missing-share-index, but not the case where signed_data is not an eth2 signed-data variant (e.g. a raw Signature). Since as_eth2_signed_data is the one branch unique to this verifier that isn't exercised, a small test passing a non-eth2 ParSignedData and asserting VerifyError::InvalidSignedDataFamily would close the matrix. Fix this →

  2. Duty embedded in VerifyError::InvalidSignature. This faithfully reproduces Charon's z.Str("duty", duty.String()) log context, and reads well. Just note the only current consumer (handler.rs:265) collapses it via e.to_string() into Failure::InvalidPartialSignature(String), so the structured duty/source fields aren't accessed programmatically yet — the value is purely in the Display output today. Fine as-is, but worth being aware of if anyone expects to match on it.

Nits

  • crates/parsigex/Cargo.toml: promoting pluto-crypto to a runtime dep and adding pluto-eth2api (runtime) / pluto-eth2util (dev) is correct and matches usage.
  • Doc comment on new_eth2_verifier is thorough and the intra-doc links resolve.

I could not run cargo test/clippy in this environment (the commands require approval here), so I reviewed by inspection — please rely on CI for the build/lint gates.
emlautarom1/parsigex-eth2-verifier

@emlautarom1 emlautarom1 merged commit 8c6325c into main Jul 1, 2026
12 checks passed
@emlautarom1 emlautarom1 deleted the emlautarom1/parsigex-eth2-verifier branch July 1, 2026 12:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants