mempool_args.cpp
1 // Copyright (c) 2022 The Bitcoin Core developers 2 // Distributed under the MIT software license, see the accompanying 3 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 5 #include <node/mempool_args.h> 6 7 #include <kernel/mempool_limits.h> 8 #include <kernel/mempool_options.h> 9 10 #include <common/args.h> 11 #include <common/messages.h> 12 #include <consensus/amount.h> 13 #include <kernel/chainparams.h> 14 #include <logging.h> 15 #include <policy/feerate.h> 16 #include <policy/policy.h> 17 #include <tinyformat.h> 18 #include <txgraph.h> 19 #include <util/moneystr.h> 20 #include <util/translation.h> 21 22 #include <chrono> 23 #include <memory> 24 25 using common::AmountErrMsg; 26 using kernel::MemPoolLimits; 27 using kernel::MemPoolOptions; 28 29 //! Maximum mempool size on 32-bit systems. 30 static constexpr int MAX_32BIT_MEMPOOL_MB{500}; 31 32 namespace { 33 void ApplyArgsManOptions(const ArgsManager& argsman, MemPoolLimits& mempool_limits) 34 { 35 mempool_limits.cluster_count = argsman.GetIntArg("-limitclustercount", mempool_limits.cluster_count); 36 37 if (auto vkb = argsman.GetIntArg("-limitclustersize")) mempool_limits.cluster_size_vbytes = *vkb * 1'000; 38 39 mempool_limits.ancestor_count = argsman.GetIntArg("-limitancestorcount", mempool_limits.ancestor_count); 40 41 mempool_limits.descendant_count = argsman.GetIntArg("-limitdescendantcount", mempool_limits.descendant_count); 42 } 43 } 44 45 util::Result<void> ApplyArgsManOptions(const ArgsManager& argsman, const CChainParams& chainparams, MemPoolOptions& mempool_opts) 46 { 47 mempool_opts.check_ratio = argsman.GetIntArg("-checkmempool", mempool_opts.check_ratio); 48 49 if (auto mb = argsman.GetIntArg("-maxmempool")) { 50 constexpr bool is_32bit{sizeof(void*) == 4}; 51 if (is_32bit && *mb > MAX_32BIT_MEMPOOL_MB) { 52 return util::Error{Untranslated(strprintf("-maxmempool is set to %i but can't be over %i MB on 32-bit systems", *mb, MAX_32BIT_MEMPOOL_MB))}; 53 } 54 mempool_opts.max_size_bytes = *mb * 1'000'000; 55 } 56 57 if (auto hours = argsman.GetIntArg("-mempoolexpiry")) mempool_opts.expiry = std::chrono::hours{*hours}; 58 59 // incremental relay fee sets the minimum feerate increase necessary for replacement in the mempool 60 // and the amount the mempool min fee increases above the feerate of txs evicted due to mempool limiting. 61 if (const auto arg{argsman.GetArg("-incrementalrelayfee")}) { 62 if (std::optional<CAmount> inc_relay_fee = ParseMoney(*arg)) { 63 mempool_opts.incremental_relay_feerate = CFeeRate{inc_relay_fee.value()}; 64 } else { 65 return util::Error{AmountErrMsg("incrementalrelayfee", *arg)}; 66 } 67 } 68 69 static_assert(DEFAULT_MIN_RELAY_TX_FEE == DEFAULT_INCREMENTAL_RELAY_FEE); 70 if (const auto arg{argsman.GetArg("-minrelaytxfee")}) { 71 if (std::optional<CAmount> min_relay_feerate = ParseMoney(*arg)) { 72 // High fee check is done afterward in CWallet::Create() 73 mempool_opts.min_relay_feerate = CFeeRate{min_relay_feerate.value()}; 74 } else { 75 return util::Error{AmountErrMsg("minrelaytxfee", *arg)}; 76 } 77 } else if (mempool_opts.incremental_relay_feerate > mempool_opts.min_relay_feerate) { 78 // Allow only setting incremental fee to control both 79 mempool_opts.min_relay_feerate = mempool_opts.incremental_relay_feerate; 80 LogInfo("Increasing minrelaytxfee to %s to match incrementalrelayfee", mempool_opts.min_relay_feerate.ToString()); 81 } 82 83 // Feerate used to define dust. Shouldn't be changed lightly as old 84 // implementations may inadvertently create non-standard transactions 85 if (const auto arg{argsman.GetArg("-dustrelayfee")}) { 86 if (std::optional<CAmount> parsed = ParseMoney(*arg)) { 87 mempool_opts.dust_relay_feerate = CFeeRate{parsed.value()}; 88 } else { 89 return util::Error{AmountErrMsg("dustrelayfee", *arg)}; 90 } 91 } 92 93 mempool_opts.permit_bare_multisig = argsman.GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG); 94 95 if (argsman.GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER)) { 96 mempool_opts.max_datacarrier_bytes = argsman.GetIntArg("-datacarriersize", MAX_OP_RETURN_RELAY); 97 } else { 98 mempool_opts.max_datacarrier_bytes = std::nullopt; 99 } 100 101 mempool_opts.require_standard = !argsman.GetBoolArg("-acceptnonstdtxn", DEFAULT_ACCEPT_NON_STD_TXN); 102 if (!chainparams.IsTestChain() && !mempool_opts.require_standard) { 103 return util::Error{Untranslated(strprintf("acceptnonstdtxn is not currently supported for %s chain", chainparams.GetChainTypeString()))}; 104 } 105 106 mempool_opts.persist_v1_dat = argsman.GetBoolArg("-persistmempoolv1", mempool_opts.persist_v1_dat); 107 108 ApplyArgsManOptions(argsman, mempool_opts.limits); 109 110 if (mempool_opts.limits.cluster_count > MAX_CLUSTER_COUNT_LIMIT) { 111 return util::Error{Untranslated(strprintf("limitclustercount must be less than or equal to %d", MAX_CLUSTER_COUNT_LIMIT))}; 112 } 113 114 return {}; 115 }