v31.1-roots.1 · Commit 3: [PATCH 03/17] feat(policy): preserve cluster accounting and repair dynamic dust
src/init.cpp
Before: src/init.cpp · After: src/init.cpp
File metadata
index ac87cf0a531d0b7d931d635cc72f5fb69b82a436..fed689af2441e05abd49f8e96f3ee94a83640d49 100644
Download original patch · Release notes
Diff rows 1–79 of 79. 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.
src/init.cpp
CHANGED
|
@@ -670,24 +670,24 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
|
|
| 670 |
SetupChainParamsBaseOptions(argsman);
|
| 671 |
|
| 672 |
argsman.AddArg("-acceptunknownwitness", strprintf("Relay transactions sending to unknown or future witness script versions (default: %u)", DEFAULT_ACCEPTUNKNOWNWITNESS) + " Values: 0 or 1; no value means 1.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 673 |
-
argsman.AddArg("-dustdynamic=<value>", "Staged parsing only; enforcement is deferred to L8 graph policy. See doc/feature-contracts/policy-parsing.md for accepted grammar.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
|
| 674 |
argsman.AddArg("-bytespersigopstrict", strprintf("Minimum bytes per sigop in transactions we relay and mine (integer 0 to 4294967295; default: %u)", DEFAULT_BYTES_PER_SIGOP_STRICT), ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 675 |
-
argsman.AddArg("-datacarriercost=<value>", "Staged parsing only; enforcement is deferred to L8 graph policy. See doc/feature-contracts/policy-parsing.md for accepted grammar.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
|
| 676 |
argsman.AddArg("-datacarrierfullcount", strprintf("Apply datacarriersize limit to all known data-carrier methods (default: %u)", DEFAULT_DATACARRIER_FULLCOUNT) + " Values: 0 or 1; no value means 1.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION | (DEFAULT_DATACARRIER_FULLCOUNT ? uint32_t{ArgsManager::DEBUG_ONLY} : 0), OptionsCategory::NODE_RELAY);
|
| 677 |
argsman.AddArg("-permitbaredatacarrier", strprintf("Relay transactions with data carrier outputs and no monetary outputs (default: %u)", DEFAULT_PERMITBAREDATACARRIER) + " Values: 0 or 1; no value means 1.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 678 |
argsman.AddArg("-acceptnonstddatacarrier", strprintf("Relay nonstandard data carrier outputs (default: %u)", DEFAULT_ACCEPT_NON_STD_DATACARRIER) + " Values: 0 or 1; no value means 1.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 679 |
argsman.AddArg("-permitephemeral", "Permit ephemeral policy exceptions: send, dust, anchor, reject, or 0, optionally prefixed with '-'. Tokens are separated by ',' or '+'; 0 disables all, empty or 1 enables all (default: anchor only)", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 680 |
-
argsman.AddArg("-subdustfeepenalty=<value>", "Staged parsing only; enforcement is deferred to L8 graph policy. See doc/feature-contracts/policy-parsing.md for accepted grammar.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
|
| 681 |
argsman.AddArg("-maxscriptsize=<n>", strprintf("Maximum size of scripts (including the witness stack) we relay and mine (integer 0 to 4294967295; default: %s)", DEFAULT_SCRIPT_SIZE_POLICY_LIMIT), ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 682 |
argsman.AddArg("-maxtxlegacysigops", strprintf("Maximum legacy sigops in transactions we relay and mine (integer 0 to 4294967295; default: %s)", MAX_TX_LEGACY_SIGOPS), ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 683 |
-
argsman.AddArg("-mempoolreplacement=<value>", "Staged parsing only; enforcement is deferred to L8 graph policy. See doc/feature-contracts/policy-parsing.md for accepted grammar.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
|
| 684 |
-
argsman.AddArg("-mempoolfullrbf", "Staged legacy alias; replacement enforcement is deferred to L8 graph policy.", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
|
| 685 |
-
argsman.AddArg("-mempooltruc=<value>", "Staged parsing only; enforcement is deferred to L8 graph policy. See doc/feature-contracts/policy-parsing.md for accepted grammar.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
|
| 686 |
argsman.AddArg("-minrelaycoinblocks=<n>", strprintf("Minimum coin blocks a transaction must spend to be relayed (integer 0 to 9223372036854775807; default: %s)", 0), ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 687 |
argsman.AddArg("-minrelaymaturity=<n>", strprintf("Minimum input maturity before relay (integer 0 to 2147483647; default: %s)", 0), ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 688 |
argsman.AddArg("-permitbareanchor", strprintf("Relay transactions that only have ephemeral anchor outputs (default: %u)", DEFAULT_PERMITBAREANCHOR) + " Values: 0 or 1; no value means 1.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 689 |
argsman.AddArg("-permitbarepubkey", strprintf("Relay legacy pubkey outputs (default: %u)", DEFAULT_PERMIT_BAREPUBKEY) + " Values: 0 or 1; no value means 1.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 690 |
-
argsman.AddArg("-spkreuse=<value>", "Staged parsing only; enforcement is deferred to L8 graph policy. See doc/feature-contracts/policy-parsing.md for accepted grammar.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
|
| 691 |
argsman.AddArg("-rejecttokens", strprintf("Refuse to relay or mine transactions involving non-bitcoin tokens (default: %u)", DEFAULT_REJECT_TOKENS) + " Values: 0 or 1; no value means 1.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 692 |
argsman.AddArg("-rejectparasites", strprintf("Refuse to relay or mine parasitic overlay protocols (default: %u)", DEFAULT_REJECT_PARASITES) + " Values: 0 or 1; no value means 1.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 693 |
argsman.AddArg("-blockmaxsize=<value>", "Staged parsing only; enforcement is deferred to L9 mining. See doc/feature-contracts/policy-parsing.md for accepted grammar.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
|
|
@@ -942,7 +942,7 @@ bool AppInitBasicSetup(const ArgsManager& args, std::atomic<int>& exit_status)
|
|
| 942 |
bool AppInitParameterInteraction(const ArgsManager& args)
|
| 943 |
{
|
| 944 |
if (auto result = ValidateRootsPolicyOptions(args); !result) return InitError(util::ErrorString(result));
|
| 945 |
-
for (const char* option : {"-datacarriercost", "-subdustfeepenalty", "-mempoolreplacement", "-mempoolfullrbf", "-mempooltruc", "-spkreuse", "-dustdynamic", "-blockmaxsize", "-blockprioritysize"}) {
|
| 946 |
if (args.IsArgSet(option)) {
|
| 947 |
InitWarning(Untranslated(strprintf("%s is parsed but not enforced in this staged candidate; graph policy and mining implementations are pending.", option)));
|
| 948 |
}
|
|
@@ -1181,6 +1181,9 @@ bool AppInitParameterInteraction(const ArgsManager& args)
|
|
| 1181 |
if (!mempool_result) {
|
| 1182 |
return InitError(util::ErrorString(mempool_result));
|
| 1183 |
}
|
|
|
|
|
|
|
|
|
|
| 1184 |
}
|
| 1185 |
|
| 1186 |
return true;
|
|
@@ -1919,6 +1922,31 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|
| 1919 |
return true;
|
| 1920 |
}
|
| 1921 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1922 |
ChainstateManager& chainman = *Assert(node.chainman);
|
| 1923 |
auto& kernel_notifications{*Assert(node.notifications)};
|
| 1924 |
|
|
|
|
| 670 |
SetupChainParamsBaseOptions(argsman);
|
| 671 |
|
| 672 |
argsman.AddArg("-acceptunknownwitness", strprintf("Relay transactions sending to unknown or future witness script versions (default: %u)", DEFAULT_ACCEPTUNKNOWNWITNESS) + " Values: 0 or 1; no value means 1.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 673 |
+
argsman.AddArg("-dustdynamic=<value>", "Update the dust rate every 15 minutes using off, [multiplier*]target:blocks, or [multiplier*]mempool:kvB (default: off). Multiplier defaults to 3; the configured dustrelayfee is the floor and fallback when no estimate is available.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 674 |
argsman.AddArg("-bytespersigopstrict", strprintf("Minimum bytes per sigop in transactions we relay and mine (integer 0 to 4294967295; default: %u)", DEFAULT_BYTES_PER_SIGOP_STRICT), ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 675 |
+
argsman.AddArg("-datacarriercost=<value>", "Treat data carrier bytes as at least N vbytes each (0 to 1073741823.75, exact hundredths; rounded up to quarter-vbytes; default: 1). Only local policy size changes.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 676 |
argsman.AddArg("-datacarrierfullcount", strprintf("Apply datacarriersize limit to all known data-carrier methods (default: %u)", DEFAULT_DATACARRIER_FULLCOUNT) + " Values: 0 or 1; no value means 1.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION | (DEFAULT_DATACARRIER_FULLCOUNT ? uint32_t{ArgsManager::DEBUG_ONLY} : 0), OptionsCategory::NODE_RELAY);
|
| 677 |
argsman.AddArg("-permitbaredatacarrier", strprintf("Relay transactions with data carrier outputs and no monetary outputs (default: %u)", DEFAULT_PERMITBAREDATACARRIER) + " Values: 0 or 1; no value means 1.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 678 |
argsman.AddArg("-acceptnonstddatacarrier", strprintf("Relay nonstandard data carrier outputs (default: %u)", DEFAULT_ACCEPT_NON_STD_DATACARRIER) + " Values: 0 or 1; no value means 1.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 679 |
argsman.AddArg("-permitephemeral", "Permit ephemeral policy exceptions: send, dust, anchor, reject, or 0, optionally prefixed with '-'. Tokens are separated by ',' or '+'; 0 disables all, empty or 1 enables all (default: anchor only)", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 680 |
+
argsman.AddArg("-subdustfeepenalty=<value>", "Subtract sub-dust output deficits from modified policy fees (default: 1). Values: 0 or 1; no value means 1. Actual fees and consensus validity are unchanged.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 681 |
argsman.AddArg("-maxscriptsize=<n>", strprintf("Maximum size of scripts (including the witness stack) we relay and mine (integer 0 to 4294967295; default: %s)", DEFAULT_SCRIPT_SIZE_POLICY_LIMIT), ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 682 |
argsman.AddArg("-maxtxlegacysigops", strprintf("Maximum legacy sigops in transactions we relay and mine (integer 0 to 4294967295; default: %s)", MAX_TX_LEGACY_SIGOPS), ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 683 |
+
argsman.AddArg("-mempoolreplacement=<value>", "Set RBF policy: 0 disables, fee,optin honors signaling or TRUC/v3 replaceability, and fee,-optin enables full RBF. Tokens are separated by ',' or '+'; empty or 1 enables fee-based replacement (default: fee,-optin).", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 684 |
+
argsman.AddArg("-mempoolfullrbf", "Legacy RBF alias: accept replacement without requiring signaling (default: 1). Explicit optin or replacement disabling overrides this alias.", ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
|
| 685 |
+
argsman.AddArg("-mempooltruc=<value>", "Set TRUC policy: reject, accept, enforce/optin, or -enforce/-optin. Tokens are separated by ',' or '+'; 0 rejects, empty or 1 enforces (default: enforce).", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 686 |
argsman.AddArg("-minrelaycoinblocks=<n>", strprintf("Minimum coin blocks a transaction must spend to be relayed (integer 0 to 9223372036854775807; default: %s)", 0), ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 687 |
argsman.AddArg("-minrelaymaturity=<n>", strprintf("Minimum input maturity before relay (integer 0 to 2147483647; default: %s)", 0), ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 688 |
argsman.AddArg("-permitbareanchor", strprintf("Relay transactions that only have ephemeral anchor outputs (default: %u)", DEFAULT_PERMITBAREANCHOR) + " Values: 0 or 1; no value means 1.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 689 |
argsman.AddArg("-permitbarepubkey", strprintf("Relay legacy pubkey outputs (default: %u)", DEFAULT_PERMIT_BAREPUBKEY) + " Values: 0 or 1; no value means 1.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 690 |
+
argsman.AddArg("-spkreuse=<value>", "Set local script reuse policy: allow or conflict; empty/1 aliases allow, 0 aliases conflict (default: allow).", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 691 |
argsman.AddArg("-rejecttokens", strprintf("Refuse to relay or mine transactions involving non-bitcoin tokens (default: %u)", DEFAULT_REJECT_TOKENS) + " Values: 0 or 1; no value means 1.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 692 |
argsman.AddArg("-rejectparasites", strprintf("Refuse to relay or mine parasitic overlay protocols (default: %u)", DEFAULT_REJECT_PARASITES) + " Values: 0 or 1; no value means 1.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION, OptionsCategory::NODE_RELAY);
|
| 693 |
argsman.AddArg("-blockmaxsize=<value>", "Staged parsing only; enforcement is deferred to L9 mining. See doc/feature-contracts/policy-parsing.md for accepted grammar.", ArgsManager::ALLOW_ANY | ArgsManager::STRICT_NEGATION | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
|
|
|
|
| 942 |
bool AppInitParameterInteraction(const ArgsManager& args)
|
| 943 |
{
|
| 944 |
if (auto result = ValidateRootsPolicyOptions(args); !result) return InitError(util::ErrorString(result));
|
| 945 |
+
for (const char* option : {"-blockmaxsize", "-blockprioritysize"}) {
|
| 946 |
if (args.IsArgSet(option)) {
|
| 947 |
InitWarning(Untranslated(strprintf("%s is parsed but not enforced in this staged candidate; graph policy and mining implementations are pending.", option)));
|
| 948 |
}
|
|
|
|
| 1181 |
if (!mempool_result) {
|
| 1182 |
return InitError(util::ErrorString(mempool_result));
|
| 1183 |
}
|
| 1184 |
+
if (mempool_opts.rbf_policy == RBFPolicy::Never && args.GetBoolArg("-mempoolfullrbf", false)) {
|
| 1185 |
+
InitWarning(_("False mempoolreplacement option contradicts true mempoolfullrbf; disallowing all RBF"));
|
| 1186 |
+
}
|
| 1187 |
}
|
| 1188 |
|
| 1189 |
return true;
|
|
|
|
| 1922 |
return true;
|
| 1923 |
}
|
| 1924 |
|
| 1925 |
+
// Register only after the final successful load: InitAndLoadChainstate may
|
| 1926 |
+
// destroy a failed attempt's mempool. Shutdown stops and joins the scheduler
|
| 1927 |
+
// before destroying the final mempool/estimator. Capture their node owner,
|
| 1928 |
+
// never a mempool pointer from a constructor or a retry attempt.
|
| 1929 |
+
if (status == ChainstateLoadStatus::SUCCESS && node.mempool->m_opts.dust_relay_target != 0) {
|
| 1930 |
+
const auto target{node.mempool->m_opts.dust_relay_target};
|
| 1931 |
+
if (target < 0 && node.fee_estimator && static_cast<unsigned>(-target) > node.fee_estimator->HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE)) {
|
| 1932 |
+
return InitError(_("Dynamic dust target exceeds the initialized fee estimator horizon"));
|
| 1933 |
+
}
|
| 1934 |
+
const auto update_dust = [&node] {
|
| 1935 |
+
if (ShutdownRequested(node)) return;
|
| 1936 |
+
const auto target{node.mempool->m_opts.dust_relay_target};
|
| 1937 |
+
std::optional<CFeeRate> estimate;
|
| 1938 |
+
if (target > 0) {
|
| 1939 |
+
estimate = node.mempool->EstimateDustFromMempool(target);
|
| 1940 |
+
} else if (node.fee_estimator) {
|
| 1941 |
+
estimate = node.fee_estimator->estimateRawFee(-target, 0.8, FeeEstimateHorizon::LONG_HALFLIFE);
|
| 1942 |
+
}
|
| 1943 |
+
node.mempool->UpdateDynamicDustFee(estimate);
|
| 1944 |
+
};
|
| 1945 |
+
update_dust();
|
| 1946 |
+
scheduler.scheduleEvery(update_dust, std::chrono::minutes{15});
|
| 1947 |
+
LogInfo("Dynamic dust updates scheduled after chainstate load");
|
| 1948 |
+
}
|
| 1949 |
+
|
| 1950 |
ChainstateManager& chainman = *Assert(node.chainman);
|
| 1951 |
auto& kernel_notifications{*Assert(node.notifications)};
|
| 1952 |
|