v31.1-roots.1 · Commit 1: [PATCH 01/17] build(roots): establish v31 portability foundation
doc/roots-features.md
Before: /dev/null · After: doc/roots-features.md
File metadata
new file mode 100644 index 0000000000000000000000000000000000000000..48a828421d2248b4362e480e8c5f0088978a010d
Download original patch · Release notes
Diff rows 1–400 of 442. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. The two line-number columns refer to before and after.
doc/roots-features.md
ADDED
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
# Bitcoin Roots v31 preservation contracts
|
|
2
|
+
|
|
3
|
+
This unpublished candidate starts directly from authenticated Core v31.1.
|
|
4
|
+
[The port review](roots-v31-port-review.md) pins the exact source and new base,
|
|
5
|
+
accounts for every source commit, and records thematic ownership and gaps.
|
|
6
|
+
|
|
7
|
+
## Availability in this candidate
|
|
8
|
+
|
|
9
|
+
The foundation carries the contract documents and CMake support for selecting
|
|
10
|
+
Qt 5/6 and optional system LevelDB/libsecp256k1. Embedded libraries remain the
|
|
11
|
+
default. Native crypto probes, descriptor-wallet/SQLite boundaries, external
|
|
12
|
+
signer support and QR/DBus/IPC build conditions use the v31 implementations.
|
|
13
|
+
These upstream build conditions are not evidence that a missing optional
|
|
14
|
+
library or platform was tested. See [portability profiles](roots-build-portability.md).
|
|
15
|
+
|
|
16
|
+
The source contracts below are preservation requirements, **not a claim that
|
|
17
|
+
Roots behavior has been ported**. Local policy/mining and strict Roots parsing
|
|
18
|
+
are deferred to L7; peer controls/health to L8; sweep, coin-control and per-send
|
|
19
|
+
RBF extensions to L9; read/write config, effective-policy RPC, resource support
|
|
20
|
+
and dormant statistics to L10; identity/desktop and maintenance integration to
|
|
21
|
+
L11. The narrow monotonic `uptime` RPC sub-aspect has reviewed upstream
|
|
22
|
+
equivalence; this does not retire the remaining operator-stats contract.
|
|
23
|
+
|
|
24
|
+
MiniUPnPc dependency discovery is retained, but its UPnP runtime and depends
|
|
25
|
+
recipe integration belong to the peer theme. The legacy `ENABLE_TOR_SUBPROCESS` declaration has no dedicated
|
|
26
|
+
launcher consumer; it is not an available feature. Roots Windows taskbar
|
|
27
|
+
progress remains deferred to desktop integration. Passing either undeclared
|
|
28
|
+
option to CMake does not implement it. No intended behavior is retired by a
|
|
29
|
+
missing dependency.
|
|
30
|
+
|
|
31
|
+
Code and test references in the contract body identify paths at pinned source
|
|
32
|
+
`10d772eb7f4b00b5193428a0dde4c06558d6c297`; they are rendered as source
|
|
33
|
+
references rather than links into this candidate when their implementation
|
|
34
|
+
has not been carried. Historical test results are not current candidate passes.
|
|
35
|
+
|
|
36
|
+
## Preservation contracts
|
|
37
|
+
|
|
38
|
+
These stable IDs describe behavior to retain when moving between Core versions.
|
|
39
|
+
The source checked for this collection is Roots
|
|
40
|
+
`17e1d484aba2a881be03b8928fba3c0125e027a2`, based on authenticated Core v30.3
|
|
41
|
+
commit `49faec4f87f5cd19c88db01a82e5c68b087c8227`. Source and test links are
|
|
42
|
+
version-specific aids; neither a function name nor the location of an admission
|
|
43
|
+
check is a preservation requirement. The contracts do not authorize a change in
|
|
44
|
+
consensus, a new feature, or repair of a documented gap.
|
|
45
|
+
|
|
46
|
+
**Acceptance rule for every ID:** preserve its observable results, defaults,
|
|
47
|
+
supported configuration, units, errors and boundaries. Tests named below are
|
|
48
|
+
acceptance evidence for the cases they actually exercise, not proof of all
|
|
49
|
+
configurations. A **gap** names an unproved case or an implementation/documentation
|
|
50
|
+
conflict. Existing non-features and the wallet authorization boundary still apply.
|
|
51
|
+
|
|
52
|
+
**Retirement rule for every ID:** remove a Roots implementation only after a
|
|
53
|
+
reviewed upstream-equivalence comparison demonstrates the same behavior and
|
|
54
|
+
defaults for the listed acceptance cases and dependencies. Re-run the tests on
|
|
55
|
+
the new base and account for remaining gaps. A similar upstream option name,
|
|
56
|
+
RPC or feature is insufficient. Maintenance may retire when the new base makes
|
|
57
|
+
it unnecessary and its relevant validation still passes. Dormant support cannot
|
|
58
|
+
be represented as an adopted working feature; enabling it requires a separate
|
|
59
|
+
compatibility decision.
|
|
60
|
+
|
|
61
|
+
### Local policy and mining
|
|
62
|
+
|
|
63
|
+
- **policy-parsing:** the [policy input compatibility contract](feature-contracts/policy-parsing.md)
|
|
64
|
+
specifies scoped grammar, effective defaults, diagnostics, migration decisions
|
|
65
|
+
and baseline characterization for Roots-added policy controls. Parser and
|
|
66
|
+
isolated startup regressions enforce the scoped strict behavior; inherited
|
|
67
|
+
Core option parsing remains outside that scope.
|
|
68
|
+
- **effective-policy:** the [effective mempool policy contract](feature-contracts/effective-policy.md)
|
|
69
|
+
defines an additive `getmempoolinfo.policy` object, initialized-state provenance,
|
|
70
|
+
units, enforcement gates and compatibility. RPC functional assertions cover
|
|
71
|
+
defaults, overrides, disabled settings, precedence and carrier/sub-dust
|
|
72
|
+
reporting/admission parity without changing local policy or consensus rules.
|
|
73
|
+
- **policy-standardness:** configurable local transaction, input and witness
|
|
74
|
+
bounds preserve rejection reasons without changing script consensus. Defaults
|
|
75
|
+
include 1,650-byte script policy, 20 equivalent bytes per sigop and 20 strict
|
|
76
|
+
bytes per sigop, 2,500 legacy sigops, bare pubkey/multisig disabled, unknown
|
|
77
|
+
witness outputs allowed, CAT21 locktime-marker rejection enabled and token
|
|
78
|
+
filters disabled. Ephemeral defaults permit anchors, but not arbitrary dust
|
|
79
|
+
or sends; bare anchors are allowed. See policy settings (`src/policy/settings.h`, source reference),
|
|
80
|
+
standardness options and constants (`src/policy/policy.h`, source reference),
|
|
81
|
+
checks (`src/policy/policy.cpp`, source reference) and admission (`src/validation.cpp`, source reference).
|
|
82
|
+
Acceptance: mempool_sigoplimit.py (`test/functional/mempool_sigoplimit.py`, source reference)
|
|
83
|
+
`test_sigops_limit`, `test_sigops_package`, `test_legacy_sigops_stdness` and
|
|
84
|
+
transaction_tests.cpp (`src/test/transaction_tests.cpp`, source reference). Gap: a complete
|
|
85
|
+
option/ephemeral/filter interaction matrix and explicit valid-block cases for
|
|
86
|
+
each local rejection are not supplied by these tests.
|
|
87
|
+
- **policy-carrier:** default `datacarrier=1`, aggregate carrier budget 83 bytes,
|
|
88
|
+
full counting enabled, nonstandard carriers and bare-carrier transactions
|
|
89
|
+
disabled. Recognized input/witness carriers also count with full counting;
|
|
90
|
+
permitting nonstandard transactions alone does not disable these checks.
|
|
91
|
+
`datacarriercost` defaults to 1 virtual byte per detected data byte, accepts
|
|
92
|
+
fixed-point values with two decimal places from 0 through 1,073,741,823.75,
|
|
93
|
+
and rounds the requested cost upward to integral weight units (quarters of a
|
|
94
|
+
vbyte). Extra weight only raises policy size. See
|
|
95
|
+
startup parsing (`src/init.cpp`, source reference), carrier detection (`src/policy/policy.cpp`, source reference)
|
|
96
|
+
and admission (`src/validation.cpp`, source reference). Acceptance:
|
|
97
|
+
mempool_datacarrier.py (`test/functional/mempool_datacarrier.py`, source reference) `run_test`
|
|
98
|
+
covers budget boundaries, disabling, extreme cost/invalid inputs and valid
|
|
99
|
+
blocks containing locally rejected transactions;
|
|
100
|
+
mempool_tests.cpp (`src/test/mempool_tests.cpp`, source reference) `MempoolExtraWeightBoundary`
|
|
101
|
+
covers size arithmetic. Conflict: current help says multiple outputs are
|
|
102
|
+
allowed, but standardness rejects more than one OP_RETURN output as
|
|
103
|
+
`multi-op-return`. Preserve the actual rejection until explicitly decided;
|
|
104
|
+
help wording is not authority to widen admission. `test_taproot_carrier` in
|
|
105
|
+
`mempool_datacarrier.py` independently checks a maximum-size push/OP_DROP
|
|
106
|
+
tapscript: default nonstandard-carrier rejection, aggregate budget rejection,
|
|
107
|
+
admission at the exact carrier budget when permitted, and valid-block acceptance.
|
|
108
|
+
mempool_subdust_fee_penalty.py (`test/functional/mempool_subdust_fee_penalty.py`, source reference)
|
|
109
|
+
`test_carrier_cost_interaction` covers output-carrier fractional cost rounding,
|
|
110
|
+
zero cost, full-count disabling and composition with the dust deficit.
|
|
111
|
+
Gap: other recognized input/witness carrier patterns and their fractional
|
|
112
|
+
cost/full-count interactions.
|
|
113
|
+
The inherited feature_taproot.py (`test/functional/feature_taproot.py`, source reference)
|
|
114
|
+
fixture `tapscript/pushmaxlimit` expects admission under that test's explicit
|
|
115
|
+
nonstandard-carrier allowance and enlarged budget, subject to its existing
|
|
116
|
+
witness-size checks. The incorrect unconditional nonstandard marker was
|
|
117
|
+
removed to match this configuration; the oversized push still fails consensus.
|
|
118
|
+
- **policy-dust:** thresholds use the effective dust relay rate; the floor is
|
|
119
|
+
3,000 sat/kvB (`dustrelayfee=0.00003000` BTC/kvB). `dustdynamic=off` is the
|
|
120
|
+
default. Dynamic mode is `[multiplier*]target:blocks` or
|
|
121
|
+
`[multiplier*]mempool:kvB`; multiplier defaults to 3, is stored in thousandths
|
|
122
|
+
and must be positive. Target is at least two blocks and no more than the
|
|
123
|
+
estimator's longest tracked target; mempool position is at least 1 kvB.
|
|
124
|
+
Dynamic estimates are multiplied, converted to integral sat/kvB and clamped
|
|
125
|
+
to the configured floor. The scheduler updates the rate every 15 minutes;
|
|
126
|
+
missing estimates fall back to the floor. The published rate
|
|
127
|
+
and standardness snapshot must agree under concurrent access. See
|
|
128
|
+
parser (`src/node/mempool_args.cpp`, source reference), publication (`src/txmempool.cpp`, source reference) and
|
|
129
|
+
threshold calculation (`src/policy/policy.cpp`, source reference). Acceptance:
|
|
130
|
+
mempool_dust.py (`test/functional/mempool_dust.py`, source reference) `test_dust_output` and
|
|
131
|
+
`test_dustrelay` cover script-dependent thresholds, exact threshold/one below,
|
|
132
|
+
and zero-rate behavior; mempool_tests.cpp (`src/test/mempool_tests.cpp`, source reference)
|
|
133
|
+
`DynamicDustFeePublication` covers changing snapshots. Gap: estimator-target
|
|
134
|
+
mode without an estimator is accepted by the parser; it is not evidence of a
|
|
135
|
+
working estimate. Extreme dynamic multiplier arithmetic needs separate coverage.
|
|
136
|
+
- **policy-subdust:** apply a configurable deficit penalty to modified fees,
|
|
137
|
+
using script-specific dust thresholds, without changing the actual fee or
|
|
138
|
+
consensus validity. Enabled by default. The
|
|
139
|
+
[worked contract](/doc/feature-contracts/subdust.md) defines units, rounding,
|
|
140
|
+
saturation, exemptions, precedence, interactions, acceptance cases and gaps.
|
|
141
|
+
- **policy-replacement:** default full RBF (`mempoolreplacement=fee,-optin`)
|
|
142
|
+
and enforced TRUC (`mempooltruc=enforce`). `Never` disables all replacement;
|
|
143
|
+
`OptIn` replaces directly signaling originals or v3 originals, including
|
|
144
|
+
non-signaling v3; full RBF still requires fee/resource replacement checks.
|
|
145
|
+
TRUC can instead be rejected or accepted without enforcing TRUC-specific
|
|
146
|
+
limits. `getmempoolinfo.fullrbf` means configured full RBF, so false does not
|
|
147
|
+
mean v3 replacements are disabled. Explicit `optin` wins over
|
|
148
|
+
`mempoolfullrbf=1`; explicit replacement disabling also wins and warns on
|
|
149
|
+
that contradiction. See selection (`src/node/mempool_args.cpp`, source reference),
|
|
150
|
+
admission/replacement (`src/validation.cpp`, source reference) and RPC (`src/rpc/mempool.cpp`, source reference).
|
|
151
|
+
Acceptance: mempool_rbf_policy.py (`test/functional/mempool_rbf_policy.py`, source reference)
|
|
152
|
+
`POLICIES`/`check_replacement` and
|
|
153
|
+
mempool_truc.py (`test/functional/mempool_truc.py`, source reference) `test_truc_replacement`,
|
|
154
|
+
`test_truc_reorg`, `test_minrelay_in_package_combos`, plus package/sibling
|
|
155
|
+
cases. Gap: all TRUC-mode/replacement-mode combinations and conflicting option
|
|
156
|
+
inputs. Current initialized incremental relay fee is 100 sat/kvB, while
|
|
157
|
+
startup help advertises 1,000; this is a recorded conflict, not a promised
|
|
158
|
+
change to the effective default.
|
|
159
|
+
- **policy-coinage:** minimum relay maturity and coin-block age both default to
|
|
160
|
+
zero (disabled). Maturity counts depth at the next block height; coin-block
|
|
161
|
+
age sums input satoshis times blocks since each coin's height. Unconfirmed
|
|
162
|
+
inputs add no confirmed age. These are additional local gates, never changes
|
|
163
|
+
to coinbase consensus maturity. See coin age (`src/policy/coin_age_priority.cpp`, source reference)
|
|
164
|
+
and admission (`src/validation.cpp`, source reference). Acceptance: priority accounting cases in
|
|
165
|
+
miner_tests.cpp (`src/test/miner_tests.cpp`, source reference) `CreateNewBlock_validity` cover the
|
|
166
|
+
shared age cache. Gap: dedicated enabled/disabled relay maturity/coin-block
|
|
167
|
+
boundaries and their valid-block fixtures.
|
|
168
|
+
- **policy-reuse:** `spkreuse=allow` defaults to no extra restriction. The
|
|
169
|
+
documented alternative `conflict` uses mempool scriptPubKey creation/spend
|
|
170
|
+
tracking to reject reuse or consider policy conflicts for replacement. This is a local
|
|
171
|
+
script rule, not a privacy score, address-ownership inference or consensus
|
|
172
|
+
prohibition. See mode selection (`src/init.cpp`, source reference), admission (`src/validation.cpp`, source reference)
|
|
173
|
+
and tracking (`src/txmempool.cpp`, source reference). Gap: no dedicated functional acceptance
|
|
174
|
+
test for these modes, reorg tracking and replacement interactions is identified;
|
|
175
|
+
generic mempool tests are not a substitute.
|
|
176
|
+
- **mining-template:** with neither size nor weight option specified, the
|
|
177
|
+
effective local limit is 1,200,000 weight units with no additional size cap
|
|
178
|
+
below the 4,000,000-byte protocol bound; minimum fee is 1,000 sat/kvB and
|
|
179
|
+
priority area is 100,000 serialized bytes. An explicit size-only option leaves
|
|
180
|
+
weight unrestricted up to consensus maximum, and a weight-only option leaves
|
|
181
|
+
size unrestricted; setting both enforces both. Priority area can be zero. Transactions
|
|
182
|
+
selected by priority and their fee-selected descendants must have accurate
|
|
183
|
+
ancestor weight/sigop accounting and appear at most once in dependency order.
|
|
184
|
+
See option normalization/assembly (`src/node/miner.cpp`, source reference) and
|
|
185
|
+
defaults (`src/policy/policy.h`, source reference). Acceptance:
|
|
186
|
+
miner_tests.cpp (`src/test/miner_tests.cpp`, source reference) `CreateNewBlock_validity` priority
|
|
187
|
+
ancestor boundary cases and
|
|
188
|
+
mining_prioritisetransaction.py (`test/functional/mining_prioritisetransaction.py`, source reference)
|
|
189
|
+
`run_test`. `test_mining_and_block_acceptance` in
|
|
190
|
+
mempool_subdust_fee_penalty.py (`test/functional/mempool_subdust_fee_penalty.py`, source reference)
|
|
191
|
+
covers modified-fee selection with priority enabled/disabled, penalty
|
|
192
|
+
disabling, unchanged actual fee rewards and a locally rejected valid-block
|
|
193
|
+
fixture. Conflict: inherited help advertised a 300,000-byte size default, while
|
|
194
|
+
assembler options (`src/node/miner.h`, source reference) leave size at the protocol maximum when
|
|
195
|
+
unset; `policy-parsing` corrected that help while preserving the interaction.
|
|
196
|
+
Gap: every size/weight/reserve/priority combination; mining a small
|
|
197
|
+
local template must never limit acceptance of a larger consensus-valid block.
|
|
198
|
+
|
|
199
|
+
### Peer controls and current-connection health
|
|
200
|
+
|
|
201
|
+
- **peer-controls:** retain Core's P2P protocol and inherited orphan/upload/
|
|
202
|
+
whitelist controls. Roots additionally bounds compact reconstruction extras
|
|
203
|
+
by count (default 32,768) and memory (10 decimal MB), excluding oversized
|
|
204
|
+
individual extras; provides `forceinbound` (implies `noban`) and explicit
|
|
205
|
+
compact-filter permissions; permits subnet disconnect; and can disable
|
|
206
|
+
outbound v1 on clearnet (`v2onlyclearnet`, default false). Default fee filters
|
|
207
|
+
are enabled. Bloom service is not globally advertised by default, with
|
|
208
|
+
implicit loopback permission when not explicitly disabled. Retain inactivity
|
|
209
|
+
limits, protected outbound/manual peers, bounded address scoring/cache behavior,
|
|
210
|
+
duplicate manual-connection checks and block-fetch safeguards. Tor binds must
|
|
211
|
+
not accidentally grant clearnet whitelist permission; SOCKS credentials must
|
|
212
|
+
not be logged. See networking (`src/net.cpp`, source reference),
|
|
213
|
+
processing (`src/net_processing.cpp`, source reference), permissions (`src/net_permissions.cpp`, source reference)
|
|
214
|
+
and proxy (`src/netbase.cpp`, source reference). Acceptance:
|
|
215
|
+
p2p_compactblocks_extratxs.py (`test/functional/p2p_compactblocks_extratxs.py`, source reference),
|
|
216
|
+
p2p_permissions.py (`test/functional/p2p_permissions.py`, source reference),
|
|
217
|
+
p2p_disconnect_ban.py (`test/functional/p2p_disconnect_ban.py`, source reference),
|
|
218
|
+
p2p_eviction.py (`test/functional/p2p_eviction.py`, source reference),
|
|
219
|
+
p2p_filter.py (`test/functional/p2p_filter.py`, source reference) and
|
|
220
|
+
p2p_invalid_messages.py (`test/functional/p2p_invalid_messages.py`, source reference), each
|
|
221
|
+
`run_test`. Gap: the full new permission/memory/transport/Tor-bind combination
|
|
222
|
+
matrix and platform-specific CPU measurement.
|
|
223
|
+
- **peer-health:** keep sorting/selection and current connection facts in the
|
|
224
|
+
existing peer table/detail pane. Missing state must reset to unavailable,
|
|
225
|
+
never another peer's stale values. Node RPC adds last block announcement,
|
|
226
|
+
forced-inbound state, deprecated misbehavior score and optional CPU load in
|
|
227
|
+
per mille of connection duration; omit CPU load when not measured or duration
|
|
228
|
+
is unsuitable. No history retention or content/activity feed. See
|
|
229
|
+
peer RPC (`src/rpc/net.cpp`, source reference), peer table (`src/qt/peertablemodel.cpp`, source reference) and
|
|
230
|
+
details (`src/qt/rpcconsole.cpp`, source reference). Acceptance:
|
|
231
|
+
apptests.cpp (`src/qt/test/apptests.cpp`, source reference) `consoleTests` resets unavailable
|
|
232
|
+
details; rpc_net.py (`test/functional/rpc_net.py`, source reference) `run_test` covers RPC.
|
|
233
|
+
Gap: visual checks at 1280×800 and 1920×1080, 100%/150% font scale, populated
|
|
234
|
+
sorting/selection and refresh; these were not executed by the headless baseline.
|
|
235
|
+
|
|
236
|
+
### Wallet authorization, signing and spend controls
|
|
237
|
+
|
|
238
|
+
- **wallet-foundation:** descriptor/SQLite wallets and optional external signing
|
|
239
|
+
are inherited Core foundations. Roots rejects unwritable database directories,
|
|
240
|
+
avoids recursively scanning node database directories and symlink/reparse
|
|
241
|
+
points, and closes unrelated child descriptors for signer commands. Preserve
|
|
242
|
+
normal wallet locking and error reporting; do not introduce another database,
|
|
243
|
+
backup/flush promise or Berkeley DB build option. See database (`src/wallet/db.cpp`, source reference),
|
|
244
|
+
SQLite (`src/wallet/sqlite.cpp`, source reference), filesystem helpers (`src/util/fs_helpers.cpp`, source reference)
|
|
245
|
+
and signer child invocation (`src/common/run_command.cpp`, source reference). Acceptance:
|
|
246
|
+
wallet_multiwallet.py (`test/functional/wallet_multiwallet.py`, source reference),
|
|
247
|
+
wallet_signer.py (`test/functional/wallet_signer.py`, source reference) and
|
|
248
|
+
wallet_tests.cpp (`src/wallet/test/wallet_tests.cpp`, source reference). Gap: platform-specific
|
|
249
|
+
reparse-point/permission cases and external signer availability in each build.
|
|
250
|
+
- **wallet-rbf:** the per-send GUI choice starts from the wallet's `walletrbf`
|
|
251
|
+
preference (Core default true), explicitly overrides it for the prepared
|
|
252
|
+
transaction, and shows its resulting signaling in confirmation and saved
|
|
253
|
+
PSBT. It is a signaling choice, not a guarantee of network replacement. See
|
|
254
|
+
Send dialog (`src/qt/sendcoinsdialog.cpp`, source reference) and
|
|
255
|
+
wallet model (`src/qt/walletmodel.cpp`, source reference). Acceptance:
|
|
256
|
+
wallettests.cpp (`src/qt/test/wallettests.cpp`, source reference) `walletTests` explicit on/off
|
|
257
|
+
override and decoded PSBT sequence assertions. Gap: visual confirmation/font
|
|
258
|
+
scale matrix, not established by a headless build.
|
|
259
|
+
- **wallet-sweep:** only documented WIF/script forms, local-key descriptor
|
|
260
|
+
destination in the selected wallet, no key import, preview by default and
|
|
261
|
+
final authorization before broadcast. Fee state is snapshotted under wallet
|
|
262
|
+
locking; cancellation/invalidation can stop scanning or preview, while accepted
|
|
263
|
+
broadcast submission completes. Reduce secret lifetime using secure storage,
|
|
264
|
+
cleansing and console redaction without claiming complete host/toolkit erasure.
|
|
265
|
+
The full operational contract is [wallet-privacy.md](/doc/wallet-privacy.md).
|
|
266
|
+
See RPC (`src/wallet/rpc/spend.cpp`, source reference), construction (`src/wallet/spend.cpp`, source reference)
|
|
267
|
+
and dialog (`src/qt/sweepdialog.cpp`, source reference). Acceptance:
|
|
268
|
+
wallet_sweepprivkeys.py (`test/functional/wallet_sweepprivkeys.py`, source reference) `run_test`
|
|
269
|
+
covers supported script forms, destination rejection, no import, stale/conflicting
|
|
270
|
+
previews and broadcast; wallettests.cpp (`src/qt/test/wallettests.cpp`, source reference)
|
|
271
|
+
`walletTests` covers secure cache and preview invalidation;
|
|
272
|
+
test_wallet_privacy_contract.py (`ci/test/test_wallet_privacy_contract.py`, source reference)
|
|
273
|
+
checks source structure of authorization/redaction boundaries. Gap: that static
|
|
274
|
+
check is not a race proof; cancellation/authorization concurrency and GUI
|
|
275
|
+
confirmation need runtime and visual evidence.
|
|
276
|
+
- **wallet-coin-control:** expose wallet facts, effective value, locked/reused/
|
|
277
|
+
grouped outputs and send fee/change/RBF consequences. Locked outputs remain
|
|
278
|
+
visible but unselectable; ordinary availability filters still exclude unsafe
|
|
279
|
+
and immature outputs. Material wallet changes clear explicit selection.
|
|
280
|
+
Conspicuously validate custom change; do not add automatic consolidation or
|
|
281
|
+
anonymity claims. See [wallet-privacy.md](/doc/wallet-privacy.md),
|
|
282
|
+
coin control (`src/qt/coincontroldialog.cpp`, source reference) and
|
|
283
|
+
wallet facts (`src/wallet/rpc/wallet.cpp`, source reference). Acceptance:
|
|
284
|
+
wallettests.cpp (`src/qt/test/wallettests.cpp`, source reference) `walletTests` selected/locked
|
|
285
|
+
and invalidation cases, wallet_send.py (`test/functional/wallet_send.py`, source reference) and
|
|
286
|
+
test_wallet_privacy_contract.py (`ci/test/test_wallet_privacy_contract.py`, source reference)
|
|
287
|
+
row-filter assertions. Gap: populated GUI and custom-change visual matrix.
|
|
288
|
+
|
|
289
|
+
### Runtime, configuration, portability and identity
|
|
290
|
+
|
|
291
|
+
- **runtime-config:** `confrw` defaults to network-datadir `bitcoin_rw.conf`.
|
|
292
|
+
Preserve recognized settings and precedence: internal forced settings, CLI,
|
|
293
|
+
read/write config, JSON settings, network config section, default config
|
|
294
|
+
section, then built-in default. For ordinary scalar values, CLI uses its last
|
|
295
|
+
value and config uses its first after negation processing; list/chain/network
|
|
296
|
+
options have separate inherited rules. Typed getters and diagnostics must not
|
|
297
|
+
leak secrets. See merging (`src/common/settings.cpp`, source reference),
|
|
298
|
+
configuration (`src/common/config.cpp`, source reference) and access/writes (`src/common/args.cpp`, source reference).
|
|
299
|
+
Acceptance: getarg_tests.cpp (`src/test/getarg_tests.cpp`, source reference) and
|
|
300
|
+
feature_config_args.py (`test/functional/feature_config_args.py`, source reference) `run_test`.
|
|
301
|
+
Scoped Roots policy grammar and its acceptance gates are specified by
|
|
302
|
+
`policy-parsing`.
|
|
303
|
+
- **operator-stats:** `uptime` returns elapsed seconds from a monotonic clock,
|
|
304
|
+
independent of adjusted wall-clock time; acceptance:
|
|
305
|
+
rpc_uptime.py (`test/functional/rpc_uptime.py`, source reference) `run_test`.
|
|
306
|
+
Retained statistics source defines `time_from`, `time_to`, and arrays of
|
|
307
|
+
`[relative_seconds, tx_count, mempool_bytes, minimum_fee_sat_per_kB]`, without
|
|
308
|
+
interpolation. The in-memory target is 10 MiB, cleanup is periodic rather
|
|
309
|
+
than a hard allocation ceiling, and enabled collection would be controlled
|
|
310
|
+
by a positive target. See stats model (`src/stats/stats.cpp`, source reference),
|
|
311
|
+
schema (`src/stats/rpc_stats.cpp`, source reference), startup declarations (`src/stats/init.cpp`, source reference)
|
|
312
|
+
and monotonic source (`src/common/system.cpp`, source reference). Gap/conflict: production does
|
|
313
|
+
not call registration, option initialization or sample collection at the
|
|
314
|
+
pinned source. `stats_tests/stats` in
|
|
315
|
+
stats_tests.cpp (`src/stats/test/stats_tests.cpp`, source reference) exercises the model directly,
|
|
316
|
+
not an available RPC. GUI-on/headless-off help wording also conflicts with
|
|
317
|
+
the model's default-disabled constant. Wiring and schema/default decisions
|
|
318
|
+
must be reviewed before claiming preservation of a working statistics service.
|
|
319
|
+
- **runtime-resources:** RAM detection influences inherited node cache sizing;
|
|
320
|
+
advisory file allocation must preserve existing bytes, FD limits and GiB
|
|
321
|
+
conversion must avoid overflow. Memory-pressure and I/O-priority helpers are
|
|
322
|
+
platform-scoped support, not proof of active consumers on each platform.
|
|
323
|
+
See cache sizing (`src/node/caches.cpp`, source reference), FS helpers (`src/util/fs_helpers.cpp`, source reference),
|
|
324
|
+
memory pressure (`src/util/mempressure.cpp`, source reference) and I/O priority (`src/util/ioprio.cpp`, source reference).
|
|
325
|
+
Acceptance: system_ram_tests.cpp (`src/test/system_ram_tests.cpp`, source reference),
|
|
326
|
+
fs_tests.cpp (`src/test/fs_tests.cpp`, source reference) and util_tests.cpp (`src/test/util_tests.cpp`, source reference).
|
|
327
|
+
Gap: platform/failure/concurrency evidence for unused helpers; no dedicated
|
|
328
|
+
Tor-launch behavior is established by a build flag.
|
|
329
|
+
- **build-portability:** retain supported CMake switches and actual dependency
|
|
330
|
+
probes, Qt 5/6 branches, QR/signer/taskbar conditions, native crypto flags,
|
|
331
|
+
and usable system LevelDB memory environment. Defaults include wallet/tests
|
|
332
|
+
enabled, GUI disabled, embedded LevelDB/secp256k1. IPC can be deliberately
|
|
333
|
+
disabled, with no IPC coverage claim. See CMakeLists.txt (`CMakeLists.txt`, source reference),
|
|
334
|
+
build guides (`doc/build-unix.md`, source reference), dependencies (`doc/dependencies.md`, source reference) and
|
|
335
|
+
LevelDB probe (`cmake/module/FindLevelDB.cmake`, source reference). Acceptance: configure/build
|
|
336
|
+
each supported profile and its registered `ctest` targets; build-contract
|
|
337
|
+
checks in ci/test (`ci/test`, source reference). Gap: the baseline covers one Linux headless
|
|
338
|
+
wallet profile, not all optional/platform configurations. `ENABLE_TOR_SUBPROCESS`
|
|
339
|
+
has no production consumer and cannot promise an automatic Tor instance.
|
|
340
|
+
- **identity-desktop:** built tools identify Roots and the selected version;
|
|
341
|
+
retain Roots icons and upstream/protocol attribution, QR-to-PNG export and
|
|
342
|
+
supported Windows taskbar progress without mass-rebranding history. See
|
|
343
|
+
version (`src/clientversion.cpp`, source reference), QR export (`src/qt/qrimagewidget.cpp`, source reference) and
|
|
344
|
+
taskbar (`src/qt/wintaskbarprogress.cpp`, source reference). Acceptance:
|
|
345
|
+
apptests.cpp (`src/qt/test/apptests.cpp`, source reference) `consoleTests` QR/icon assertions,
|
|
346
|
+
binary `-version`, and supported Qt/platform builds. Gap: QR/receive UI at both
|
|
347
|
+
resolutions/font scales and Windows taskbar runtime evidence.
|
|
348
|
+
|
|
349
|
+
### Maintenance dispositions
|
|
350
|
+
|
|
351
|
+
These IDs account for source work without treating it as operator behavior.
|
|
352
|
+
|
|
353
|
+
- **maintenance-ci:** classifiers, test fixtures, sanitizer/corpus scheduling,
|
|
354
|
+
platform checks and reuse of proven promotion CI. Acceptance:
|
|
355
|
+
`python3 -m unittest discover -s ci/test`, relevant lint and actual required
|
|
356
|
+
candidate CI profiles. Equivalent infrastructure must test the exact candidate;
|
|
357
|
+
a successful older workflow/build cannot retire the gate.
|
|
358
|
+
- **maintenance-release:** immutable source/tag/asset validation, portable
|
|
359
|
+
export/replay with `.github` exclusions and `git am -3 --keep-cr`, contributor
|
|
360
|
+
credit, five-platform archives, canonical COPYING, signature trust and
|
|
361
|
+
new-draft-only behavior. See maintainer workflow (`contrib/roots/README.md`, source reference)
|
|
362
|
+
and release tools (`ci/release/README.md`, source reference); acceptance: their tests under
|
|
363
|
+
ci/test (`ci/test`, source reference) and temporary export/replay. Optional notice tools do not
|
|
364
|
+
prove complete dependency copyright coverage. Publishing, tagging and remote
|
|
365
|
+
canonical updates are outside these contracts' implementation work.
|
|
366
|
+
- **maintenance-docs:** catalog/provenance/privacy/guidance, release notes and
|
|
367
|
+
generated manuals/example config follow the actual source/help. Acceptance:
|
|
368
|
+
check-doc.py (`test/lint/check-doc.py`, source reference), local links, `git diff --check` and
|
|
369
|
+
regenerated-output comparison when interfaces change. Preserve upstream names
|
|
370
|
+
where they identify lineage rather than Roots UI.
|
|
371
|
+
- **maintenance-native:** behavior-preserving C++ modernization and test/fuzz
|
|
372
|
+
fixture adaptation, safe empty file writes and test-only assertion hooks.
|
|
373
|
+
Acceptance: affected unit/functional/fuzz suites and diff inspection. Reverted
|
|
374
|
+
transient script changes do not create a consensus contract or require a port.
|
|
375
|
+
|
|
376
|
+
### Dependencies by stable ID
|
|
377
|
+
|
|
378
|
+
The shared consensus-neutral and configuration rules apply to every contract.
|
|
379
|
+
This table records additional feature dependencies; identifiers remain separate
|
|
380
|
+
even when implementations share a commit or file.
|
|
381
|
+
|
|
382
|
+
| Contract | Depends on |
|
|
383
|
+
| --- | --- |
|
|
384
|
+
| policy-standardness | None |
|
|
385
|
+
| policy-carrier | policy-standardness |
|
|
386
|
+
| policy-dust | policy-standardness |
|
|
387
|
+
| policy-subdust | policy-dust |
|
|
388
|
+
| policy-replacement | policy-standardness |
|
|
389
|
+
| policy-coinage | None |
|
|
390
|
+
| policy-reuse | policy-standardness |
|
|
391
|
+
| mining-template | policy-coinage, policy-carrier, policy-replacement |
|
|
392
|
+
| policy-parsing | runtime-config, policy-standardness, policy-carrier, policy-dust, policy-subdust, policy-replacement, policy-coinage, policy-reuse, mining-template |
|
|
393
|
+
| effective-policy | policy-parsing, runtime-config, policy-standardness, policy-carrier, policy-dust, policy-subdust, policy-replacement, policy-coinage, policy-reuse |
|
|
394
|
+
| peer-controls | policy-replacement |
|
|
395
|
+
| peer-health | peer-controls |
|
|
396
|
+
| wallet-foundation | build-portability |
|
|
397
|
+
| wallet-rbf | wallet-foundation, policy-replacement |
|
|
398
|
+
| wallet-sweep | wallet-foundation, wallet-rbf, runtime-config |
|
|
399
|
+
| wallet-coin-control | wallet-foundation, wallet-rbf |
|
|
400
|
+
| operator-stats | runtime-config |
|