Skip to content

feat: miner aggregation support#560

Draft
ethan-crypto wants to merge 12 commits intomainfrom
miner-aggr
Draft

feat: miner aggregation support#560
ethan-crypto wants to merge 12 commits intomainfrom
miner-aggr

Conversation

@ethan-crypto
Copy link
Copy Markdown
Contributor

@ethan-crypto ethan-crypto commented May 8, 2026

Summary

Adds delegated Wormhole L1 aggregation support to the chain through a new pallet-miner-aggregation, plus Wormhole nullifier locking and L1 verification/settlement helpers.

The new flow allows users to submit bounded L0 aggregate proof candidates, lets registered and bonded aggregation miners claim compatible bundles, locks bundle nullifiers while delegated L1 proving is in progress, and settles exits/rewards once a valid L1 aggregate proof is submitted.

What changed

Miner aggregation pallet

  • Adds pallet-miner-aggregation for delegated L1 aggregation.
  • Supports L0 candidate submission with reserved storage bonds, validity bonds, and aggregation tips.
  • Adds aggregator registration, update, and unregister flows with reward addresses, bonds, and active job limits.
  • Adds bundle claiming for compatible L0 candidates grouped by BundleGroupKey.
  • Locks candidate nullifiers on bundle claim through pallet-wormhole.
  • Supports bundle timeout handling that unlocks nullifiers, releases/slashes miner bonds, and requeues or expires candidates as appropriate.
  • Adds L1 aggregate proof submission and settlement.
  • Adds challenge flows for invalid pending candidates and invalid candidates already included in a claimed bundle.
  • Adds slashing paths for miner timeouts, invalid L1 proof submissions, and invalid bundled claims.
  • Adds challenger rewards for invalid L0 candidates.
  • Pays aggregation rewards through candidate tips and a configurable delegated L1 prover fee share.

Wormhole settlement and nullifiers

  • Adds LockedNullifiers state to pallet-wormhole.
  • Adds helpers to lock, unlock, validate, and consume nullifiers assigned to aggregation bundles.
  • Updates direct L0 settlement so it rejects nullifiers that are already used or currently locked by a bundle.
  • Adds helpers for deserializing, parsing, and verifying L1 aggregate proofs.
  • Refactors public output settlement into prepare/apply steps so delegated L1 settlement can reuse the same settlement logic safely.
  • Adds delegated L1 fee-share handling while preserving existing direct L0 settlement fee behavior.

Runtime and workspace wiring

  • Adds the miner aggregation pallet to the workspace.
  • Wires MinerAggregation into the runtime.
  • Updates runtime configuration for candidate limits, proof sizes, candidate lifetime, bundle proving period, miner bonds, slashing rates, challenge rewards, active bundle limits, and delegated prover rewards.
  • Pins qp-zk-circuits dependencies to the matching delegated L1 aggregation revision so chain, miner, and circuit artifacts stay aligned.

Tests, fixtures, and docs

  • Adds tests covering:
    • candidate submission and queueing
    • bundle claim and nullifier locking
    • direct L0 settlement rejection once nullifiers are locked
    • bundle timeout and requeue/refund behavior
    • atomic rollback on failed settlement
    • registered reward address enforcement
    • aggregator lifecycle and bond handling
    • delegated L1 fee sharing
    • timeout, invalid proof, and invalid claim slashing
    • challenge handling for invalid pending and bundled candidates
    • L1 aggregate effect validation
    • fixture-backed positive L1 settlement
  • Adds delegated L1 fixture data.
  • Adds scripts for delegated L1 fixture generation and local E2E validation.
  • Adds documentation for the delegated L1 aggregation protocol, dependency strategy, runtime weight status, MVP limitations, and release-mode fixture requirements.

*Enables staged miner aggregation in the runtime and uses matching circuit artifacts for bundled proof generation and verification.

*Improves settlement safety by locking nullifiers while bundles are assembled, rejecting duplicates and reused inputs, and adding optional layer-1 verifier support for multi-stage aggregation.
@ethan-crypto ethan-crypto marked this pull request as draft May 8, 2026 06:13
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Identified two security-relevant issues in the miner aggregation flow after module deduplication and manual validation.

Open in Web View Automation 

Sent by Cursor Security Review Agent: Security Reviewer

Comment thread pallets/miner-aggregation/src/lib.rs Outdated
.map_err(|_| Error::<T>::L1ProofRejected)?;

let nullifiers = Self::layer1_nullifier_bytes(&inputs)?;
pallet_wormhole::Pallet::<T>::mark_locked_nullifiers_used(bundle_id, &nullifiers)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Agentic Security Review
Severity: HIGH

submit_l1_aggregate marks locked nullifiers as used before calling settle_public_outputs, but settle_public_outputs can still fail. This creates a partial-state failure path where nullifiers are consumed and locks removed while the bundle remains unsettled.

Impact: A malicious or malformed aggregate can cause persistent bundle liveness failure and strand reserved funds, because timeout recovery later cannot unlock already-removed nullifier locks.

pub fn claim_bundle(
origin: OriginFor<T>,
group_key: BundleGroupKey,
aggregator_address: [u8; 32],
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Agentic Security Review
Severity: MEDIUM

claim_bundle accepts caller-supplied aggregator_address and stores it directly in the bundle without enforcing equality to the miner’s registered reward_address. Settlement payouts are later derived from this bundle value.

Impact: A registered miner (or compromised claiming key) can redirect candidate aggregation tips away from the configured registered reward destination, breaking the intended payout-boundary invariant.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit af0ea93. Configure here.

);
Self::deposit_event(Event::AggregatorRegistered { account });
Ok(())
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-registration permanently locks previously reserved aggregator bond

Medium Severity

register_aggregator unconditionally overwrites any existing RegisteredAggregators entry without unreserving the previously held bond. If a registered aggregator calls this again, the old reserved bond is permanently locked (no unreserve path exists), and active_jobs resets to 0, making the counter inconsistent with MinerActiveBundles storage. There is no unregister/withdraw function to recover the stranded funds.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit af0ea93. Configure here.

}

Ok(total_exit_amount)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated settlement logic risks future inconsistent patches

Low Severity

settle_public_outputs duplicates ~100 lines of complex financial logic (fee calculation, minting, burning, transfer recording) already present inline in verify_aggregated_proof. Both paths compute fees, mint to exit accounts, pay block author, and burn. A bug fix applied to one but not the other would create a divergence in money-handling behavior.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit af0ea93. Configure here.

*Adds transactional execution around bundle and proof flows so failed settlement rolls back cleanly instead of leaving partial state behind.

*Refactors public output settlement into prepare/apply steps, validates locked nullifiers before consuming them, and keeps locks, claim status, and active job tracking intact when post-verification settlement fails.

*Improves fee and amount validation with safer arithmetic and adds regression tests for rollback behavior and settlement preparation.
*Rejects invalid or mismatched reward addresses so bundles, proofs, and payouts stay bound to the address registered by the aggregator.

*Prevents silent fallback to the miner account during settlement, tightens proof validation against the claimed reward destination, and adds coverage for rejection and payout paths.
*Adds update and unregister flows so registration changes can safely resize or release reserved funds instead of leaving old bond amounts locked.

*Blocks registration changes while work is still active and verifies active-job accounting after claim, timeout, and settlement to catch inconsistent state early.
*Rewards delegated L1 aggregation with a configurable share of non-burned volume fees, so prover incentives are paid as part of settlement instead of relying only on tips.

*Emits settlement and reward events for better accounting, keeps direct settlement fee behavior unchanged, and preserves burn handling when no block author is available.
*Adds configurable slashing and challenger rewards so timeouts, invalid proof submissions, and invalid claims are penalized instead of simply releasing reserved funds.

*Allows invalid candidates to be challenged even after bundling, which restores unaffected work safely by unlocking nullifiers, re-queueing valid leftovers, and keeping miner job accounting consistent.

*Updates runtime parameters, events, weights, and tests to cover the new dispute and penalty flow.
*Adds stronger MVP checks so settlement rejects mismatched exits, nullifiers, reordered effects, and inconsistent exit slot counts.

*Clarifies that the bundle root remains metadata until the L1 circuit constrains it, and adds focused tests to lock in the intended verification behavior.
*Verifies successful aggregate settlement against real L1 fixtures so the positive path no longer relies on cheap rejection checks alone.

*Adds targeted mismatch cases to catch metadata drift before settlement and protect balance, bond, and nullifier handling.

*Updates testing notes to document release-mode fixture generation and the environment needed to run the L1 proof path.
*Pins the ZK circuit dependencies to an exact revision so downstream builds stay reproducible and aligned across related repos during delegated aggregation work.

*Clarifies MVP limitations and the current dependency strategy, and documents that runtime weights are conservative placeholders rather than benchmark output.

*Splits aggregate submission estimates by cheap-reject vs valid-proof paths and keeps the dispatchable on the safe upper bound until real benchmarks replace the placeholders.
*Ensures tests verify settlement inputs stay available before a bundle is claimed, then become locked once claimed.

*Prevents regressions where direct settlement could proceed after claim and strengthens coverage around bundle state transitions.
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.

1 participant