Skip to content

Integration tests for sweep / spend coordination paths in keep-frost-net/src/node/psbt.rs (round-4b) #551

Description

@kwsantiago

Round 4b of #417. Round 4a (this PR) covered keep-bitcoin's recovery_tx.rs and psbt.rs (86 mutants). The much larger `keep-frost-net/src/node/psbt.rs` (147 mutants, 0 inline tests) is the actual sweep + spend coordination logic and is filed here as its own session because:

  1. It has zero inline tests today.
  2. The functions are mostly async coordination handlers (`handle_psbt_propose`, `handle_psbt_sign`, `request_psbt_spend`, `request_descriptor_migration_sweep`) that need multi-peer integration test infrastructure — the same shape as Multi-peer integration tests covering keep-frost-net signing/coordination decisions (round-2 mutation kills) #541 / Multi-peer integration tests for keep-frost-net ECDH coordination (round-2 mutation kills) #543 / Integration tests for descriptor session persistence + load/migration paths (round-3b mutation kills) #549.

What round 4a shipped (PR landing now)

What still needs integration tests

Per-function breakdown from baseline mutation run:

Function Surviving mutations Why unit tests can't kill them
`request_psbt_spend` / `request_descriptor_migration_sweep` ~40 Multi-peer coordination: needs a simulator that drives proposer → responders → aggregation.
`handle_psbt_propose` ~25 Responder side gates (destination re-derivation per #414, sweep cap per #502, replay window, peer policy).
`handle_psbt_sign` / `handle_psbt_finalize` ~30 State machine on the responder side.
Pure helpers I didn't get to ~20 Some boundary mutations in helper functions that can probably be killed by direct unit tests in a follow-up.

Proposed approach

Same shape as #541, #543, #549:

  1. In-process simulator: shared in-memory event channel for KfpMessages, bypass relay.
  2. Cover the destination-rebinding case from WDC: responder-side sweep destination & prevout-amount validation #414: an authorized proposer submits a PSBT with destination ≠ NEW descriptor's re-derived address → responder refuses to sign.
  3. Cover the prevout-value mismatch from Responder-side prevout amount validation against a chain view (#414 amount half) #502 (once the chain view check from Responder-side prevout amount validation against a chain view (#414 amount half) #502 lands): a proposer-supplied `witness_utxo.value_sats` that doesn't match the chain → responder refuses.
  4. Cover the fee-fraction cap path: proposer pegs fee at the cap exactly → accepted; cap + 1 → refused.
  5. Re-run `cargo mutants -p keep-frost-net --file keep-frost-net/src/node/psbt.rs` and confirm survival rate drops.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestmediumnostr-frostNostr FROST coordination protocolp3Lowest PrioritysecuritySecurity-related issueswdcWallet Descriptor Coordination

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions