v31.1-roots.1 · Commit 6: [PATCH 06/17] feat(wallet): preserve Roots signing and spend controls on v31
doc/roots-v31-port-review.md
Before: doc/roots-v31-port-review.md · After: doc/roots-v31-port-review.md
File metadata
index 0948ff33ab106892045cf13b8157c1d4fadd214d..0a0a6ca759a62ab091751e6a6246df35262dbef1 100644
Download original patch · Release notes
Diff rows 1–108 of 108. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.
doc/roots-v31-port-review.md
CHANGED
|
@@ -619,3 +619,108 @@ matrix. No static mockup or history collector is introduced.
|
|
| 619 |
These adaptations preserve the catalogued Roots contracts and attribution to
|
| 620 |
Jaromil and devjoinedthechat alongside the Bitcoin Core and Bitcoin Knots
|
| 621 |
provenance already recorded above.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 619 |
These adaptations preserve the catalogued Roots contracts and attribution to
|
| 620 |
Jaromil and devjoinedthechat alongside the Bitcoin Core and Bitcoin Knots
|
| 621 |
provenance already recorded above.
|
| 622 |
+
|
| 623 |
+
## L11.1 wallet foundations and per-send RBF
|
| 624 |
+
|
| 625 |
+
The descriptor/SQLite and external-signer boundaries retain the native v31
|
| 626 |
+
wallet API. Roots database enumeration excludes node database directories and
|
| 627 |
+
avoids descending through symlinks/reparse points. SQLite opening probes directory
|
| 628 |
+
write access before opening an existing database, retaining v31 locking/error
|
| 629 |
+
handling; all 19 source SQLite warning/error modernization lines already exist
|
| 630 |
+
upstream. No legacy database build support or new backup/flush promise is added.
|
| 631 |
+
|
| 632 |
+
External signer invocation keeps v31's explicit argument vector and closes
|
| 633 |
+
unrelated inherited Unix descriptors after redirecting standard streams, retaining
|
| 634 |
+
the exec-error pipe at FD 3 with close-on-exec set. `close_range` closes all higher
|
| 635 |
+
descriptors when available. Its Linux fallback reads `/proc/self/fd` using raw
|
| 636 |
+
`getdents64` into a fixed stack buffer: it enumerates actual descriptors, including
|
| 637 |
+
those above a subsequently lowered soft limit, without post-fork heap allocation
|
| 638 |
+
or scanning a numeric descriptor limit. Other Unix builds use a detected native
|
| 639 |
+
`closefrom` fallback. If no safe closure mechanism succeeds, the child reports an
|
| 640 |
+
error through the retained pipe and exits before executing the signer. Non-Linux
|
| 641 |
+
fallback runtime behavior is an untested platform gap; unsupported fallback
|
| 642 |
+
platforms fail closed. The unsafe source RLIMIT-based fallback is replaced;
|
| 643 |
+
source process poll/kill APIs remain unported. The current Windows
|
| 644 |
+
CreateProcess implementation does not provide equivalent inherited-handle
|
| 645 |
+
isolation; Windows handle, permission and reparse behavior remain explicit gaps.
|
| 646 |
+
|
| 647 |
+
The Send dialog takes its initial RBF choice from the selected wallet's
|
| 648 |
+
`walletrbf`, retains native explicit coin-control overrides and reports signaling
|
| 649 |
+
from the prepared transaction even when no fee is charged. Saved PSBT tests decode
|
| 650 |
+
both signaling choices. Replacement acceptance remains dependent on network policy.
|
| 651 |
+
Automatic anti-fee-sniping locktimes avoid the source CAT21 policy marker; explicit
|
| 652 |
+
caller locktimes and consensus validity are unchanged. This ports the spending
|
| 653 |
+
safeguard associated with the accepted local-policy rule.
|
| 654 |
+
|
| 655 |
+
Focused candidate coverage exercises database-directory write rejection, skipped
|
| 656 |
+
node databases and symlink traversal; descriptor wallet/send and external signer
|
| 657 |
+
behavior; child descriptor closure plus preserved standard streams and process
|
| 658 |
+
errors; both wallet RBF defaults, explicit overrides, confirmation text and PSBT
|
| 659 |
+
sequences. Sweep authorization, coin-control facts and the rendered interaction
|
| 660 |
+
matrix remain L11.2. Attribution remains Jaromil and devjoinedthechat alongside
|
| 661 |
+
Bitcoin Core/Knots provenance.
|
| 662 |
+
|
| 663 |
+
L11.1 focused evidence: 34 GCC unit cases in system/filesystem/wallet/spend and
|
| 664 |
+
wallet database/load/PSBT suites; four functional profiles (wallet signer,
|
| 665 |
+
multiwallet RPC and CLI, wallet send); 21 Qt6 test results, including the RBF
|
| 666 |
+
confirmation and decoded PSBT assertions; and the same 34 focused unit cases in
|
| 667 |
+
Clang ASan/UBSan under a 60-second runtime bound. Leak detection was disabled
|
| 668 |
+
(`ASAN_OPTIONS=detect_leaks=0`); undefined behavior halts on error. This is bounded
|
| 669 |
+
sanitizer coverage, not a leak or exhaustive race proof. A Qt-only fixture reset
|
| 670 |
+
was corrected after its first run and the Qt suite rerun; production and headless
|
| 671 |
+
results stayed hash-matched. Qt5 and the visual matrix remain L11.2. The full
|
| 672 |
+
applicable candidate gate remains the L11 acceptance gate.
|
| 673 |
+
|
| 674 |
+
L11.1 signer review corrected the source fallback's soft-limit assumption. A new
|
| 675 |
+
regression opens a descriptor at 123 or higher before lowering the child's soft
|
| 676 |
+
limit to 32, forces fallback and checks descriptor closure, standard streams,
|
| 677 |
+
retained exec-error pipe and its close-on-exec flag. All three current signer
|
| 678 |
+
system cases pass under GCC and bounded Clang ASan/UBSan; `wallet_signer.py`
|
| 679 |
+
passes again against the corrected daemon. Unaffected wallet/database/RBF and
|
| 680 |
+
Qt6 evidence retains its original source/fixture and binary-hash provenance.
|
| 681 |
+
The combined focused gate now covers 35 distinct unit cases, with the three
|
| 682 |
+
signer cases replacing the original two; it is not a claim that every retained
|
| 683 |
+
case was rerun against the new binary. The full acceptance gate is still L11.
|
| 684 |
+
|
| 685 |
+
### L11.2 — sweep and coin-control authorization
|
| 686 |
+
|
| 687 |
+
The v31 port carries transient-key WIF sweep through shared native UTXO scanning,
|
| 688 |
+
RPC and Qt, without importing supplied keys. Preview remains the default. The
|
| 689 |
+
GUI requires a current preview, default-Cancel confirmation and an exact rebuilt
|
| 690 |
+
transaction-ID match. Atomic cancellation/final submission transitions prevent
|
| 691 |
+
accepted cancellation from later broadcasting. Worker disposal clears secure
|
| 692 |
+
storage and catches interruption errors; complete Qt/host memory erasure is not
|
| 693 |
+
promised. Fee convergence uses one locked native estimate/fallback snapshot.
|
| 694 |
+
|
| 695 |
+
Source review found an inherited destination defect: cached-script ownership
|
| 696 |
+
accepted an incomplete local-key multisig descriptor. A disposable source-build
|
| 697 |
+
probe confirmed accepted preview but incomplete wallet-only spending. Both v31
|
| 698 |
+
entry points now share a native signing-satisfaction check. Cached public
|
| 699 |
+
descriptor expansion maps available roots, including encrypted keys, to derived
|
| 700 |
+
public keys without private-key retrieval/export or unlock. An availability-gated
|
| 701 |
+
dummy creator uses native script satisfaction for multisig, Taproot alternatives
|
| 702 |
+
and MuSig participants. Missing 2-of-2 keys are rejected; a sufficient 2-of-3
|
| 703 |
+
subset remains eligible. Timelock maturity and future network acceptance remain
|
| 704 |
+
separate from local signing capability.
|
| 705 |
+
|
| 706 |
+
Coin-control preserves native availability/selection and PSBT behavior while
|
| 707 |
+
reporting effective value, input size, lock, watch-only, reuse/group, fee/change
|
| 708 |
+
and actual transaction RBF facts. Same-balance wallet notifications invalidate
|
| 709 |
+
selection. Horizontal scrolling retains readable columns at large fonts; summary
|
| 710 |
+
and controls fit the bounded visual profiles. These are facts, not privacy scores.
|
| 711 |
+
|
| 712 |
+
Focused final verification covers 91 cases across all affected wallet, shared
|
| 713 |
+
script/descriptor, key, RPC and process suites; six functional profiles (sweep,
|
| 714 |
+
send, multiwallet RPC/CLI, signer and scantxoutset); the complete Qt5 and Qt6
|
| 715 |
+
test suites (21 result rows each, including initialization/cleanup); and 48
|
| 716 |
+
bounded Clang ASan/UBSan cases with leak detection disabled. After a recursive
|
| 717 |
+
lock annotation correction, all 91 unit cases and all six affected functional
|
| 718 |
+
profiles were rerun against the frozen final binaries.
|
| 719 |
+
Eight actual Qt5/Qt6 profiles at 1280x800 and 1920x1080 with 100%/150% font scale
|
| 720 |
+
produced 80 captures. These unchanged-UI captures retain their original binary
|
| 721 |
+
hashes; both Qt suites passed again with the final destination correction.
|
| 722 |
+
Native confirmation captures preserve a prior test's background shutdown window
|
| 723 |
+
and synthetic regtest fee-estimator limitations. Linux/Xvfb evidence does not
|
| 724 |
+
establish Windows/macOS rendering, physical-DPI scaling, complete secret erasure
|
| 725 |
+
or exhaustive races. The full applicable L11 acceptance sweep remains the next
|
| 726 |
+
root-directed gate. Credits remain Jaromil, devjoinedthechat, Core and Knots.
|