v31.1-roots.1 · Commit 1: [PATCH 01/17] build(roots): establish v31 portability foundation
doc/feature-contracts/effective-policy.md
Before: /dev/null · After: doc/feature-contracts/effective-policy.md
File metadata
new file mode 100644 index 0000000000000000000000000000000000000000..c53e2ef750ebdd0bdb275229b1fdd3edfdc210ff
Download original patch · Release notes
Diff rows 1–121 of 121. 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/feature-contracts/effective-policy.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Effective mempool policy (`effective-policy`)
|
|
2
|
+
|
|
3
|
+
**v31 candidate status: deferred.** This preserved contract describes the
|
|
4
|
+
accepted 30.3 source, including its documented gaps; the foundation does not
|
|
5
|
+
implement its Roots controls or RPC fields. Source code/test paths below refer
|
|
6
|
+
to `10d772eb7f4b00b5193428a0dde4c06558d6c297`, not current candidate behavior.
|
|
7
|
+
[The port review](../roots-v31-port-review.md) records ownership and current gates.
|
|
8
|
+
|
|
9
|
+
## Scope and compatibility
|
|
10
|
+
|
|
11
|
+
The additive `getmempoolinfo.policy` object reports initialized local transaction
|
|
12
|
+
admission controls. It does not describe consensus validity, peer permissions,
|
|
13
|
+
wallet preferences, per-call bypasses, or mining-template limits. A transaction
|
|
14
|
+
rejected by local policy can still appear in a valid block. This RPC neither
|
|
15
|
+
changes policy nor adds a runtime configuration interface.
|
|
16
|
+
|
|
17
|
+
Existing top-level fields retain their names, types and meanings. In particular,
|
|
18
|
+
`minrelaytxfee`, `incrementalrelayfee` and `mempoolminfee` already report effective
|
|
19
|
+
fee rates in BTC/kvB (1,000 virtual bytes); the ordinary defaults are 0.00001000,
|
|
20
|
+
0.00000100 and 0.00001000 respectively. The initialized incremental rate is
|
|
21
|
+
100 sat/kvB even though inherited startup help says 1,000. `mempoolminfee` can
|
|
22
|
+
rise with mempool pressure. `maxmempool` already reports the initialized memory
|
|
23
|
+
limit in bytes. These fields are not duplicated inside `policy`.
|
|
24
|
+
|
|
25
|
+
All fields below are always present, with no omitted or null values. Numbers
|
|
26
|
+
other than `dust_relay_fee` are JSON integers. Disabled carrier admission is
|
|
27
|
+
distinguished from an enabled zero-byte budget by `datacarrier`. False Boolean
|
|
28
|
+
values disable or deny the named behavior, subject to the gates below. Consumers
|
|
29
|
+
must allow additional fields; changing existing types, units or enum meanings
|
|
30
|
+
requires a separately reviewed compatibility decision. Ordinary defaults below
|
|
31
|
+
assume no policy overrides; network and internal parameter interaction may
|
|
32
|
+
select different initialized values.
|
|
33
|
+
|
|
34
|
+
## Schema
|
|
35
|
+
|
|
36
|
+
| Field | Type / units | Default | Meaning and enforcement gate |
|
|
37
|
+
| --- | --- | --- | --- |
|
|
38
|
+
| `require_standard` | Boolean | true | Enables transaction/input/witness standardness checks; false does not disable the other admission checks below. |
|
|
39
|
+
| `max_script_size` | Integer / bytes | 1650 | Script policy bound under standardness; scriptSig is additionally capped at 1650 bytes. Zero is a zero-byte bound, not disabled. |
|
|
40
|
+
| `bytes_per_sigop` | Integer / virtual bytes per sigop | 20 | Policy virtual-size accounting parameter, including fee/size checks; zero removes this size contribution. |
|
|
41
|
+
| `bytes_per_sigop_strict` | Integer / equivalent bytes per sigop | 20 | Accurate sigop density bound independent of standardness; zero disables this additional density check. Fixed sigop limits still apply. |
|
|
42
|
+
| `max_tx_legacy_sigops` | Integer / sigops | 2500 | Legacy transaction sigop bound under standardness; zero is a zero-sigop bound. |
|
|
43
|
+
| `datacarrier` | Boolean | true | Whether an OP_RETURN carrier budget exists; false denies carriers under standardness/full-count checking. |
|
|
44
|
+
| `max_datacarrier_bytes` | Integer / bytes | 83 | Aggregate serialized carrier budget; zero when datacarrier is disabled, or when an enabled budget is explicitly zero. |
|
|
45
|
+
| `datacarrier_fullcount` | Boolean | true | Count recognized input/witness carriers too; the aggregate check applies independently of standardness when true. |
|
|
46
|
+
| `datacarrier_weight_per_byte` | Integer / weight units per detected byte | 4 | Initialized rounded-up carrier cost (four weight units per virtual byte). Extra policy weight is added only where this exceeds the byte's existing weight, never reducing consensus weight. Zero adds no extra weight. |
|
|
47
|
+
| `accept_nonstd_datacarrier` | Boolean | false | Permit recognized nonstandard carriers independently of standardness; does not disable the full-count aggregate budget. |
|
|
48
|
+
| `permit_bare_datacarrier` | Boolean | false | Permit carrier-only transactions under standardness. |
|
|
49
|
+
| `dust_relay_fee` | JSON number / BTC per kvB | 0.00003000 | Live rate used to calculate output dust thresholds and the sub-dust penalty; zero makes those thresholds zero. |
|
|
50
|
+
| `subdust_fee_penalty` | Boolean | true | Subtract accumulated output dust shortfalls from policy modified fees, independently of standardness. |
|
|
51
|
+
| `permit_bare_pubkey` | Boolean | false | Permit bare pubkey outputs under standardness. |
|
|
52
|
+
| `permit_bare_multisig` | Boolean | false | Permit bare multisig outputs under standardness; equals the existing top-level field. |
|
|
53
|
+
| `reject_parasites` | Boolean | true | Reject the CAT21 locktime marker under standardness. |
|
|
54
|
+
| `reject_tokens` | Boolean | false | Enable recognized token filters under standardness. |
|
|
55
|
+
| `accept_unknown_witness` | Boolean | true | Permit unknown witness output versions under standardness. |
|
|
56
|
+
| `permit_bare_anchor` | Boolean | true | Permit transactions with only anchor outputs under standardness. |
|
|
57
|
+
| `ephemeral_anchor` | Boolean | true | Permit anchor outputs under standardness. |
|
|
58
|
+
| `ephemeral_dust` | Boolean | false | Permit nonzero ephemeral dust under standardness, subject to other dust/package rules. |
|
|
59
|
+
| `ephemeral_send` | Boolean | false | Permit non-anchor dust outputs under standardness, subject to other dust/package rules. |
|
|
60
|
+
| `replacement` | String enum | `always` | `never`, `optin`, or `always`; resolved replacement mode, not a guarantee of replacement. Opt-in also permits non-signaling TRUC/v3 replacements. |
|
|
61
|
+
| `truc` | String enum | `enforce` | `reject`, `accept`, or `enforce`; resolved local v3 admission/topology policy. |
|
|
62
|
+
| `min_relay_coinblocks` | Integer / satoshi-blocks | 0 | Minimum sum of input value times confirmations; zero disables this age restriction. |
|
|
63
|
+
| `min_relay_maturity` | Integer / blocks | 0 | Minimum input confirmation age restriction; zero disables it. |
|
|
64
|
+
| `spk_reuse` | String enum | `allow` | `allow` or `conflict`; initialized script reuse mode for mempool conflicts, independent of standardness. |
|
|
65
|
+
|
|
66
|
+
Allow flags are permissions within the active policy, not unconditional admission
|
|
67
|
+
guarantees. In particular `require_standard=false` bypasses the checks explicitly
|
|
68
|
+
gated by standardness; their initialized parameters remain visible so operators
|
|
69
|
+
can distinguish the gate from its subordinate settings. Full-count carrier
|
|
70
|
+
checks, nonstandard-carrier rejection, fee penalties, strict sigop density,
|
|
71
|
+
replacement/TRUC and maturity restrictions have independent gates. Existing
|
|
72
|
+
package, dust, fixed limits and consensus checks remain applicable.
|
|
73
|
+
|
|
74
|
+
## Provenance, precedence and consistency
|
|
75
|
+
|
|
76
|
+
Read `CTxMemPool::m_opts` for initialized mempool controls, `GetDustRelayFee()`
|
|
77
|
+
for the live dust rate, the initialized policy globals for script/size parameters,
|
|
78
|
+
and `SpkReuseMode` for reuse policy. Do not reread argument strings, reconstruct
|
|
79
|
+
defaults, or introduce another configuration store. Constructor normalization
|
|
80
|
+
matters: the dust floor is initialized from the selected dust fee. RBF/TRUC and
|
|
81
|
+
ephemeral token options resolve to modes/flags, not the original spellings;
|
|
82
|
+
carrier cost is rounded upward to integral weight units. If incremental relay
|
|
83
|
+
fee is increased and minrelaytxfee was not explicit, the minimum relay fee is
|
|
84
|
+
raised to match it.
|
|
85
|
+
|
|
86
|
+
Startup selection follows `runtime-config` and `policy-parsing`: forced settings,
|
|
87
|
+
CLI, read/write config, JSON settings, network config, default config, built-in
|
|
88
|
+
defaults; scalar CLI chooses its last value and config its first after negation
|
|
89
|
+
processing. Only initialized results are published. Invalid effective options
|
|
90
|
+
prevent startup and therefore produce no RPC response.
|
|
91
|
+
|
|
92
|
+
Build the new object inside the existing `MempoolInfoToJSON` mempool critical
|
|
93
|
+
section. The mempool fields and live rates share that observation with existing
|
|
94
|
+
top-level fields; no cross-RPC or transaction-admission snapshot is promised.
|
|
95
|
+
The globals and option controls above are startup-only in this implementation
|
|
96
|
+
and initialized before RPC warmup finishes. The live dust rate and top-level
|
|
97
|
+
rolling minimum are read with existing locking; there is no policy setter RPC.
|
|
98
|
+
|
|
99
|
+
Non-off `dustdynamic` currently fails startup because production scheduler wiring
|
|
100
|
+
is missing. Reporting a live dust rate does not imply that dynamic modes operate
|
|
101
|
+
in this revision. Dormant `getmempoolstats` is outside this contract. Mining
|
|
102
|
+
options are reconstructed and clamped by individual block assemblers, with no
|
|
103
|
+
single retained active instance to report here; this mempool schema deliberately
|
|
104
|
+
does not claim to represent their limits.
|
|
105
|
+
|
|
106
|
+
## Acceptance and dependencies
|
|
107
|
+
|
|
108
|
+
Depends on `policy-parsing`, `runtime-config`, `policy-standardness`,
|
|
109
|
+
`policy-carrier`, `policy-dust`, `policy-subdust`, `policy-replacement`,
|
|
110
|
+
`policy-coinage` and `policy-reuse`.
|
|
111
|
+
`rpc_effective_policy.py` specifies defaults, initialized overrides, disabled
|
|
112
|
+
controls, resolved aliases, precedence, invalid startup and reporting/admission
|
|
113
|
+
parity, including standardness-independent full carrier counting and a valid
|
|
114
|
+
block containing a locally rejected carrier transaction. The existing
|
|
115
|
+
`feature_policy_args.py`, `mempool_datacarrier.py` and
|
|
116
|
+
`mempool_subdust_fee_penalty.py` establish parsing and representative enforcement
|
|
117
|
+
before the new RPC is implemented. Keep their valid-block acceptance coverage.
|
|
118
|
+
|
|
119
|
+
Retire a version-specific reporting implementation only when a reviewed upstream
|
|
120
|
+
interface provides equivalent initialized values, units, gates, consistency and
|
|
121
|
+
acceptance evidence. Raw configuration echoing is not equivalent.
|