feat(consensus): BLS endorsement sender + wire format (IIP-52)#4842
feat(consensus): BLS endorsement sender + wire format (IIP-52)#4842envestcc wants to merge 2 commits into
Conversation
…te (IIP-52) Scaffolding for the BLS signature aggregation work tracked in IIP-52. No behavior change yet: EnableBLSAggregation is gated on IsToBeEnabled, and the BLS keys plumbed into rollDPoSCtx are not yet used to sign or verify endorsements. - blockchain/config.go: add Chain.BLSProducerPrivKey (comma-separated hex) and BLSProducerPrivateKeys(). Empty value falls back to deriving each BLS key from the corresponding ECDSA producer key via crypto.GenerateBLS12381PrivateKey. - consensus/scheme/rolldpos: Builder.SetBLSPriKey; NewRollDPoSCtx accepts []*crypto.BLS12381PrivateKey aligned 1:1 with producer ECDSA keys; rollDPoSCtx stores them on blsPriKeys for the upcoming signing path. - consensus/consensus.go: wire SetBLSPriKey(cfg.Chain.BLSProducerPrivateKeys()). - action/protocol/context.go: FeatureCtx.EnableBLSAggregation gated on g.IsToBeEnabled(height); flips to a named hardfork height later. - go.mod: bump iotex-proto to envestcc/iotex-proto bls-aggregate (52e72a6) for the BlockFooter aggregated_signature / signer_bitmap fields and the BLSEndorsement message. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
I think there is no need to add a new BLSEndorsement; we can simply continue using Endorsement. The length of the signature should be sufficient to distinguish whether it is a BLS or an ECDSA signature. This way, many parts of the code would not need to be modified.
9080cc1 to
73e2d57
Compare
|
Refactored per the review suggestion — force-pushed
Dropped:
Also amended iotex-proto PR #169 to drop the standalone Diff size: 12 files / +396 → 6 files / +147. Build and 15 targeted tests still green. (I tried to update the PR body to reflect this too, but GitHub's GraphQL keeps 5xx'ing on edits — sorry for the stale description until that clears.) |
| return msgs, nil | ||
| } | ||
|
|
||
| // newBLSEndorsements signs the consensus vote with each producer's BLS key |
There was a problem hiding this comment.
Is it necessary to separate a new BLSEndorsements method, or can we directly modify the existing newEndorsement method?
Switches consensus vote signing to BLS12-381 post-fork, reusing the existing Endorsement type and dispatching on signature length (65B secp256k1 vs 96B BLS). Receiver verification and endorsement-manager quorum integration land in a follow-up PR; with the feature gate parked at IsToBeEnabled this commit is dead code in production. - endorsement.EndorseBLS / VerifyBLSEndorsement: thin helpers that produce / verify a regular *Endorsement whose signature field carries a BLS sig. Endorser remains the delegate's secp256k1 producer key so the existing Endorser().Address() path still resolves the iotex address; receivers look up the BLS verifying key from candidate state by that address. - ConsensusConfig.BLSAggregationEnabled(height): feature gate wired off Genesis.ToBeEnabledBlockHeight. Will be re-pointed at a named hardfork height once the full Phase-2 stack lands. - rollDPoSCtx.newEndorsement / endorseBlockProposal: post-fork, sign PROPOSAL, LOCK and COMMIT votes plus the proposer's wrapping endorsement with BLS (skipping delegates without a configured BLS key). Block header signing remains on the ECDSA producer key — that signature ties the block to chain identity and is unrelated to the consensus vote layer. - The proposer's producerKey (ECDSA + BLS + address) is threaded through Proposal / mintNewBlock / endorseBlockProposal so the branch can pick the right key without a separate lookup. - iotex-proto bump to envestcc/iotex-proto@e4439ef (PR iotexproject#169): clarifies Endorsement.signature semantics (pre-fork 65B secp256k1, post-fork 96B BLS, distinguished by length). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
73e2d57 to
ef3235d
Compare
|
Done in |
|



Depends on #4841 — stacked on top of the BLS key plumbing PR. Once #4841 merges, this PR's diff will collapse to just the new changes.
Sender + wire-format half of the BLS signature aggregation work tracked in IIP-52. Receiver verification + endorsement-manager quorum integration land in a follow-up PR; with the feature gate parked at `IsToBeEnabled` this PR is dead code in production.
What's in (new vs. #4841)
What's deferred to the follow-up PR
Why all three topics, not just COMMIT
The original IIP-52 motivation (compress the on-chain footer) only requires aggregating COMMIT votes. Implementation-wise though, keeping PROPOSAL/LOCK on ECDSA while COMMIT runs on BLS creates a mixed-mode coupling at the lock check: a delegate that emitted COMMIT (BLS) but not PROPOSAL still counts toward locking, but the proof-of-lock would then need to carry mixed-type entries on the wire. Switching all three topics to BLS post-fork keeps the lock check / proof-of-lock paths uniform and leaves room for future LOCK aggregation in BlockProposal relay (`bls_endorsements` field would then aggregate). The CPU cost (extra ~36 ms verify per 5-second round) is negligible.
Test plan
🤖 Generated with Claude Code