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. Before is on the left; after is on the right. Unified view fits narrow screens more easily.
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.
|