feat(key-wallet): expose reserved outpoints for cross-account input selection#905
feat(key-wallet): expose reserved outpoints for cross-account input selection#905bfoss765 wants to merge 2 commits into
Conversation
…election The UTXO reservation ledger (ReservationSet) is consulted by an account's own coin selection via set_funding, but its read surface — reservations() and ReservationSet::reserved() — is pub(crate). A caller that selects inputs across accounts, force-adding another account's spendable_utxos() into a shared sweep, bypasses that account's selector and so its reservation awareness. spendable_utxos() filters on spendability only, so after a broadcast leaves inputs reserved a rebuild/retry can reselect the same foreign inputs and produce a conflicting transaction. Add two additive public methods on ManagedCoreFundsAccount: - reserved_outpoints(current_height) -> HashSet<OutPoint>: a read-only snapshot of the currently reserved outpoints, TTL-swept at the given height. - spendable_utxos_excluding_reserved(last_processed_height): the reservation-aware counterpart of spendable_utxos, for cross-account sweeps. Existing spendable_utxos() semantics are unchanged so current callers are unaffected. Covered by a unit test proving a reserved outpoint is visible via the new read API, excluded from the excluding enumeration while still present in spendable_utxos, and reappears once released. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthrough
ChangesReservation-aware UTXO selection
Estimated code review effort: 3 (Moderate) | ~15–30 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #905 +/- ##
==========================================
- Coverage 74.54% 74.51% -0.04%
==========================================
Files 327 327
Lines 75032 75047 +15
==========================================
- Hits 55936 55923 -13
- Misses 19096 19124 +28
|
The public reserved_outpoints doc linked [`ReservationSet`], a pub(crate) type, tripping rustdoc::private-intra-doc-links (-D warnings) and failing the Documentation CI check. Plain-code span instead of an intra-doc link. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Motivation
Cross-account input sweeps in platform-wallet need to exclude UTXOs that an in-flight transaction build has already reserved, and today the reservation ledger is
pub(crate)so they cannot.The
ReservationSet(added in #812) bridges the window between selecting a build's inputs and processing its broadcast back into the wallet: reserved inputs are skipped by that account's own coin selection throughset_funding. But its read surface —ManagedCoreFundsAccount::reservations()andReservationSet::reserved()— is crate-private.A caller that selects inputs across accounts (force-adding a non-primary account's
spendable_utxos()into a shared sweep) bypasses that account's coin selector and therefore its reservation awareness.spendable_utxos()filters on spendability (maturity/lock) only. So after a broadcast leaves inputs reserved, a rebuild/retry can reselect the same foreign inputs and produce a conflicting transaction.This is the review finding on dashpay/platform#4074 (asset-lock funding from all accounts): the union sweep in
rs-platform-wallet'sasset_lock/build.rsforce-adds non-primary accounts'spendable_utxos()viaadd_inputs, bypassing reservation awareness.Change (additive — no existing signatures change)
Two new public read methods on
ManagedCoreFundsAccount:reserved_outpoints(current_height) -> HashSet<OutPoint>— a read-only, TTL-swept snapshot of the outpoints currently reserved by in-flight builds.spendable_utxos_excluding_reserved(last_processed_height) -> BTreeSet<&Utxo>— the reservation-aware counterpart ofspendable_utxos, intended for cross-account sweeps.spendable_utxos()semantics are intentionally left unchanged, since other callers rely on the maturity-only behaviour; keeping the new API additive keeps the change small and unblocks the platform-wallet consumer.Tests
Added
reserved_outpoints_are_excluded_from_spendable_and_reappear_on_release(inkey-wallet/src/tests/spent_outpoints_tests.rs), proving that a reserved outpoint is:reserved_outpoints,spendable_utxos_excluding_reservedwhile still present in the unchangedspendable_utxos,Validation
Intended consumer / follow-up
The platform-side consumption is a follow-up once this merges and the
rust-dashcorepin advances: dashpay/platform#4074's union sweep inpackages/rs-platform-wallet/src/wallet/asset_lock/build.rsshould callspendable_utxos_excluding_reserved(...)(or consultreserved_outpoints(...)) instead of the rawspendable_utxos()when force-adding non-primary accounts' inputs.🤖 Generated with Claude Code
Summary by CodeRabbit