aboutsummaryrefslogtreecommitdiff
path: root/src/node
diff options
context:
space:
mode:
Diffstat (limited to 'src/node')
-rw-r--r--src/node/blockstorage.cpp6
-rw-r--r--src/node/interfaces.cpp76
-rw-r--r--src/node/mempool_args.cpp99
-rw-r--r--src/node/mempool_args.h27
-rw-r--r--src/node/psbt.cpp2
-rw-r--r--src/node/validation_cache_args.cpp34
-rw-r--r--src/node/validation_cache_args.h17
7 files changed, 217 insertions, 44 deletions
diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp
index 6815fcd24d..42b6b017fe 100644
--- a/src/node/blockstorage.cpp
+++ b/src/node/blockstorage.cpp
@@ -21,6 +21,7 @@
#include <util/system.h>
#include <validation.h>
+#include <map>
#include <unordered_map>
namespace node {
@@ -834,6 +835,9 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile
// -reindex
if (fReindex) {
int nFile = 0;
+ // Map of disk positions for blocks with unknown parent (only used for reindex);
+ // parent hash -> child disk position, multiple children can have the same parent.
+ std::multimap<uint256, FlatFilePos> blocks_with_unknown_parent;
while (true) {
FlatFilePos pos(nFile, 0);
if (!fs::exists(GetBlockPosFilename(pos))) {
@@ -844,7 +848,7 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile
break; // This error is logged in OpenBlockFile
}
LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
- chainman.ActiveChainstate().LoadExternalBlockFile(file, &pos);
+ chainman.ActiveChainstate().LoadExternalBlockFile(file, &pos, &blocks_with_unknown_parent);
if (ShutdownRequested()) {
LogPrintf("Shutdown requested. Exit %s\n", __func__);
return;
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
index be7e3992f0..2c845d0127 100644
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -36,7 +36,6 @@
#include <shutdown.h>
#include <support/allocators/secure.h>
#include <sync.h>
-#include <timedata.h>
#include <txmempool.h>
#include <uint256.h>
#include <univalue.h>
@@ -67,6 +66,8 @@ using interfaces::Node;
using interfaces::WalletLoader;
namespace node {
+// All members of the classes in this namespace are intentionally public, as the
+// classes themselves are private.
namespace {
#ifdef ENABLE_EXTERNAL_SIGNER
class ExternalSignerImpl : public interfaces::ExternalSigner
@@ -74,15 +75,12 @@ class ExternalSignerImpl : public interfaces::ExternalSigner
public:
ExternalSignerImpl(::ExternalSigner signer) : m_signer(std::move(signer)) {}
std::string getName() override { return m_signer.m_name; }
-private:
::ExternalSigner m_signer;
};
#endif
class NodeImpl : public Node
{
-private:
- ChainstateManager& chainman() { return *Assert(m_context->chainman); }
public:
explicit NodeImpl(NodeContext& context) { setContext(&context); }
void initLogging() override { InitLogging(*Assert(m_context->args)); }
@@ -289,12 +287,7 @@ public:
}
double getVerificationProgress() override
{
- const CBlockIndex* tip;
- {
- LOCK(::cs_main);
- tip = chainman().ActiveChain().Tip();
- }
- return GuessVerificationProgress(chainman().GetParams().TxData(), tip);
+ return GuessVerificationProgress(chainman().GetParams().TxData(), WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip()));
}
bool isInitialBlockDownload() override {
return chainman().ActiveChainstate().IsInitialBlockDownload();
@@ -308,7 +301,11 @@ public:
}
}
bool getNetworkActive() override { return m_context->connman && m_context->connman->GetNetworkActive(); }
- CFeeRate getDustRelayFee() override { return ::dustRelayFee; }
+ CFeeRate getDustRelayFee() override
+ {
+ if (!m_context->mempool) return CFeeRate{DUST_RELAY_TX_FEE};
+ return m_context->mempool->m_dust_relay_feerate;
+ }
UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) override
{
JSONRPCRequest req;
@@ -390,6 +387,7 @@ public:
{
m_context = context;
}
+ ChainstateManager& chainman() { return *Assert(m_context->chainman); }
NodeContext* m_context{nullptr};
};
@@ -502,40 +500,28 @@ public:
class ChainImpl : public Chain
{
-private:
- ChainstateManager& chainman() { return *Assert(m_node.chainman); }
public:
explicit ChainImpl(NodeContext& node) : m_node(node) {}
std::optional<int> getHeight() override
{
- LOCK(::cs_main);
- const CChain& active = chainman().ActiveChain();
- int height = active.Height();
- if (height >= 0) {
- return height;
- }
- return std::nullopt;
+ const int height{WITH_LOCK(::cs_main, return chainman().ActiveChain().Height())};
+ return height >= 0 ? std::optional{height} : std::nullopt;
}
uint256 getBlockHash(int height) override
{
LOCK(::cs_main);
- const CChain& active = chainman().ActiveChain();
- CBlockIndex* block = active[height];
- assert(block);
- return block->GetBlockHash();
+ return Assert(chainman().ActiveChain()[height])->GetBlockHash();
}
bool haveBlockOnDisk(int height) override
{
LOCK(::cs_main);
- const CChain& active = chainman().ActiveChain();
- CBlockIndex* block = active[height];
+ const CBlockIndex* block{chainman().ActiveChain()[height]};
return block && ((block->nStatus & BLOCK_HAVE_DATA) != 0) && block->nTx > 0;
}
CBlockLocator getTipLocator() override
{
LOCK(::cs_main);
- const CChain& active = chainman().ActiveChain();
- return active.GetLocator();
+ return chainman().ActiveChain().GetLocator();
}
CBlockLocator getActiveChainLocator(const uint256& block_hash) override
{
@@ -547,8 +533,7 @@ public:
std::optional<int> findLocatorFork(const CBlockLocator& locator) override
{
LOCK(::cs_main);
- const CChainState& active = chainman().ActiveChainstate();
- if (const CBlockIndex* fork = active.FindForkInGlobalIndex(locator)) {
+ if (const CBlockIndex* fork = chainman().ActiveChainstate().FindForkInGlobalIndex(locator)) {
return fork->nHeight;
}
return std::nullopt;
@@ -556,8 +541,7 @@ public:
bool findBlock(const uint256& hash, const FoundBlock& block) override
{
WAIT_LOCK(cs_main, lock);
- const CChain& active = chainman().ActiveChain();
- return FillBlock(chainman().m_blockman.LookupBlockIndex(hash), block, lock, active);
+ return FillBlock(chainman().m_blockman.LookupBlockIndex(hash), block, lock, chainman().ActiveChain());
}
bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock& block) override
{
@@ -579,11 +563,10 @@ public:
bool findAncestorByHash(const uint256& block_hash, const uint256& ancestor_hash, const FoundBlock& ancestor_out) override
{
WAIT_LOCK(cs_main, lock);
- const CChain& active = chainman().ActiveChain();
const CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash);
const CBlockIndex* ancestor = chainman().m_blockman.LookupBlockIndex(ancestor_hash);
if (block && ancestor && block->GetAncestor(ancestor->nHeight) != ancestor) ancestor = nullptr;
- return FillBlock(ancestor, ancestor_out, lock, active);
+ return FillBlock(ancestor, ancestor_out, lock, chainman().ActiveChain());
}
bool findCommonAncestor(const uint256& block_hash1, const uint256& block_hash2, const FoundBlock& ancestor_out, const FoundBlock& block1_out, const FoundBlock& block2_out) override
{
@@ -697,9 +680,21 @@ public:
if (!m_node.mempool) return {};
return m_node.mempool->GetMinFee();
}
- CFeeRate relayMinFee() override { return ::minRelayTxFee; }
- CFeeRate relayIncrementalFee() override { return ::incrementalRelayFee; }
- CFeeRate relayDustFee() override { return ::dustRelayFee; }
+ CFeeRate relayMinFee() override
+ {
+ if (!m_node.mempool) return CFeeRate{DEFAULT_MIN_RELAY_TX_FEE};
+ return m_node.mempool->m_min_relay_feerate;
+ }
+ CFeeRate relayIncrementalFee() override
+ {
+ if (!m_node.mempool) return CFeeRate{DEFAULT_INCREMENTAL_RELAY_FEE};
+ return m_node.mempool->m_incremental_relay_feerate;
+ }
+ CFeeRate relayDustFee() override
+ {
+ if (!m_node.mempool) return CFeeRate{DUST_RELAY_TX_FEE};
+ return m_node.mempool->m_dust_relay_feerate;
+ }
bool havePruned() override
{
LOCK(::cs_main);
@@ -723,11 +718,7 @@ public:
}
void waitForNotificationsIfTipChanged(const uint256& old_tip) override
{
- if (!old_tip.IsNull()) {
- LOCK(::cs_main);
- const CChain& active = chainman().ActiveChain();
- if (old_tip == active.Tip()->GetBlockHash()) return;
- }
+ if (!old_tip.IsNull() && old_tip == WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip()->GetBlockHash())) return;
SyncWithValidationInterfaceQueue();
}
std::unique_ptr<Handler> handleRpc(const CRPCCommand& command) override
@@ -783,6 +774,7 @@ public:
}
NodeContext* context() override { return &m_node; }
+ ChainstateManager& chainman() { return *Assert(m_node.chainman); }
NodeContext& m_node;
};
} // namespace
diff --git a/src/node/mempool_args.cpp b/src/node/mempool_args.cpp
new file mode 100644
index 0000000000..60993f1d8d
--- /dev/null
+++ b/src/node/mempool_args.cpp
@@ -0,0 +1,99 @@
+// Copyright (c) 2022 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <node/mempool_args.h>
+
+#include <kernel/mempool_limits.h>
+#include <kernel/mempool_options.h>
+
+#include <chainparams.h>
+#include <consensus/amount.h>
+#include <logging.h>
+#include <policy/feerate.h>
+#include <policy/policy.h>
+#include <tinyformat.h>
+#include <util/error.h>
+#include <util/moneystr.h>
+#include <util/system.h>
+#include <util/translation.h>
+
+#include <chrono>
+#include <memory>
+
+using kernel::MemPoolLimits;
+using kernel::MemPoolOptions;
+
+namespace {
+void ApplyArgsManOptions(const ArgsManager& argsman, MemPoolLimits& mempool_limits)
+{
+ mempool_limits.ancestor_count = argsman.GetIntArg("-limitancestorcount", mempool_limits.ancestor_count);
+
+ if (auto vkb = argsman.GetIntArg("-limitancestorsize")) mempool_limits.ancestor_size_vbytes = *vkb * 1'000;
+
+ mempool_limits.descendant_count = argsman.GetIntArg("-limitdescendantcount", mempool_limits.descendant_count);
+
+ if (auto vkb = argsman.GetIntArg("-limitdescendantsize")) mempool_limits.descendant_size_vbytes = *vkb * 1'000;
+}
+}
+
+std::optional<bilingual_str> ApplyArgsManOptions(const ArgsManager& argsman, const CChainParams& chainparams, MemPoolOptions& mempool_opts)
+{
+ mempool_opts.check_ratio = argsman.GetIntArg("-checkmempool", mempool_opts.check_ratio);
+
+ if (auto mb = argsman.GetIntArg("-maxmempool")) mempool_opts.max_size_bytes = *mb * 1'000'000;
+
+ if (auto hours = argsman.GetIntArg("-mempoolexpiry")) mempool_opts.expiry = std::chrono::hours{*hours};
+
+ // incremental relay fee sets the minimum feerate increase necessary for BIP 125 replacement in the mempool
+ // and the amount the mempool min fee increases above the feerate of txs evicted due to mempool limiting.
+ if (argsman.IsArgSet("-incrementalrelayfee")) {
+ if (std::optional<CAmount> inc_relay_fee = ParseMoney(argsman.GetArg("-incrementalrelayfee", ""))) {
+ mempool_opts.incremental_relay_feerate = CFeeRate{inc_relay_fee.value()};
+ } else {
+ return AmountErrMsg("incrementalrelayfee", argsman.GetArg("-incrementalrelayfee", ""));
+ }
+ }
+
+ if (argsman.IsArgSet("-minrelaytxfee")) {
+ if (std::optional<CAmount> min_relay_feerate = ParseMoney(argsman.GetArg("-minrelaytxfee", ""))) {
+ // High fee check is done afterward in CWallet::Create()
+ mempool_opts.min_relay_feerate = CFeeRate{min_relay_feerate.value()};
+ } else {
+ return AmountErrMsg("minrelaytxfee", argsman.GetArg("-minrelaytxfee", ""));
+ }
+ } else if (mempool_opts.incremental_relay_feerate > mempool_opts.min_relay_feerate) {
+ // Allow only setting incremental fee to control both
+ mempool_opts.min_relay_feerate = mempool_opts.incremental_relay_feerate;
+ LogPrintf("Increasing minrelaytxfee to %s to match incrementalrelayfee\n", mempool_opts.min_relay_feerate.ToString());
+ }
+
+ // Feerate used to define dust. Shouldn't be changed lightly as old
+ // implementations may inadvertently create non-standard transactions
+ if (argsman.IsArgSet("-dustrelayfee")) {
+ if (std::optional<CAmount> parsed = ParseMoney(argsman.GetArg("-dustrelayfee", ""))) {
+ mempool_opts.dust_relay_feerate = CFeeRate{parsed.value()};
+ } else {
+ return AmountErrMsg("dustrelayfee", argsman.GetArg("-dustrelayfee", ""));
+ }
+ }
+
+ mempool_opts.permit_bare_multisig = argsman.GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG);
+
+ if (argsman.GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER)) {
+ mempool_opts.max_datacarrier_bytes = argsman.GetIntArg("-datacarriersize", MAX_OP_RETURN_RELAY);
+ } else {
+ mempool_opts.max_datacarrier_bytes = std::nullopt;
+ }
+
+ mempool_opts.require_standard = !argsman.GetBoolArg("-acceptnonstdtxn", !chainparams.RequireStandard());
+ if (!chainparams.IsTestChain() && !mempool_opts.require_standard) {
+ return strprintf(Untranslated("acceptnonstdtxn is not currently supported for %s chain"), chainparams.NetworkIDString());
+ }
+
+ mempool_opts.full_rbf = argsman.GetBoolArg("-mempoolfullrbf", mempool_opts.full_rbf);
+
+ ApplyArgsManOptions(argsman, mempool_opts.limits);
+
+ return std::nullopt;
+}
diff --git a/src/node/mempool_args.h b/src/node/mempool_args.h
new file mode 100644
index 0000000000..52d8b4f265
--- /dev/null
+++ b/src/node/mempool_args.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2022 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_NODE_MEMPOOL_ARGS_H
+#define BITCOIN_NODE_MEMPOOL_ARGS_H
+
+#include <optional>
+
+class ArgsManager;
+class CChainParams;
+struct bilingual_str;
+namespace kernel {
+struct MemPoolOptions;
+};
+
+/**
+ * Overlay the options set in \p argsman on top of corresponding members in \p mempool_opts.
+ * Returns an error if one was encountered.
+ *
+ * @param[in] argsman The ArgsManager in which to check set options.
+ * @param[in,out] mempool_opts The MemPoolOptions to modify according to \p argsman.
+ */
+[[nodiscard]] std::optional<bilingual_str> ApplyArgsManOptions(const ArgsManager& argsman, const CChainParams& chainparams, kernel::MemPoolOptions& mempool_opts);
+
+
+#endif // BITCOIN_NODE_MEMPOOL_ARGS_H
diff --git a/src/node/psbt.cpp b/src/node/psbt.cpp
index 5a932f435d..57162cd679 100644
--- a/src/node/psbt.cpp
+++ b/src/node/psbt.cpp
@@ -137,7 +137,7 @@ PSBTAnalysis AnalyzePSBT(PartiallySignedTransaction psbtx)
if (success) {
CTransaction ctx = CTransaction(mtx);
- size_t size = GetVirtualTransactionSize(ctx, GetTransactionSigOpCost(ctx, view, STANDARD_SCRIPT_VERIFY_FLAGS));
+ size_t size(GetVirtualTransactionSize(ctx, GetTransactionSigOpCost(ctx, view, STANDARD_SCRIPT_VERIFY_FLAGS), ::nBytesPerSigOp));
result.estimated_vsize = size;
// Estimate fee rate
CFeeRate feerate(fee, size);
diff --git a/src/node/validation_cache_args.cpp b/src/node/validation_cache_args.cpp
new file mode 100644
index 0000000000..5ea0a8ca0a
--- /dev/null
+++ b/src/node/validation_cache_args.cpp
@@ -0,0 +1,34 @@
+// Copyright (c) 2022 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <node/validation_cache_args.h>
+
+#include <kernel/validation_cache_sizes.h>
+
+#include <util/system.h>
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <optional>
+
+using kernel::ValidationCacheSizes;
+
+namespace node {
+void ApplyArgsManOptions(const ArgsManager& argsman, ValidationCacheSizes& cache_sizes)
+{
+ if (auto max_size = argsman.GetIntArg("-maxsigcachesize")) {
+ // 1. When supplied with a max_size of 0, both InitSignatureCache and
+ // InitScriptExecutionCache create the minimum possible cache (2
+ // elements). Therefore, we can use 0 as a floor here.
+ // 2. Multiply first, divide after to avoid integer truncation.
+ size_t clamped_size_each = std::max<int64_t>(*max_size, 0) * (1 << 20) / 2;
+ cache_sizes = {
+ .signature_cache_bytes = clamped_size_each,
+ .script_execution_cache_bytes = clamped_size_each,
+ };
+ }
+}
+} // namespace node
diff --git a/src/node/validation_cache_args.h b/src/node/validation_cache_args.h
new file mode 100644
index 0000000000..f447c13b49
--- /dev/null
+++ b/src/node/validation_cache_args.h
@@ -0,0 +1,17 @@
+// Copyright (c) 2022 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_NODE_VALIDATION_CACHE_ARGS_H
+#define BITCOIN_NODE_VALIDATION_CACHE_ARGS_H
+
+class ArgsManager;
+namespace kernel {
+struct ValidationCacheSizes;
+};
+
+namespace node {
+void ApplyArgsManOptions(const ArgsManager& argsman, kernel::ValidationCacheSizes& cache_sizes);
+} // namespace node
+
+#endif // BITCOIN_NODE_VALIDATION_CACHE_ARGS_H