Skip to content
Bitcoin Roots

v31.1-roots.1 · Commit 3: [PATCH 03/17] feat(policy): preserve cluster accounting and repair dynamic dust

doc/feature-contracts/subdust.md

Before: doc/feature-contracts/subdust.md · After: doc/feature-contracts/subdust.md

File metadata
index dd0b72e6cb6817f252069a3f38d826754e565b69..ef891552313cdaa7b624d0c3bb243f3d0f38aa52 100644

Download original patch · Release notes

Diff rows 1–69 of 69. 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/subdust.md CHANGED
@@ -1,9 +1,65 @@
1
  # Sub-dust effective-fee contract
2
 
3
- **v31 candidate status: deferred to L8 graph policy.** 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
  Stable ID: **policy-subdust**. Depends on **policy-dust** and the shared local
 
1
  # Sub-dust effective-fee contract
2
 
3
+ **v31 candidate status: native graph accounting implemented in L8.1.**
4
+ The source contract below remains the preservation reference. Admission stores
5
+ an immutable dust deficit and carrier weight on each entry; actual fees and
6
+ transaction weight remain separate. Staging receives the final modified fee
7
+ before graph insertion. Native graph fee updates, replacement diagrams, block
8
+ removal, reorg dependency discovery and trimming use these same entry values.
9
+ Dynamic dust lifecycle is repaired in L8.2; priority selection and joint
10
+ mining-policy combinations remain L9. Runtime-config precedence remains L12.
11
+
12
+ Dynamic dust updates are node-owned: one task is registered after the final
13
+ successful chainstate load, updates immediately and every 15 minutes, and is
14
+ stopped/joined before the final mempool or estimator is destroyed. Failed/retried
15
+ constructors register no callbacks. The live rate and standardness snapshots
16
+ share the mempool lock. Updating the rate does not reprice resident entries;
17
+ new admission captures its own immutable deficit. Wallet dust queries and
18
+ ephemeral checks use the same published rate.
19
+
20
+ `off` remains the default. Target mode uses the initialized long-horizon raw
21
+ estimate at success threshold 0.8; unavailable/zero estimates fall back to the
22
+ configured dustrelayfee floor. Mempool mode walks native chunk/topological order
23
+ to the configured decimal-kvB position and uses that entry's actual fee divided
24
+ by its policy vsize, preserving the source boundary units and fee meaning.
25
+ An empty/short mempool also falls back to the floor. Scaling first quantizes the
26
+ estimate to sat/kvB, applies the thousandths multiplier with floor rounding, and
27
+ saturates at INT64_MAX without overflowing an intermediate multiplication.
28
+ These lifecycle/fallback/boundary semantics repair the documented source gaps.
29
+
30
+ The v31 adaptation makes numerical limits explicit. Fee-rate evaluation
31
+ saturates an unrepresentable signed-64-bit quotient; output thresholds then
32
+ saturate at `INT64_MAX`, followed by the existing deficit/subtraction saturation.
33
+ The graph reserves the sum of absolute modified fees across resident and staged
34
+ entries up to `INT64_MAX`, and adjusted weight up to `INT32_MAX`. Pending removals
35
+ remain reserved until commit. Out-of-budget admission fails locally with
36
+ `mempool-fee-overflow` or `too-large-cluster`; a resident fee delta that exhausts
37
+ the budget fails without changing either the entry, graph or persisted delta.
38
+ This conservative bound is an adaptation to native graph and diagram storage,
39
+ not a consensus limit or a change to actual transaction fees. It can reject
40
+ extreme replacement proposals even if the final graph alone would fit. The bound
41
+ is global, not per cluster: it also rejects cancelling positive/negative fees
42
+ whose absolute sum exceeds the limit, and independent clusters whose individual
43
+ fees fit but whose combined absolute fees do not. These are representable
44
+ combinations, not inherently overflowing transactions. Per-cluster bounds alone
45
+ would leave multi-cluster replacement diagrams and their cumulative `FeeFrac`
46
+ arithmetic unprotected; preserving those extremes requires a separate widening
47
+ of native graph arithmetic. This adapter deliberately reserves main and staged
48
+ states conservatively rather than widening native storage.
49
+ The existing local sigop-cost ceiling is checked before policy multiplication;
50
+ an extreme bytespersigop setting whose vsize exceeds CFeeRate's int32 domain is
51
+ rejected before narrowing. The sigop fixture verifies graceful local rejection
52
+ and acceptance of the same consensus-valid transaction in a block.
53
+ `amount_tests/FeeRateSaturatedEvaluation` and
54
+ `mempool_tests/GraphPolicyBudgetsAndReuseClaims` cover these limits.
55
+
56
+ `mempool_tests/GraphPolicyAccounting` checks staging/rollback, fee deltas,
57
+ block removal and reorg dependency restoration against native diagrams.
58
+ `mempool_subdust_fee_penalty.py` retains source fee, carrier, package/TRUC,
59
+ replacement and actual-reward fixtures; its priority-area portion is explicitly
60
+ owned by L9. `subdust_fee_penalty` retains L5's wide-integer admission oracle;
61
+ `carrier_policy_weight` independently checks output-carrier arithmetic and
62
+ entry sizes through the extra-weight clamp.
63
  [The port review](../roots-v31-port-review.md) records ownership and current gates.
64
 
65
  Stable ID: **policy-subdust**. Depends on **policy-dust** and the shared local