Skip to content

test: property-based + stateful tests for the Bitcoin-staking surface#7268

Open
simone-stacks wants to merge 46 commits into
stacks-network:pox-wf-integrationfrom
simone-stacks:feat/pox-5-waterfall-proptests
Open

test: property-based + stateful tests for the Bitcoin-staking surface#7268
simone-stacks wants to merge 46 commits into
stacks-network:pox-wf-integrationfrom
simone-stacks:feat/pox-5-waterfall-proptests

Conversation

@simone-stacks

@simone-stacks simone-stacks commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a comprehensive property-based and stateful (madhouse-rs) test layer for the Bitcoin-staking feature surface, with no changes to production behaviour. It covers the Clarity Bitcoin builtins, the sBTC deposit-address derivation, the PoX-5 STX-locking primitives, and the node↔contract dispatch seam.

Additional info (benefits, drawbacks, caveats)

Surface covered

Component Production file(s)
Clarity 6 Bitcoin builtins (verify-merkle-proof, get-bitcoin-tx-output?) clarity/src/vm/functions/bitcoin.rs
Merkle CVE-2012-2459 adversarial machine clarity/src/vm/functions/bitcoin_madhouse.rs
sBTC P2TR (taproot) deposit-script derivation stackslib/src/chainstate/stacks/sbtc.rs
PoX-5 STX-locking primitives + node↔contract dispatch pox-locking/src/pox_5.rs, pox-locking/src/tests/madhouse.rs

What's added

  • Merkle verifier (stateless): roundtrip, tampering of leaf/root/sibling, wrong depth, out-of-range index, zero/cross-tree, the deflated-tx-count collision, and canonical depth vs an independent oracle.
  • Merkle CVE-2012-2459 adversarial machine: honest-proof / forge / tampered-leaf / wrong-depth / out-of-range transitions, plus cross-tree and inflated-tx-count transitions over deep trees, with a global invariant hook (tx_count = 0 and an inflated cross-count rejected for every tree in the pool) re-checked after every command.
  • native_* coercion layer: wrong arity, mis-typed arguments (non-32 buffs, non-uint scalars, non-list siblings), and oversized (>24) siblings lists never panic on consensus input — they return an error or false; plus a randomized buff_to_array::<32> length-rejection property.
  • get-bitcoin-tx-output?: roundtrip, vout out-of-range / u64-overflow → err u2, unparseable bytes → err u1, the script at-cap / over-cap boundary, and the consensus cost-input function.
  • sBTC taproot: 9 byte-for-byte reference fixtures (validated against the sBTC source) plus metamorphic properties — determinism, full injectivity over every input (pubkey, recipient, fee, lock_time, reclaim-script), off-curve-pubkey rejection, wrapper/generic equivalence — and generator-validity properties.
  • PoX-5 locking primitives: per-gate rejection properties (zero amount/height, double-lock, insufficient balance, no-decrease, not-locked, malformed/overflowing responses, and the pox_rollover_v5 gates) with exact error-code assertions (LockingError::as_error_code), plus full-balance boundary acceptance.
  • Node↔contract seam: handle_contract_call → parse_pox_stake_result → pox_lock_v5 / pox_rollover_v5 — the node parsing and applying the contract's stake / lockup / roll-over response (the boundary the companion contract-side effort never reaches).
  • PoX-5 staker-lifecycle madhouse machine: conservation / auto-unlock / monotonic-locking invariants, an auto-unlock-boundary command (advances the burn height to exactly unlock_height, the off-by-one a random walk never lands on), and negative-path (illegal-transition) commands.
  • Adapts the proof synthesizer to the upstream verify-merkle-proof hardening.

Note on P2WSH. An earlier revision of this branch also covered P2WSH watched-output tracking (a third madhouse machine plus watched-output properties). pox-wf-integration has since reverted the P2WSH output-storage feature ("no longer needed in the latest Pstaking design"), so those tests were retired when this branch merged that change.

Companion effort #7245 (PoX-5 Clarity Stateful PBT)

#7245 drives pox-5.clar directly with a fast-check stateful machine (staking lifecycle, signer grants/rotation, bond setup/registration, error branches, standing invariants). The two efforts hit the stack from opposite ends and meet at the Bitcoin builtins:

  • This PR hardens verify-merkle-proof / get-bitcoin-tx-output? at the Rust level (CVE-resistant, panic-free); [DRAFT] PoX-5 Clarity Stateful PBT #7245's register-for-bond L1 path and announce-l1-early-exit sit on top of those builtins in-contract, but simnet can't supply real burn headers, so [DRAFT] PoX-5 Clarity Stateful PBT #7245 covers only the rejection branches (ERR_INVALID_BTC_HEADER, the is-l1-lock gate, etc.); this PR covers the builtins' happy paths the contract layer can't reach.
  • The stake/lockup handoff is checked from both sides: [DRAFT] PoX-5 Clarity Stateful PBT #7245 that the contract produces the right response and lock; this PR that the node parses and applies it.

No overlap; together they cover pox-5 / Bitcoin staking top-to-bottom.

Validation

  • All suites green; both stateful machines also pass under MADHOUSE=1 PROPTEST_CASES=2500.
  • Production functions under test were developed against cargo-mutants; the one real surviving mutant found during review — a node-crash vector in the merkle builtin's buffer coercion (buff_to_array on a short consensus buffer) — is now pinned.

Checklist

  • Test coverage for new or modified code paths
  • For new Clarity features or consensus changes, add property tests (see docs/property-testing.md)
  • Changelog fragment(s) or "no changelog" label added (see changelog.d/README.md)
  • Required documentation changes (e.g., rpc/openapi.yaml for RPC endpoints, event-dispatcher.md for new events)
  • New clarity functions have corresponding PR in clarity-benchmarking repo

@simone-stacks simone-stacks requested a review from radu-stacks June 2, 2026 21:46
@simone-stacks simone-stacks changed the title Feat/pox 5 waterfall proptests test: property-based + stateful tests for the Bitcoin-staking surface Jun 2, 2026
@radu-stacks

Copy link
Copy Markdown
Contributor

@simone-stacks Can you please run cargo fmt-stacks so we can see CI results? 🙏

@simone-stacks

Copy link
Copy Markdown
Contributor Author

@radu-stacks done!

@coveralls

coveralls commented Jun 4, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 27410170590

Warning

Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes.
Quick fix: rebase this PR. Learn more →

Coverage increased (+0.1%) to 86.077%

Details

  • Coverage increased (+0.1%) from the base build.
  • Patch coverage: 14 uncovered changes across 3 files (363 of 377 lines covered, 96.29%).
  • 6698 coverage regressions across 100 files.

Uncovered Changes

File Changed Covered %
clarity/src/vm/functions/bitcoin_madhouse.rs 225 216 96.0%
pox-locking/src/lib.rs 15 11 73.33%
pox-locking/src/pox_5.rs 48 47 97.92%
Total (5 files) 377 363 96.29%

Coverage Regressions

6698 previously-covered lines in 100 files lost coverage.

Top 10 Files by Coverage Loss Lines Losing Coverage Coverage
stackslib/src/chainstate/burn/db/sortdb.rs 575 90.3%
stackslib/src/config/mod.rs 418 69.43%
stackslib/src/net/mod.rs 310 77.9%
stackslib/src/chainstate/stacks/index/storage.rs 277 82.27%
clarity/src/vm/database/clarity_db.rs 259 82.14%
clarity/src/vm/database/structures.rs 248 77.65%
stackslib/src/chainstate/stacks/boot/mod.rs 248 94.21%
stackslib/src/chainstate/stacks/miner.rs 216 83.51%
stackslib/src/burnchains/burnchain.rs 205 72.03%
stackslib/src/chainstate/nakamoto/signer_set.rs 203 70.08%

Coverage Stats

Coverage Status
Relevant Lines: 226648
Covered Lines: 195091
Line Coverage: 86.08%
Coverage Strength: 18634737.84 hits per line

💛 - Coveralls

@radu-stacks radu-stacks left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is a solid piece of work! Leaving here the first round of review comments after thoroughly checking the targeted areas.

Comment thread clarity/src/vm/functions/bitcoin_madhouse.rs
Comment thread pox-locking/src/tests/madhouse.rs Outdated
Comment thread pox-locking/src/pox_5.rs Outdated
Comment thread stackslib/src/burnchains/tests/madhouse.rs Outdated
Comment thread pox-locking/src/pox_5.rs
Comment thread stackslib/src/chainstate/stacks/sbtc.rs
Comment thread clarity/src/vm/functions/bitcoin.rs
Comment thread pox-locking/src/tests/madhouse.rs Outdated
Comment thread pox-locking/src/tests/madhouse.rs Outdated
Comment thread clarity/src/vm/tests/proptest_strategies.rs
@radu-stacks radu-stacks force-pushed the feat/pox-5-waterfall-proptests branch from 251fc97 to 219d675 Compare June 5, 2026 12:12
@radu-stacks radu-stacks force-pushed the feat/pox-5-waterfall-proptests branch from 9e10f28 to 146633a Compare June 5, 2026 16:29
@radu-stacks radu-stacks marked this pull request as ready for review June 15, 2026 08:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants