feat(key-wallet): payload-finalization seam for input-committing special transactions - #991
feat(key-wallet): payload-finalization seam for input-committing special transactions#991QuantumExplorer wants to merge 1 commit into
Conversation
…ial transactions A ProUpServTx's payload commits to the chosen inputs (inputs_hash) and is itself BLS-signed by the operator key, while each input's ECDSA sighash covers the finished payload. build_signed_reserved fuses input selection and input signing with no seam between them, so such a payload could never be finalized at the right moment. Add TransactionBuilder::build_signed_reserved_with_payload_finalizer: after selection reserves the chosen inputs, a finalizer closure receives the unsigned transaction (inputs chosen and BIP-69 sorted, placeholder payload attached) and returns the finalized payload; the builder installs it and only then signs the inputs. The placeholder is required so selection prices the payload bytes into the fee, and the finalized payload must keep the placeholder's variant and estimated size — the fee is fixed at selection time, so growth would underpay the configured rate. Every failure path (finalizer error, guards, signing) releases the reservation owner-guarded, exactly like a failed sign in build_signed_reserved. The fee-sizing payload match moves out of calculate_base_size into estimated_payload_size so the size guard and the fee estimate can never disagree. 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 Plus Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthrough
ChangesPayload Finalization Flow
Merge Risk: 🟡 Moderate · up to The new signing path reserves inputs while a payload is finalized and signed, but interruption or expiration during that window can leave inputs unavailable or allow a stale build to return after ownership changes, while payload correctness depends on callers enforcing semantic commitments. Merge should wait for explicit owner acceptance or hardening of the reservation lifecycle and caller contract. Sequence Diagram(s)sequenceDiagram
participant TransactionBuilder
participant finalize_payload
participant TransactionSigner
TransactionBuilder->>TransactionBuilder: Assemble unsigned transaction
TransactionBuilder->>finalize_payload: Finalize payload using selected inputs
finalize_payload-->>TransactionBuilder: Return finalized payload
TransactionBuilder->>TransactionBuilder: Validate variant and estimated size
TransactionBuilder->>TransactionSigner: Sign finalized transaction
TransactionSigner-->>TransactionBuilder: Return signed transaction
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev #991 +/- ##
==========================================
+ Coverage 77.14% 77.22% +0.08%
==========================================
Files 329 329
Lines 82998 83244 +246
==========================================
+ Hits 64026 64284 +258
+ Misses 18972 18960 -12
|
What
Adds
TransactionBuilder::build_signed_reserved_with_payload_finalizer— a two-phase build path for special transactions whose payload commits to the chosen inputs and is itself signed. The motivating case is the ProUpServTx (unban / update-service): its payload'sinputs_hashis only knowable after input selection, its operator-BLSpayload_sigcovers that hash, and each input's ECDSA sighash covers the finished payload — a strict select → hash → BLS-sign → input-sign order that the existingbuild_signed_reserved(which fuses selection and input signing) cannot express.How
assemble_unsignedselects, BIP-69-sorts, and reserves the inputs, afinalize_payloadclosure receives the unsigned transaction (placeholder payload still attached) and returns the finalized payload; the builder installs it and only then computes input sighashes (the legacy sighash consensus-encodes the whole tx, payload included).build_signed_reserved(feat(kotlin-sdk): split build/broadcast with reservation release for BIP70-style deferred submission platform#4185).calculate_base_sizeintoestimated_payload_size, so the size guard and the fee estimate use one source of truth. No behavior change to existing paths.Tests
Six new tests: happy path (finalizer sees selected unsigned inputs, payload installed before input signing,
inputs_hashmatches, inputs stay reserved), finalizer-error release, variant-change guard, size-growth guard, missing-placeholder refusal (finalizer never runs, nothing reserved), and size-guard/fee-estimate agreement. Fullkey-walletsuite: 678 passed.cargo fmt,clippy --all-features --all-targets, andcargo check --workspace --all-featuresclean.Context
First of a three-PR sequence for unbanning PoSe-banned masternodes/evonodes from the mobile wallets: this seam (rust-dashcore) → ProUpServTx orchestrator + FFI (dashpay/platform) → wallet UI. The seam is generic and also unlocks future ProUpRegTx / ProUpRevTx builders. Note for the platform bump: the current platform pin (
3d13d983, onchore/sync-fixes-without-swept) has not touched this file, so this commit cherry-picks cleanly onto that lineage if the pin cannot move todevyet.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes