diff --git a/configure.ac b/configure.ac index b5116922f9..82af1655d0 100644 --- a/configure.ac +++ b/configure.ac @@ -1061,6 +1061,21 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [ AC_MSG_RESULT([no])] ) +AC_MSG_CHECKING(for compatible sysinfo call) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[ + struct sysinfo info; + int rv = sysinfo(&info); + unsigned long test = info.freeram + info.bufferram + info.mem_unit; + ]])], + [ + AC_MSG_RESULT(yes); + AC_DEFINE(HAVE_LINUX_SYSINFO, 1, [Define this symbol if you have a Linux-compatible sysinfo call]) + ],[ + AC_MSG_RESULT(no) + ] +) + dnl Check for posix_fallocate AC_MSG_CHECKING([for posix_fallocate]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ diff --git a/src/init.cpp b/src/init.cpp index 9974c4fec7..491f1b8949 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -441,6 +441,7 @@ void SetupServerArgs(ArgsManager& argsman) argsman.AddArg("-dbcache=", strprintf("Maximum database cache size MiB (%d to %d, default: %d). In addition, unused mempool memory is shared for this cache (see -maxmempool).", nMinDbCache, nMaxDbCache, nDefaultDbCache), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-includeconf=", "Specify additional configuration file, relative to the -datadir path (only useable from configuration file, not command line)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-loadblock=", "Imports blocks from external file on startup", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); + argsman.AddArg("-lowmem=", strprintf("If system available memory falls below MiB, flush caches (0 to disable, default: %s)", util::g_low_memory_threshold / 1024 / 1024), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-maxmempool=", strprintf("Keep the transaction memory pool below megabytes (default: %u)", DEFAULT_MAX_MEMPOOL_SIZE_MB), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-maxorphantx=", strprintf("Keep at most unconnectable transactions in memory (default: %u)", DEFAULT_MAX_ORPHAN_TRANSACTIONS), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-mempoolexpiry=", strprintf("Do not keep transactions in the mempool longer than hours (default: %u)", DEFAULT_MEMPOOL_EXPIRY_HOURS), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); @@ -586,7 +587,8 @@ void SetupServerArgs(ArgsManager& argsman) argsman.AddArg("-datacarriercost", strprintf("Treat extra data in transactions as at least N vbytes per actual byte (default: %s)", DEFAULT_WEIGHT_PER_DATA_BYTE / 4.0), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY); argsman.AddArg("-datacarrierfullcount", strprintf("Apply datacarriersize limit to all known datacarrier methods (default: %s)", DEFAULT_DATACARRIER_FULLCOUNT), ArgsManager::ALLOW_ANY | (DEFAULT_DATACARRIER_FULLCOUNT ? uint32_t{ArgsManager::DEBUG_ONLY} : 0), OptionsCategory::NODE_RELAY); argsman.AddArg("-datacarriersize", strprintf("Maximum size of data in data carrier transactions we relay and mine (default: %u)", MAX_OP_RETURN_RELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY); - argsman.AddArg("-mempoolfullrbf", strprintf("Accept transaction replace-by-fee without requiring replaceability signaling (default: %u)", DEFAULT_MEMPOOL_FULL_RBF), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY); + argsman.AddArg("-mempoolfullrbf", strprintf("Accept transaction replace-by-fee without requiring replaceability signaling (default: %u)", (DEFAULT_MEMPOOL_RBF_POLICY == RBFPolicy::Always)), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY); + argsman.AddArg("-mempoolreplacement", strprintf("Set to 0 to disable RBF entirely, \"fee,optin\" to honour RBF opt-out signal, or \"fee,-optin\" to always RBF aka full RBF (default: %s)", "fee,optin"), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY); argsman.AddArg("-permitbaremultisig", strprintf("Relay non-P2SH multisig (default: %u)", DEFAULT_PERMIT_BAREMULTISIG), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY); argsman.AddArg("-minrelaytxfee=", strprintf("Fees (in %s/kvB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)", @@ -1488,6 +1490,17 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) } LogPrintf("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)\n", cache_sizes.coins * (1.0 / 1024 / 1024), mempool_opts.max_size_bytes * (1.0 / 1024 / 1024)); + if (gArgs.IsArgSet("-lowmem")) { + util::g_low_memory_threshold = gArgs.GetIntArg("-lowmem", 0 /* not used */) * 1024 * 1024; + } + if (util::g_low_memory_threshold > 0) { + LogPrintf("* Flushing caches if available system memory drops below %s MiB\n", util::g_low_memory_threshold / 1024 / 1024); + } + + if (mempool_opts.rbf_policy == RBFPolicy::Always) { + nLocalServices = ServiceFlags(nLocalServices | NODE_REPLACE_BY_FEE); + } + for (bool fLoaded = false; !fLoaded && !ShutdownRequested();) { node.mempool = std::make_unique(mempool_opts); diff --git a/src/kernel/mempool_options.h b/src/kernel/mempool_options.h index 400d14ab92..20e25be5da 100644 --- a/src/kernel/mempool_options.h +++ b/src/kernel/mempool_options.h @@ -16,14 +16,16 @@ class CBlockPolicyEstimator; +enum class RBFPolicy { Never, OptIn, Always }; + /** Default for -maxmempool, maximum megabytes of mempool memory usage */ static constexpr unsigned int DEFAULT_MAX_MEMPOOL_SIZE_MB{300}; /** Default for -maxmempool when blocksonly is set */ static constexpr unsigned int DEFAULT_BLOCKSONLY_MAX_MEMPOOL_SIZE_MB{5}; /** Default for -mempoolexpiry, expiration time for mempool transactions in hours */ static constexpr unsigned int DEFAULT_MEMPOOL_EXPIRY_HOURS{336}; -/** Default for -mempoolfullrbf, if the transaction replaceability signaling is ignored */ -static constexpr bool DEFAULT_MEMPOOL_FULL_RBF{false}; +/** Default for -mempoolreplacement; must update docs in init.cpp manually */ +static constexpr RBFPolicy DEFAULT_MEMPOOL_RBF_POLICY{RBFPolicy::OptIn}; namespace kernel { /** @@ -55,7 +57,7 @@ struct MemPoolOptions { bool datacarrier_fullcount{DEFAULT_DATACARRIER_FULLCOUNT}; bool permit_bare_multisig{DEFAULT_PERMIT_BAREMULTISIG}; bool require_standard{true}; - bool full_rbf{DEFAULT_MEMPOOL_FULL_RBF}; + RBFPolicy rbf_policy{DEFAULT_MEMPOOL_RBF_POLICY}; MemPoolLimits limits{}; }; } // namespace kernel diff --git a/src/node/mempool_args.cpp b/src/node/mempool_args.cpp index 0671fe7714..545223a3ac 100644 --- a/src/node/mempool_args.cpp +++ b/src/node/mempool_args.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include