Skip to content
Bitcoin Roots

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.