Skip to content

Remove wormhole turnstile (soundness counters and address reveal) - #645

Merged
illuzen merged 2 commits into
mainfrom
illuzen/no-turnstile
Aug 7, 2026
Merged

Remove wormhole turnstile (soundness counters and address reveal)#645
illuzen merged 2 commits into
mainfrom
illuzen/no-turnstile

Conversation

@illuzen

@illuzen illuzen commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Remove the wormhole turnstile

Summary

Removes the wormhole "turnstile" — the soundness counters (PotentialWormholeBalance, TotalWormholeExits) and the ambiguous-address reveal machinery built around them. The mechanism capped cumulative wormhole exits at an estimate of what could plausibly have been deposited, but since the estimate had to conservatively include every zero-nonce account, it only rate-limited a soundness attacker rather than stopping one. That guarantee was not worth the complexity it spread across five pallets and the runtime.

Net effect: -1,622 / +112 lines across 22 files.

What is removed

  • pallet-wormhole: the two counters, the exits <= potential_balance check in process_exit_bundle, the SoundnessInvariantViolation error, the ambiguous-address heuristic (is_ambiguous_account), the reveal_account / reduce_potential_balance helpers, and the NonWormholeAccounts config item.
  • qp-wormhole primitives: reveal_address is dropped from the TransferProofRecorder trait; the AddressRevealer trait is deleted.
  • pallet-multisig: no longer reveals newly created multisig addresses; its ProofRecorder config item and qp-wormhole dependency are removed, along with the is_multisig helper (only used by the reveal heuristic).
  • pallet-utility: the KnownDerivatives storage and reveal-on-first-use logic in as_derivative are removed, along with the AddressRevealer config item and qp-wormhole dependency.
  • Runtime: WormholeProofRecorderExtension no longer does nonce sniffing, balance capture, or reveals in validate/prepare — it now only counts transfers for weight and records proofs from events in post_dispatch. The NonWormholeAccounts wiring in configs is gone.
  • Docs: docs/wormhole-soundness-detection-plan.md (described the removed mechanism) is deleted.

What is NOT affected

Transfer-proof recording is untouched. Proofs are recorded event-driven by the extension's post_dispatch (covering direct transfers, batches, derivatives, and multisig executions alike), plus the direct call sites that run outside signed transactions: mining-reward mints, scheduled reversible transfers, genesis endowments, and exit-bundle mints. Multisig's removed ProofRecorder was used solely for the reveal call, which never produced a proof.

Migration

  • Wormhole storage version bumped to v2; a VersionedMigration (v1 -> v2) deletes the two counter keys. It replaces the old v0 -> v1 seed migration in the runtime migration tuple.
  • KnownDerivatives entries in pallet-utility are left as harmless orphaned keys rather than paying for a multi-block sweep.
  • spec_version bumped 140 -> 141.

Weights

Reads/writes charged for the removed storage operations are dropped:

  • create_multisig: 2 fewer reads, 1 fewer write (reveal lookup + counter update).
  • as_derivative: no longer charges the KnownDerivatives read/write or reveal.
  • Mining rewards base weight: 3 fewer reads and 3 fewer writes.
  • The extension's per-transfer weight no longer includes counter updates, and its base weight is now zero.

Testing

  • cargo check --tests and --features runtime-benchmarks clean for all touched crates.
  • Full suites pass: wormhole (59), multisig (56), reversible-transfers (48), utility (35), mining-rewards (29), runtime (28 unit + 28 integration).
  • New test migration_removes_soundness_counters verifies the v2 migration deletes both counter keys.
  • Tests that existed only to exercise the turnstile (reveal semantics, counter accounting, invariant-violation rejection) are removed.

The PotentialWormholeBalance / TotalWormholeExits counters and the
ambiguous-address reveal machinery only rate-limited a soundness
attacker rather than stopping one, at considerable complexity. Strip
the mechanism from pallet-wormhole, the qp-wormhole traits, multisig,
utility, and the runtime extension; add a v1->v2 migration that deletes
the counters from storage. Bumps spec_version to 141.

Co-authored-by: Cursor <cursoragent@cursor.com>

@n13 n13 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The branch is not rustfmt-clean, so the required 🏁 Fast Checks (Format) job fails and prevents the build/test and Clippy jobs from running.

cargo +nightly fmt --all -- --check reproduces formatting diffs in:

  • pallets/wormhole/src/lib.rs around the storage-version documentation
  • runtime/src/transaction_extensions.rs in the as_derivative weight assertion

Please run the formatter and update the branch.

@n13 n13 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approved — the formatting blocker is resolved, and no blocking findings remain.

Validation:

  • cargo +nightly fmt --all -- --check passes at 0a5a59f6.
  • Focused suites across the touched pallets and runtime passed: 255 tests passed, 4 ignored.
  • cargo check -p quantus-runtime --features runtime-benchmarks passed.
  • cargo check -p quantus-runtime --features try-runtime passed.

Fresh GitHub CI is queued; this approval is based on the equivalent local validation above.

@illuzen
illuzen merged commit 29cc9b4 into main Aug 7, 2026
5 checks passed
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