feat: harden batch-sender (pause, admin, typed errors, multisig) - #175
Conversation
|
Thanks @Eltimios. The
Worth flagging the bigger picture too. Issue #155 is the L-tier hardening pass: That is fine if it is early, just push the rest before marking it ready. If any part of the scope is unclear, particularly the multisig rotation, ask here and I will point you at the exact pattern to copy. |
…ith-protocol#155) Adds init(admin, announcer, asset_policy), admin-gated pause/unpause/is_paused, and the BatchSenderError enum (codes 1300-1316, reserved range per ERRORS.md) replacing every panic! in batch_send. Verified locally: 9 unit tests in src/test.rs pass. Multisig, tests, and docs land in follow-up commits to this same PR.
This module implements an on-chain multi-sig quorum and timelock signer-rotation flow, allowing governance signers to propose new signer sets and thresholds, requiring quorum approval and a timelock before execution.
|
@Eltimios Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
…ith-protocol#155) Added production-hardening acceptance tests for stealth-batch-sender, covering various scenarios including initialization, pause/unpause functionality, and error handling for batch sending.
…th-protocol#155) Updated the On-Chain Signer Rotation section to include 'stealth-batch-sender' and clarify governance details.
This document serves as a comprehensive catalog of error codes for Stellar contracts, detailing their meanings and the contracts they belong to. It includes information on code allocation policies and existing error codes across various contracts.
|
@truthixify — you're right, and thanks for catching it. That first push had One open design question I'd like your read on: Also flagging: |
Added a comment to trigger CI validation for error catalog.
Added comments to trigger CI validation for error catalog.
|
Quick heads-up on CI status for this PR: the last three pushes ( The most recent real result (run #283, on Since three consecutive pushes failed to dispatch a run at all, this looks like a repo/org-level Actions issue (possibly a spending limit or quota) rather than random bad luck — worth a maintainer checking Settings → Actions and Settings → Billing when convenient. Happy to push again once that's sorted, or someone with admin access can just re-run manually. |
…-protocol#155) The production-hardening pass added a required init(admin, announcer, asset_policy) flow. batch_send now returns NotInitialized until init() is called, which broke the chaos harness test. Call init() after registering the contract so batch_send runs as intended.
…raith-protocol#155) measure_batch now calls init(admin, announcer, asset_policy) before batch_send, matching the new required-init flow, and the regenerated bench data reflects the added init/pause checks.
|
Merged, and thank you for turning this around properly @Eltimios. |
|
It’s a pleasure working on this issue @truthixify
|
Overview
This PR completes the production-hardening pass for
stealth-batch-sender(issue #155): a one-timeinit(admin, announcer, asset_policy)flow, admin-guardedpause/unpause/is_paused, a typedBatchSenderErrorsurface replacing every rawpanic!in the contract, and a 7-day timelocked signer-rotation flow (propose_/approve_/execute_/cancel_rotate_signers) mirroringstealth-sender.batch_sendremains withdrawal-free and is now guarded byrequire_not_paused().Note on history: an earlier push to this branch contained placeholder
TODOtext instead of real code in several files (caught by @truthixify's review — thank you for flagging it). Everything below reflects what's actually implemented and locally tested as of the latest commits, not what an earlier, inaccurate version of this description claimed.Related Issue
Closes #155.
Changes
🛡️ Production-Hardening Core —
stellar/stealth-batch-sender/src/lib.rsinit(admin, announcer, asset_policy)withAlreadyInitializedtyped error.Pausedstorage plus admin-guardedpause,unpause, andis_paused, mirroring thestealth-senderpattern.panic!with aBatchSenderErrorenum (codes1300-1316, the range reserved for this contract inERRORS.md).batch_sendwithrequire_not_paused(); no withdrawal path exists in this contract, so nothing was left unguarded.announceris stored atinitbut not yet invoked bybatch_send(which still emits its own directANNOUNCEevent, unchanged from the original). Wiring in an announcer-contract call would be a new on-chain integration — flagging it rather than adding it silently.🔐 Signer-Set Multisig Rotation —
stellar/stealth-batch-sender/src/multisig.rsstealth-sender/src/multisig.rsshape for signer-set storage and validation.propose_rotate_signers,approve_rotate_signers,execute_rotate_signers,cancel_rotate_signers, with a 7-day timelock (ROTATION_TIMELOCK_SECS).🧪 Tests
stellar/stealth-batch-sender/src/test.rs— rewritten to 9 result-based tests (try_*+Err(Ok(...))assertions) instead of#[should_panic], matching the new typed-error surface.stellar/stealth-batch-sender/tests/production.rs(new) — 20 acceptance tests covering init idempotency, pause/unpause + paused-call rejection, the full typed-error surface (including asset-policy allow/deny), and signer-rotation happy + adversarial paths.cargo fmt --all --check.📄 Docs
stellar/PAUSE.md— batch-sender added to the pause support matrix and guarded-surface list.stellar/MULTISIG.md— batch-sender added to the on-chain signer-rotation section.stellar/ERRORS.md(new on this fork) — full error-code catalog including the1300-1316batch-sender range. Heads up: GitHub is showing a merge conflict on this file againstwraith-protocol:develop— this fork was behind upstream and didn't haveERRORS.mdat all until this PR added it, so it'll need reconciling with upstream's copy before merge.Known gaps — not yet done
I don't have a working
wasm32-unknown-unknownRust toolchain in the environment I used to prepare this, so the following from the original acceptance criteria are not complete, and I didn't want to fabricate numbers for them:stellar/SIZE.mdentry yet).stellar/abi/stealth_batch_sender.json).stellar/bindings/typescript/stealth-batch-sender/).These correspond to CI's wasm-build/size-check/ABI-snapshot/bindings steps, which are
continue-on-error: truein.github/workflows/ci.ymlper the existing soroban-sdk/rustc compatibility note, so they won't block CI — but they should still be done before merge. Commands to run once a working toolchain is available:rustup target add wasm32-unknown-unknown stellar contract build --package stealth-batch-sender stellar contract optimize --wasm target/wasm32-unknown-unknown/release/stealth_batch_sender.wasm # then update stellar/SIZE.md, stellar/abi/stealth_batch_sender.json, and regenerate TS bindingsVerification Results
Hardening acceptance check: