aboutsummaryrefslogtreecommitdiff
path: root/src/node/interfaces.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/node/interfaces.cpp')
-rw-r--r--src/node/interfaces.cpp219
1 files changed, 137 insertions, 82 deletions
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
index cb063ae9f8..aa7ddec770 100644
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -19,10 +19,11 @@
#include <netaddress.h>
#include <netbase.h>
#include <node/blockstorage.h>
+#include <kernel/chain.h>
#include <node/coin.h>
#include <node/context.h>
#include <node/transaction.h>
-#include <node/ui_interface.h>
+#include <node/interface_ui.h>
#include <policy/feerate.h>
#include <policy/fees.h>
#include <policy/policy.h>
@@ -35,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>
@@ -66,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
@@ -73,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)); }
@@ -90,8 +89,16 @@ public:
uint32_t getLogCategories() override { return LogInstance().GetCategoryMask(); }
bool baseInitialize() override
{
- return AppInitBasicSetup(gArgs) && AppInitParameterInteraction(gArgs) && AppInitSanityChecks() &&
- AppInitLockDataDirectory() && AppInitInterfaces(*m_context);
+ if (!AppInitBasicSetup(gArgs)) return false;
+ if (!AppInitParameterInteraction(gArgs, /*use_syscall_sandbox=*/false)) return false;
+
+ m_context->kernel = std::make_unique<kernel::Context>();
+ if (!AppInitSanityChecks(*m_context->kernel)) return false;
+
+ if (!AppInitLockDataDirectory()) return false;
+ if (!AppInitInterfaces(*m_context)) return false;
+
+ return true;
}
bool appInitMain(interfaces::BlockAndHeaderTipInfo* tip_info) override
{
@@ -112,6 +119,46 @@ public:
}
}
bool shutdownRequested() override { return ShutdownRequested(); }
+ bool isSettingIgnored(const std::string& name) override
+ {
+ bool ignored = false;
+ gArgs.LockSettings([&](util::Settings& settings) {
+ if (auto* options = util::FindKey(settings.command_line_options, name)) {
+ ignored = !options->empty();
+ }
+ });
+ return ignored;
+ }
+ util::SettingsValue getPersistentSetting(const std::string& name) override { return gArgs.GetPersistentSetting(name); }
+ void updateRwSetting(const std::string& name, const util::SettingsValue& value) override
+ {
+ gArgs.LockSettings([&](util::Settings& settings) {
+ if (value.isNull()) {
+ settings.rw_settings.erase(name);
+ } else {
+ settings.rw_settings[name] = value;
+ }
+ });
+ gArgs.WriteSettingsFile();
+ }
+ void forceSetting(const std::string& name, const util::SettingsValue& value) override
+ {
+ gArgs.LockSettings([&](util::Settings& settings) {
+ if (value.isNull()) {
+ settings.forced_settings.erase(name);
+ } else {
+ settings.forced_settings[name] = value;
+ }
+ });
+ }
+ void resetSettings() override
+ {
+ gArgs.WriteSettingsFile(/*errors=*/nullptr, /*backup=*/true);
+ gArgs.LockSettings([&](util::Settings& settings) {
+ settings.rw_settings.clear();
+ });
+ gArgs.WriteSettingsFile();
+ }
void mapPort(bool use_upnp, bool use_natpmp) override { StartMapPort(use_upnp, use_natpmp); }
bool getProxy(Network net, Proxy& proxy_info) override { return GetProxy(net, proxy_info); }
size_t getNodeCount(ConnectionDirection flags) override
@@ -212,9 +259,10 @@ public:
bool getHeaderTip(int& height, int64_t& block_time) override
{
LOCK(::cs_main);
- if (::pindexBestHeader) {
- height = ::pindexBestHeader->nHeight;
- block_time = ::pindexBestHeader->GetBlockTime();
+ auto best_header = chainman().m_best_header;
+ if (best_header) {
+ height = best_header->nHeight;
+ block_time = best_header->GetBlockTime();
return true;
}
return false;
@@ -227,7 +275,7 @@ public:
uint256 getBestBlockHash() override
{
const CBlockIndex* tip = WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip());
- return tip ? tip->GetBlockHash() : Params().GenesisBlock().GetHash();
+ return tip ? tip->GetBlockHash() : chainman().GetParams().GenesisBlock().GetHash();
}
int64_t getLastBlockTime() override
{
@@ -235,16 +283,11 @@ public:
if (chainman().ActiveChain().Tip()) {
return chainman().ActiveChain().Tip()->GetBlockTime();
}
- return Params().GenesisBlock().GetBlockTime(); // Genesis block's time of current network
+ return chainman().GetParams().GenesisBlock().GetBlockTime(); // Genesis block's time of current network
}
double getVerificationProgress() override
{
- const CBlockIndex* tip;
- {
- LOCK(::cs_main);
- tip = chainman().ActiveChain().Tip();
- }
- return GuessVerificationProgress(Params().TxData(), tip);
+ return GuessVerificationProgress(chainman().GetParams().TxData(), WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip()));
}
bool isInitialBlockDownload() override {
return chainman().ActiveChainstate().IsInitialBlockDownload();
@@ -258,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;
@@ -330,9 +377,8 @@ public:
std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) override
{
return MakeHandler(
- ::uiInterface.NotifyHeaderTip_connect([fn](SynchronizationState sync_state, const CBlockIndex* block) {
- fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()},
- /* verification progress is unused when a header was received */ 0);
+ ::uiInterface.NotifyHeaderTip_connect([fn](SynchronizationState sync_state, int64_t height, int64_t timestamp, bool presync) {
+ fn(sync_state, BlockTip{(int)height, timestamp, uint256{}}, presync);
}));
}
NodeContext* context() override { return m_context; }
@@ -340,6 +386,7 @@ public:
{
m_context = context;
}
+ ChainstateManager& chainman() { return *Assert(m_context->chainman); }
NodeContext* m_context{nullptr};
};
@@ -352,6 +399,7 @@ bool FillBlock(const CBlockIndex* index, const FoundBlock& block, UniqueLock<Rec
if (block.m_max_time) *block.m_max_time = index->GetBlockTimeMax();
if (block.m_mtp_time) *block.m_mtp_time = index->GetMedianTimePast();
if (block.m_in_active_chain) *block.m_in_active_chain = active[index->nHeight] == index;
+ if (block.m_locator) { *block.m_locator = GetLocator(index); }
if (block.m_next_block) FillBlock(active[index->nHeight] == index ? active[index->nHeight + 1] : nullptr, *block.m_next_block, lock, active);
if (block.m_data) {
REVERSE_LOCK(lock);
@@ -377,11 +425,11 @@ public:
}
void BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* index) override
{
- m_notifications->blockConnected(*block, index->nHeight);
+ m_notifications->blockConnected(kernel::MakeBlockInfo(index, block.get()));
}
void BlockDisconnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* index) override
{
- m_notifications->blockDisconnected(*block, index->nHeight);
+ m_notifications->blockDisconnected(kernel::MakeBlockInfo(index, block.get()));
}
void UpdatedBlockTip(const CBlockIndex* index, const CBlockIndex* fork_index, bool is_ibd) override
{
@@ -425,7 +473,7 @@ public:
// try to handle the request. Otherwise, reraise the exception.
if (!last_handler) {
const UniValue& code = e["code"];
- if (code.isNum() && code.get_int() == RPC_WALLET_NOT_FOUND) {
+ if (code.isNum() && code.getInt<int>() == RPC_WALLET_NOT_FOUND) {
return false;
}
}
@@ -451,46 +499,39 @@ 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 = Assert(m_node.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 = Assert(m_node.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 = Assert(m_node.chainman)->ActiveChain();
- CBlockIndex* block = active[height];
+ LOCK(::cs_main);
+ 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 = Assert(m_node.chainman)->ActiveChain();
- return active.GetLocator();
+ LOCK(::cs_main);
+ return chainman().ActiveChain().GetLocator();
+ }
+ CBlockLocator getActiveChainLocator(const uint256& block_hash) override
+ {
+ LOCK(::cs_main);
+ const CBlockIndex* index = chainman().m_blockman.LookupBlockIndex(block_hash);
+ return GetLocator(index);
}
std::optional<int> findLocatorFork(const CBlockLocator& locator) override
{
- LOCK(cs_main);
- const CChainState& active = Assert(m_node.chainman)->ActiveChainstate();
- if (CBlockIndex* fork = active.FindForkInGlobalIndex(locator)) {
+ LOCK(::cs_main);
+ if (const CBlockIndex* fork = chainman().ActiveChainstate().FindForkInGlobalIndex(locator)) {
return fork->nHeight;
}
return std::nullopt;
@@ -498,20 +539,19 @@ public:
bool findBlock(const uint256& hash, const FoundBlock& block) override
{
WAIT_LOCK(cs_main, lock);
- const CChain& active = Assert(m_node.chainman)->ActiveChain();
- return FillBlock(m_node.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
{
WAIT_LOCK(cs_main, lock);
- const CChain& active = Assert(m_node.chainman)->ActiveChain();
+ const CChain& active = chainman().ActiveChain();
return FillBlock(active.FindEarliestAtLeast(min_time, min_height), block, lock, active);
}
bool findAncestorByHeight(const uint256& block_hash, int ancestor_height, const FoundBlock& ancestor_out) override
{
WAIT_LOCK(cs_main, lock);
- const CChain& active = Assert(m_node.chainman)->ActiveChain();
- if (const CBlockIndex* block = m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) {
+ const CChain& active = chainman().ActiveChain();
+ if (const CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash)) {
if (const CBlockIndex* ancestor = block->GetAncestor(ancestor_height)) {
return FillBlock(ancestor, ancestor_out, lock, active);
}
@@ -521,18 +561,17 @@ public:
bool findAncestorByHash(const uint256& block_hash, const uint256& ancestor_hash, const FoundBlock& ancestor_out) override
{
WAIT_LOCK(cs_main, lock);
- const CChain& active = Assert(m_node.chainman)->ActiveChain();
- const CBlockIndex* block = m_node.chainman->m_blockman.LookupBlockIndex(block_hash);
- const CBlockIndex* ancestor = m_node.chainman->m_blockman.LookupBlockIndex(ancestor_hash);
+ 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
{
WAIT_LOCK(cs_main, lock);
- const CChain& active = Assert(m_node.chainman)->ActiveChain();
- const CBlockIndex* block1 = m_node.chainman->m_blockman.LookupBlockIndex(block_hash1);
- const CBlockIndex* block2 = m_node.chainman->m_blockman.LookupBlockIndex(block_hash2);
+ const CChain& active = chainman().ActiveChain();
+ const CBlockIndex* block1 = chainman().m_blockman.LookupBlockIndex(block_hash1);
+ const CBlockIndex* block2 = chainman().m_blockman.LookupBlockIndex(block_hash2);
const CBlockIndex* ancestor = block1 && block2 ? LastCommonAncestor(block1, block2) : nullptr;
// Using & instead of && below to avoid short circuiting and leaving
// output uninitialized. Cast bool to int to avoid -Wbitwise-instead-of-logical
@@ -544,8 +583,8 @@ public:
void findCoins(std::map<COutPoint, Coin>& coins) override { return FindCoins(m_node, coins); }
double guessVerificationProgress(const uint256& block_hash) override
{
- LOCK(cs_main);
- return GuessVerificationProgress(Params().TxData(), chainman().m_blockman.LookupBlockIndex(block_hash));
+ LOCK(::cs_main);
+ return GuessVerificationProgress(chainman().GetParams().TxData(), chainman().m_blockman.LookupBlockIndex(block_hash));
}
bool hasBlocks(const uint256& block_hash, int min_height, std::optional<int> max_height) override
{
@@ -557,7 +596,7 @@ public:
// used to limit the range, and passing min_height that's too low or
// max_height that's too high will not crash or change the result.
LOCK(::cs_main);
- if (CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash)) {
+ if (const CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash)) {
if (max_height && block->nHeight >= *max_height) block = block->GetAncestor(*max_height);
for (; block->nStatus & BLOCK_HAVE_DATA; block = block->pprev) {
// Check pprev to not segfault if min_height is too low
@@ -590,7 +629,7 @@ public:
bool relay,
std::string& err_string) override
{
- const TransactionError err = BroadcastTransaction(m_node, tx, err_string, max_tx_fee, relay, /*wait_callback*/ false);
+ const TransactionError err = BroadcastTransaction(m_node, tx, err_string, max_tx_fee, relay, /*wait_callback=*/false);
// Chain clients only care about failures to accept the tx to the mempool. Disregard non-mempool related failures.
// Note: this will need to be updated if BroadcastTransactions() is updated to return other non-mempool failures
// that Chain clients do not need to know about.
@@ -604,8 +643,12 @@ public:
}
void getPackageLimits(unsigned int& limit_ancestor_count, unsigned int& limit_descendant_count) override
{
- limit_ancestor_count = gArgs.GetIntArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
- limit_descendant_count = gArgs.GetIntArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT);
+ const CTxMemPool::Limits default_limits{};
+
+ const CTxMemPool::Limits& limits{m_node.mempool ? m_node.mempool->m_limits : default_limits};
+
+ limit_ancestor_count = limits.ancestor_count;
+ limit_descendant_count = limits.descendant_count;
}
bool checkChainLimits(const CTransactionRef& tx) override
{
@@ -613,15 +656,12 @@ public:
LockPoints lp;
CTxMemPoolEntry entry(tx, 0, 0, 0, false, 0, lp);
CTxMemPool::setEntries ancestors;
- auto limit_ancestor_count = gArgs.GetIntArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
- auto limit_ancestor_size = gArgs.GetIntArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT) * 1000;
- auto limit_descendant_count = gArgs.GetIntArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT);
- auto limit_descendant_size = gArgs.GetIntArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000;
+ const CTxMemPool::Limits& limits{m_node.mempool->m_limits};
std::string unused_error_string;
LOCK(m_node.mempool->cs);
return m_node.mempool->CalculateMemPoolAncestors(
- entry, ancestors, limit_ancestor_count, limit_ancestor_size,
- limit_descendant_count, limit_descendant_size, unused_error_string);
+ entry, ancestors, limits.ancestor_count, limits.ancestor_size_vbytes,
+ limits.descendant_count, limits.descendant_size_vbytes, unused_error_string);
}
CFeeRate estimateSmartFee(int num_blocks, bool conservative, FeeCalculation* calc) override
{
@@ -636,15 +676,27 @@ public:
CFeeRate mempoolMinFee() override
{
if (!m_node.mempool) return {};
- return m_node.mempool->GetMinFee(gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
+ return m_node.mempool->GetMinFee();
+ }
+ 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;
}
- CFeeRate relayMinFee() override { return ::minRelayTxFee; }
- CFeeRate relayIncrementalFee() override { return ::incrementalRelayFee; }
- CFeeRate relayDustFee() override { return ::dustRelayFee; }
bool havePruned() override
{
- LOCK(cs_main);
- return node::fHavePruned;
+ LOCK(::cs_main);
+ return chainman().m_blockman.m_have_pruned;
}
bool isReadyToBroadcast() override { return !node::fImporting && !node::fReindex && !isInitialBlockDownload(); }
bool isInitialBlockDownload() override {
@@ -664,11 +716,7 @@ public:
}
void waitForNotificationsIfTipChanged(const uint256& old_tip) override
{
- if (!old_tip.IsNull()) {
- LOCK(::cs_main);
- const CChain& active = Assert(m_node.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
@@ -718,6 +766,13 @@ public:
notifications.transactionAddedToMempool(entry.GetSharedTx(), 0 /* mempool_sequence */);
}
}
+ bool hasAssumedValidChain() override
+ {
+ return chainman().IsSnapshotActive();
+ }
+
+ NodeContext* context() override { return &m_node; }
+ ChainstateManager& chainman() { return *Assert(m_node.chainman); }
NodeContext& m_node;
};
} // namespace