Add Vesting CLI/exercise support and bump crypto deps for chain branch - #129
Conversation
Regenerate metadata against the Vesting-enabled runtime, add quantus vesting commands plus an exercise phase covering create/claim/retarget/end via the treasury multisig, and align poseidon/rusty-crystals/zk-circuits with chore/bump-crypto-deps-2026-08 (path dilithium-crypto + git zk-circuits). Co-authored-by: Cursor <cursoragent@cursor.com>
New wallets default to ml-dsa-65 via --scheme, legacy wallets without a stored scheme stay on 87, and exercise now signs with both schemes. Co-authored-by: Cursor <cursoragent@cursor.com>
Box QuantusSigner variants, use is_multiple_of for scheme selection, and allow dead_code on SDK convenience wrappers unused by the CLI binary. Co-authored-by: Cursor <cursoragent@cursor.com>
n13
left a comment
There was a problem hiding this comment.
Verdict: REQUEST CHANGES — the latest head still has a broken supported-runtime path, deterministic test failures, and unsafe failure handling in the new exercise/vesting code.
Findings (highest severity first):
-
[P1] Default ML-DSA-65 wallets cannot transact on runtimes this CLI still declares compatible (
src/config/mod.rs:17-20,src/cli/wallet.rs:48-50,src/chain/client.rs:350-368). Specs 134-136 expose the legacy one-variant signature enum (variant 0, ML-DSA-87), while this PR defaults newly created/imported wallets to ML-DSA-65 and encodes that as variant 1. The runtime gate accepts those nodes, wallet creation succeeds, and then every signed transaction from the default wallet is rejected as an undecodable signature. Either remove the old runtime pairs, retain ML-DSA-87 as the default until they are removed, or explicitly prevent ML-DSA-65 submission to pre-142 runtimes; cover the selected compatibility contract in tests. -
[P1] The required test matrix is red at this head (
src/cli/wormhole.rs:4541,src/cli/wormhole.rs:4655). The 4-bps change makes the medium fee result 9996, but the test still requires 9990. The new source-inspection guard also rejects the legitimateTransactionStage::Finalizednormalization branch inside the_untilsubmitters.SKIP_CIRCUIT_BUILD=1 cargo test --locked --lib cli::wormhole::tests::reproducibly reports 35 passed / 2 failed, and the Ubuntu build-and-test CI job is now failed. Update both assertions so the checked-in suite validates the intended behavior and passes. -
[P2] The wormhole exercise can leave a funded, empty-password wallet behind while hiding cleanup failures (
src/cli/exercise/scenarios/wormhole.rs:30-52). Bothdelete_walletresults are discarded, and the funding transfer uses?before cleanup is installed. A funding/watch error therefore bypasses deletion entirely; a deletion error after the command is also silently ignored. This can leave the deterministic exercise wallet (potentially holding the 500-token funding) on disk and make a later run fail withAlreadyExists. Run cleanup on every post-creation exit and propagate or log any deletion failure. -
[P2] Relative vesting moments overflow instead of failing input validation (
src/cli/vesting.rs:315-320). A syntactically valid large+<seconds>value performs uncheckedseconds * 1_000andnow_ms + offset; it panics with overflow checks and wraps in release builds, producing unrelated call data/timestamps. Usechecked_mulandchecked_addand return an actionableQuantusError.
Validation:
git diff --check 4ddb4ace...459d655— passed.SKIP_CIRCUIT_BUILD=1 cargo clippy --all-targets --locked -- -D warnings— passed.SKIP_CIRCUIT_BUILD=1 cargo test --locked --lib cli::wormhole::tests::— failed: 35 passed, 2 failed at lines 4541 and 4655.- GitHub CI at
459d655: format, analysis/doc, and security-audit jobs passed; Ubuntu build/test failed; macOS and examples were still running at review time.
Keep 134–136 compatible for ML-DSA-87 wallets, but reject default ML-DSA-65 signing against those one-variant signature enums with an actionable error. Co-authored-by: Cursor <cursoragent@cursor.com>
Assert the medium fee output at 9996 and require wait_tx_inclusion to take the normalized stage parameter without forbidding Finalized match-arm passthrough. Co-authored-by: Cursor <cursoragent@cursor.com>
Propagate delete failures and delete even when funding or multiround fails so funded empty-password wallets are not left on disk. Co-authored-by: Cursor <cursoragent@cursor.com>
Use checked_mul/checked_add for +<seconds> parsing so large offsets return QuantusError instead of panicking or wrapping. Co-authored-by: Cursor <cursoragent@cursor.com>
clippy: :items_after_test_module rejects production items after a #[cfg(test)] module. Co-authored-by: Cursor <cursoragent@cursor.com>
n13
left a comment
There was a problem hiding this comment.
Verdict: APPROVE — all four previously reported blockers are resolved on 85fd3bd.
- ML-DSA-65 support is now explicit per compatible runtime, and both shared CLI transaction submission paths reject ML-DSA-65 signers on legacy runtimes with an actionable error while leaving ML-DSA-87 usable.
- The two deterministic wormhole test failures are corrected.
- The exercise wallet is cleaned up on every post-creation exit, with run and cleanup failures both preserved.
- Relative vesting timestamps now use checked multiplication and addition and reject overflow.
Validation:
git diff --check 4ddb4ace...85fd3bd— passed.SKIP_CIRCUIT_BUILD=1 cargo test --locked --lib cli::wormhole::tests::— 37 passed.SKIP_CIRCUIT_BUILD=1 cargo test --locked --lib config::tests::— 9 passed.SKIP_CIRCUIT_BUILD=1 cargo test --locked --lib cli::vesting::tests::— 2 passed.SKIP_CIRCUIT_BUILD=1 cargo clippy --all-targets --locked -- -D warnings— passed.- GitHub CI is green across format, Ubuntu/macOS build and test, analysis/doc, audit, and examples.
No remaining blocking findings.
Summary
info,list,show,claim,create-schedule,end-schedule,retarget), including--call-data-onlyfor routing admin calls through the treasury multisig.vestingphase toquantus exercisethat covers all four extrinsics (permissionless claim, BadOrigin on create, create→claim→reclaim via Alice/Bob/Charlie treasury multisig, retarget→end with pot balance checks).COMPATIBLE_RUNTIMES.chore/bump-crypto-deps-2026-08: poseidon 3.1.0, rusty-crystals 4.1.0, zk-circuits/wormhole 4.2.0 (crates.io), plonky2 1.5.5; temporarily path-depend on the chain’sqp-dilithium-cryptountil a 4.x-compatible release is published.Notes / follow-ups
--upgrade-wasm), but not in the default phase set. Committing a bumped-speccompact.compressed.wasm(~700 KB) and wiring CI is a good next step; the blob must have a higherspec_versionthan the node under test.qp-dilithium-cryptois still apathdep (crates.io 0.5.0 requires rusty-crystals 3.x). Switch to crates.io once a 4.x-compatible dilithium-crypto is published.Test plan
cargo test --release --lib(236 passed)quantus vesting info/listagainst local Vesting-enabled nodequantus exercise --phases vestingagainst local--devnode (7/7 steps)QUANTUS_BINS_DIR=./generated-binswhen run from repo root)main(or the vesting / crypto-bump branch) once those landquantus exercise --upgrade-wasm <bumped-spec.wasm>on a fast-governance node