aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bitcoin-chainstate.cpp6
-rw-r--r--src/checkqueue.h10
-rw-r--r--src/deploymentstatus.cpp2
-rw-r--r--src/deploymentstatus.h15
-rw-r--r--src/httpserver.cpp6
-rw-r--r--src/i2p.h6
-rw-r--r--src/index/blockfilterindex.h2
-rw-r--r--src/init.cpp2
-rw-r--r--src/net.cpp6
-rw-r--r--src/net.h49
-rw-r--r--src/net_processing.cpp275
-rw-r--r--src/node/miner.cpp6
-rw-r--r--src/qt/clientmodel.h2
-rw-r--r--src/random.cpp6
-rw-r--r--src/rpc/blockchain.cpp57
-rw-r--r--src/rpc/mining.cpp16
-rw-r--r--src/scheduler.h29
-rw-r--r--src/sync.h10
-rw-r--r--src/test/blockfilter_index_tests.cpp8
-rw-r--r--src/test/fuzz/utxo_snapshot.cpp2
-rw-r--r--src/test/miner_tests.cpp2
-rw-r--r--src/test/util/mining.cpp2
-rw-r--r--src/test/util/setup_common.cpp7
-rw-r--r--src/test/validation_block_tests.cpp12
-rw-r--r--src/test/validation_chainstate_tests.cpp3
-rw-r--r--src/test/versionbits_tests.cpp55
-rw-r--r--src/threadinterrupt.h8
-rw-r--r--src/validation.cpp111
-rw-r--r--src/validation.h57
-rw-r--r--src/validationinterface.cpp30
-rw-r--r--src/validationinterface.h6
-rw-r--r--src/versionbits.h8
-rw-r--r--src/wallet/bdb.cpp4
-rw-r--r--src/wallet/bdb.h4
34 files changed, 416 insertions, 408 deletions
diff --git a/src/bitcoin-chainstate.cpp b/src/bitcoin-chainstate.cpp
index e5b6875a36..ab805ac1ec 100644
--- a/src/bitcoin-chainstate.cpp
+++ b/src/bitcoin-chainstate.cpp
@@ -70,7 +70,7 @@ int main(int argc, char* argv[])
// SETUP: Chainstate
- ChainstateManager chainman;
+ ChainstateManager chainman{chainparams};
auto rv = node::LoadChainstate(false,
std::ref(chainman),
@@ -163,7 +163,7 @@ int main(int argc, char* argv[])
LOCK(cs_main);
const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock);
if (pindex) {
- UpdateUncommittedBlockStructures(block, pindex, chainparams.GetConsensus());
+ chainman.UpdateUncommittedBlockStructures(block, pindex);
}
}
@@ -190,7 +190,7 @@ int main(int argc, char* argv[])
bool new_block;
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
RegisterSharedValidationInterface(sc);
- bool accepted = chainman.ProcessNewBlock(chainparams, blockptr, /*force_processing=*/true, /*new_block=*/&new_block);
+ bool accepted = chainman.ProcessNewBlock(blockptr, /*force_processing=*/true, /*new_block=*/&new_block);
UnregisterSharedValidationInterface(sc);
if (!new_block && accepted) {
std::cerr << "duplicate" << std::endl;
diff --git a/src/checkqueue.h b/src/checkqueue.h
index d0e88a3410..bead6f0c6f 100644
--- a/src/checkqueue.h
+++ b/src/checkqueue.h
@@ -66,7 +66,7 @@ private:
bool m_request_stop GUARDED_BY(m_mutex){false};
/** Internal function that does bulk of the verification work. */
- bool Loop(bool fMaster)
+ bool Loop(bool fMaster) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{
std::condition_variable& cond = fMaster ? m_master_cv : m_worker_cv;
std::vector<T> vChecks;
@@ -140,7 +140,7 @@ public:
}
//! Create a pool of new worker threads.
- void StartWorkerThreads(const int threads_num)
+ void StartWorkerThreads(const int threads_num) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{
{
LOCK(m_mutex);
@@ -159,13 +159,13 @@ public:
}
//! Wait until execution finishes, and return whether all evaluations were successful.
- bool Wait()
+ bool Wait() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{
return Loop(true /* master thread */);
}
//! Add a batch of checks to the queue
- void Add(std::vector<T>& vChecks)
+ void Add(std::vector<T>& vChecks) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{
if (vChecks.empty()) {
return;
@@ -188,7 +188,7 @@ public:
}
//! Stop all of the worker threads.
- void StopWorkerThreads()
+ void StopWorkerThreads() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{
WITH_LOCK(m_mutex, m_request_stop = true);
m_worker_cv.notify_all();
diff --git a/src/deploymentstatus.cpp b/src/deploymentstatus.cpp
index ae19a6e40d..3a524af29e 100644
--- a/src/deploymentstatus.cpp
+++ b/src/deploymentstatus.cpp
@@ -9,8 +9,6 @@
#include <type_traits>
-VersionBitsCache g_versionbitscache;
-
/* Basic sanity checking for BuriedDeployment/DeploymentPos enums and
* ValidDeployment check */
diff --git a/src/deploymentstatus.h b/src/deploymentstatus.h
index ba5103de74..9f5919f71b 100644
--- a/src/deploymentstatus.h
+++ b/src/deploymentstatus.h
@@ -10,33 +10,30 @@
#include <limits>
-/** Global cache for versionbits deployment status */
-extern VersionBitsCache g_versionbitscache;
-
/** Determine if a deployment is active for the next block */
-inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::BuriedDeployment dep)
+inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::BuriedDeployment dep, [[maybe_unused]] VersionBitsCache& versionbitscache)
{
assert(Consensus::ValidDeployment(dep));
return (pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1) >= params.DeploymentHeight(dep);
}
-inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos dep)
+inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos dep, VersionBitsCache& versionbitscache)
{
assert(Consensus::ValidDeployment(dep));
- return ThresholdState::ACTIVE == g_versionbitscache.State(pindexPrev, params, dep);
+ return ThresholdState::ACTIVE == versionbitscache.State(pindexPrev, params, dep);
}
/** Determine if a deployment is active for this block */
-inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::BuriedDeployment dep)
+inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::BuriedDeployment dep, [[maybe_unused]] VersionBitsCache& versionbitscache)
{
assert(Consensus::ValidDeployment(dep));
return index.nHeight >= params.DeploymentHeight(dep);
}
-inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::DeploymentPos dep)
+inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::DeploymentPos dep, VersionBitsCache& versionbitscache)
{
assert(Consensus::ValidDeployment(dep));
- return DeploymentActiveAfter(index.pprev, params, dep);
+ return DeploymentActiveAfter(index.pprev, params, dep, versionbitscache);
}
/** Determine if a deployment is enabled (can ever be active) */
diff --git a/src/httpserver.cpp b/src/httpserver.cpp
index 96bee8640d..dba66becc0 100644
--- a/src/httpserver.cpp
+++ b/src/httpserver.cpp
@@ -87,7 +87,7 @@ public:
{
}
/** Enqueue a work item */
- bool Enqueue(WorkItem* item)
+ bool Enqueue(WorkItem* item) EXCLUSIVE_LOCKS_REQUIRED(!cs)
{
LOCK(cs);
if (!running || queue.size() >= maxDepth) {
@@ -98,7 +98,7 @@ public:
return true;
}
/** Thread function */
- void Run()
+ void Run() EXCLUSIVE_LOCKS_REQUIRED(!cs)
{
while (true) {
std::unique_ptr<WorkItem> i;
@@ -115,7 +115,7 @@ public:
}
}
/** Interrupt and exit loops */
- void Interrupt()
+ void Interrupt() EXCLUSIVE_LOCKS_REQUIRED(!cs)
{
LOCK(cs);
running = false;
diff --git a/src/i2p.h b/src/i2p.h
index b211d4f5e4..433fcc3a08 100644
--- a/src/i2p.h
+++ b/src/i2p.h
@@ -84,7 +84,7 @@ public:
* to the listening socket and address.
* @return true on success
*/
- bool Listen(Connection& conn);
+ bool Listen(Connection& conn) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
/**
* Wait for and accept a new incoming connection.
@@ -103,7 +103,7 @@ public:
* it is set to `false`. Only set if `false` is returned.
* @return true on success
*/
- bool Connect(const CService& to, Connection& conn, bool& proxy_error);
+ bool Connect(const CService& to, Connection& conn, bool& proxy_error) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
private:
/**
@@ -172,7 +172,7 @@ private:
/**
* Check the control socket for errors and possibly disconnect.
*/
- void CheckControlSock();
+ void CheckControlSock() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
/**
* Generate a new destination with the SAM proxy and set `m_private_key` to it.
diff --git a/src/index/blockfilterindex.h b/src/index/blockfilterindex.h
index b1836fe12f..6deff59000 100644
--- a/src/index/blockfilterindex.h
+++ b/src/index/blockfilterindex.h
@@ -64,7 +64,7 @@ public:
bool LookupFilter(const CBlockIndex* block_index, BlockFilter& filter_out) const;
/** Get a single filter header by block. */
- bool LookupFilterHeader(const CBlockIndex* block_index, uint256& header_out);
+ bool LookupFilterHeader(const CBlockIndex* block_index, uint256& header_out) EXCLUSIVE_LOCKS_REQUIRED(!m_cs_headers_cache);
/** Get a range of filters between two heights on a chain. */
bool LookupFilterRange(int start_height, const CBlockIndex* stop_index,
diff --git a/src/init.cpp b/src/init.cpp
index feb4ad52a6..e180a2b5cd 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1424,7 +1424,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
for (bool fLoaded = false; !fLoaded && !ShutdownRequested();) {
node.mempool = std::make_unique<CTxMemPool>(node.fee_estimator.get(), mempool_check_ratio);
- node.chainman = std::make_unique<ChainstateManager>();
+ node.chainman = std::make_unique<ChainstateManager>(chainparams);
ChainstateManager& chainman = *node.chainman;
const bool fReset = fReindex;
diff --git a/src/net.cpp b/src/net.cpp
index 41ac31445d..1c775f9a3f 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -1867,6 +1867,12 @@ void CConnman::SetTryNewOutboundPeer(bool flag)
LogPrint(BCLog::NET, "net: setting try another outbound peer=%s\n", flag ? "true" : "false");
}
+void CConnman::StartExtraBlockRelayPeers()
+{
+ LogPrint(BCLog::NET, "net: enabling extra block-relay-only peers\n");
+ m_start_extra_block_relay_peers = true;
+}
+
// Return the number of peers we have over our outbound connection limit
// Exclude peers that are marked for disconnect, or are going to be
// disconnected soon (eg ADDR_FETCH and FEELER)
diff --git a/src/net.h b/src/net.h
index 5cdddf1fee..3d1a2658c7 100644
--- a/src/net.h
+++ b/src/net.h
@@ -13,7 +13,6 @@
#include <crypto/siphash.h>
#include <hash.h>
#include <i2p.h>
-#include <logging.h>
#include <net_permissions.h>
#include <netaddress.h>
#include <netbase.h>
@@ -613,7 +612,7 @@ public:
* @return True if the peer should stay connected,
* False if the peer should be disconnected from.
*/
- bool ReceiveMsgBytes(Span<const uint8_t> msg_bytes, bool& complete);
+ bool ReceiveMsgBytes(Span<const uint8_t> msg_bytes, bool& complete) EXCLUSIVE_LOCKS_REQUIRED(!cs_vRecv);
void SetCommonVersion(int greatest_common_version)
{
@@ -625,9 +624,9 @@ public:
return m_greatest_common_version;
}
- CService GetAddrLocal() const LOCKS_EXCLUDED(m_addr_local_mutex);
+ CService GetAddrLocal() const EXCLUSIVE_LOCKS_REQUIRED(!m_addr_local_mutex);
//! May not be called more than once
- void SetAddrLocal(const CService& addrLocalIn) LOCKS_EXCLUDED(m_addr_local_mutex);
+ void SetAddrLocal(const CService& addrLocalIn) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_local_mutex);
CNode* AddRef()
{
@@ -640,9 +639,9 @@ public:
nRefCount--;
}
- void CloseSocketDisconnect();
+ void CloseSocketDisconnect() EXCLUSIVE_LOCKS_REQUIRED(!m_sock_mutex);
- void CopyStats(CNodeStats& stats);
+ void CopyStats(CNodeStats& stats) EXCLUSIVE_LOCKS_REQUIRED(!m_subver_mutex, !m_addr_local_mutex, !cs_vSend, !cs_vRecv);
ServiceFlags GetLocalServices() const
{
@@ -761,7 +760,7 @@ public:
bool m_i2p_accept_incoming;
};
- void Init(const Options& connOptions) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
+ void Init(const Options& connOptions) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex, !m_total_bytes_sent_mutex)
{
AssertLockNotHeld(m_total_bytes_sent_mutex);
@@ -795,7 +794,8 @@ public:
bool network_active = true);
~CConnman();
- bool Start(CScheduler& scheduler, const Options& options) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex);
+
+ bool Start(CScheduler& scheduler, const Options& options) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex, !m_added_nodes_mutex, !m_addr_fetches_mutex, !mutexMsgProc);
void StopThreads();
void StopNodes();
@@ -805,7 +805,7 @@ public:
StopNodes();
};
- void Interrupt();
+ void Interrupt() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc);
bool GetNetworkActive() const { return fNetworkActive; };
bool GetUseAddrmanOutgoing() const { return m_use_addrman_outgoing; };
void SetNetworkActive(bool active);
@@ -857,10 +857,7 @@ public:
void SetTryNewOutboundPeer(bool flag);
bool GetTryNewOutboundPeer() const;
- void StartExtraBlockRelayPeers() {
- LogPrint(BCLog::NET, "net: enabling extra block-relay-only peers\n");
- m_start_extra_block_relay_peers = true;
- }
+ void StartExtraBlockRelayPeers();
// Return the number of outbound peers we have in excess of our target (eg,
// if we previously called SetTryNewOutboundPeer(true), and have since set
@@ -872,9 +869,9 @@ public:
// Count the number of block-relay-only peers we have over our limit.
int GetExtraBlockRelayCount() const;
- bool AddNode(const std::string& node);
- bool RemoveAddedNode(const std::string& node);
- std::vector<AddedNodeInfo> GetAddedNodeInfo() const;
+ bool AddNode(const std::string& node) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex);
+ bool RemoveAddedNode(const std::string& node) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex);
+ std::vector<AddedNodeInfo> GetAddedNodeInfo() const EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex);
/**
* Attempts to open a connection. Currently only used from tests.
@@ -927,7 +924,7 @@ public:
unsigned int GetReceiveFloodSize() const;
- void WakeMessageHandler();
+ void WakeMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc);
/** Return true if we should disconnect the peer for failing an inactivity check. */
bool ShouldRunInactivityChecks(const CNode& node, std::chrono::seconds now) const;
@@ -954,11 +951,11 @@ private:
bool Bind(const CService& addr, unsigned int flags, NetPermissionFlags permissions);
bool InitBinds(const Options& options);
- void ThreadOpenAddedConnections();
- void AddAddrFetch(const std::string& strDest);
- void ProcessAddrFetch();
- void ThreadOpenConnections(std::vector<std::string> connect);
- void ThreadMessageHandler();
+ void ThreadOpenAddedConnections() EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex);
+ void AddAddrFetch(const std::string& strDest) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex);
+ void ProcessAddrFetch() EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex);
+ void ThreadOpenConnections(std::vector<std::string> connect) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !m_added_nodes_mutex, !m_nodes_mutex);
+ void ThreadMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc);
void ThreadI2PAcceptIncoming();
void AcceptConnection(const ListenSocket& hListenSocket);
@@ -1009,7 +1006,7 @@ private:
/**
* Check connected and listening sockets for IO readiness and process them accordingly.
*/
- void SocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex);
+ void SocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex, !mutexMsgProc);
/**
* Do the read/write for connected sockets that are ready for IO.
@@ -1023,7 +1020,7 @@ private:
const std::set<SOCKET>& recv_set,
const std::set<SOCKET>& send_set,
const std::set<SOCKET>& error_set)
- EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex);
+ EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex, !mutexMsgProc);
/**
* Accept incoming connections, one from each read-ready listening socket.
@@ -1031,8 +1028,8 @@ private:
*/
void SocketHandlerListening(const std::set<SOCKET>& recv_set);
- void ThreadSocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex);
- void ThreadDNSAddressSeed();
+ void ThreadSocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex, !mutexMsgProc);
+ void ThreadDNSAddressSeed() EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !m_nodes_mutex);
uint64_t CalculateKeyedNetGroup(const CAddress& ad) const;
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index cb0e8c88f8..349d7fd8fb 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -175,6 +175,8 @@ static constexpr double MAX_ADDR_RATE_PER_SECOND{0.1};
* based increments won't go above this, but the MAX_ADDR_TO_SEND increment following GETADDR
* is exempt from this limit). */
static constexpr size_t MAX_ADDR_PROCESSING_TOKEN_BUCKET{MAX_ADDR_TO_SEND};
+/** The compactblocks version we support. See BIP 152. */
+static constexpr uint64_t CMPCTBLOCKS_VERSION{2};
// Internal stuff
namespace {
@@ -365,23 +367,12 @@ struct CNodeState {
bool fPreferredDownload{false};
//! Whether this peer wants invs or headers (when possible) for block announcements.
bool fPreferHeaders{false};
- //! Whether this peer wants invs or cmpctblocks (when possible) for block announcements.
- bool fPreferHeaderAndIDs{false};
- /**
- * Whether this peer will send us cmpctblocks if we request them.
- * This is not used to gate request logic, as we really only care about fSupportsDesiredCmpctVersion,
- * but is used as a flag to "lock in" the version of compact blocks (fWantsCmpctWitness) we send.
- */
- bool fProvidesHeaderAndIDs{false};
+ /** Whether this peer wants invs or cmpctblocks (when possible) for block announcements. */
+ bool m_requested_hb_cmpctblocks{false};
+ /** Whether this peer will send us cmpctblocks if we request them. */
+ bool m_provides_cmpctblocks{false};
//! Whether this peer can give us witnesses
bool fHaveWitness{false};
- //! Whether this peer wants witnesses in cmpctblocks/blocktxns
- bool fWantsCmpctWitness{false};
- /**
- * If we've announced NODE_WITNESS to this peer: whether the peer sends witnesses in cmpctblocks/blocktxns,
- * otherwise: whether this peer sends non-witnesses in cmpctblocks/blocktxns.
- */
- bool fSupportsDesiredCmpctVersion{false};
/** State used to enforce CHAIN_SYNC_TIMEOUT and EXTRA_PEER_CHECK_INTERVAL logic.
*
@@ -440,30 +431,37 @@ public:
CTxMemPool& pool, bool ignore_incoming_txs);
/** Overridden from CValidationInterface. */
- void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected) override;
- void BlockDisconnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex* pindex) override;
- void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override;
- void BlockChecked(const CBlock& block, const BlockValidationState& state) override;
+ void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected) override
+ EXCLUSIVE_LOCKS_REQUIRED(!m_recent_confirmed_transactions_mutex);
+ void BlockDisconnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex* pindex) override
+ EXCLUSIVE_LOCKS_REQUIRED(!m_recent_confirmed_transactions_mutex);
+ void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
+ void BlockChecked(const CBlock& block, const BlockValidationState& state) override
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr<const CBlock>& pblock) override;
/** Implement NetEventsInterface */
- void InitializeNode(CNode* pnode) override;
- void FinalizeNode(const CNode& node) override;
- bool ProcessMessages(CNode* pfrom, std::atomic<bool>& interrupt) override;
- bool SendMessages(CNode* pto) override EXCLUSIVE_LOCKS_REQUIRED(pto->cs_sendProcessing);
+ void InitializeNode(CNode* pnode) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
+ void FinalizeNode(const CNode& node) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
+ bool ProcessMessages(CNode* pfrom, std::atomic<bool>& interrupt) override
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex);
+ bool SendMessages(CNode* pto) override EXCLUSIVE_LOCKS_REQUIRED(pto->cs_sendProcessing)
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex);
/** Implement PeerManager */
void StartScheduledTasks(CScheduler& scheduler) override;
void CheckForStaleTipAndEvictPeers() override;
std::optional<std::string> FetchBlock(NodeId peer_id, const CBlockIndex& block_index) override;
- bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const override;
+ bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
bool IgnoresIncomingTxs() override { return m_ignore_incoming_txs; }
- void SendPings() override;
- void RelayTransaction(const uint256& txid, const uint256& wtxid) override;
+ void SendPings() override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
+ void RelayTransaction(const uint256& txid, const uint256& wtxid) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
void SetBestHeight(int height) override { m_best_height = height; };
- void Misbehaving(const NodeId pnode, const int howmuch, const std::string& message) override;
+ void Misbehaving(const NodeId pnode, const int howmuch, const std::string& message) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
void ProcessMessage(CNode& pfrom, const std::string& msg_type, CDataStream& vRecv,
- const std::chrono::microseconds time_received, const std::atomic<bool>& interruptMsgProc) override;
+ const std::chrono::microseconds time_received, const std::atomic<bool>& interruptMsgProc) override
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex);
void UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_seconds) override;
private:
@@ -474,15 +472,15 @@ private:
void EvictExtraOutboundPeers(std::chrono::seconds now) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/** Retrieve unbroadcast transactions from the mempool and reattempt sending to peers */
- void ReattemptInitialBroadcast(CScheduler& scheduler);
+ void ReattemptInitialBroadcast(CScheduler& scheduler) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Get a shared pointer to the Peer object.
* May return an empty shared_ptr if the Peer object can't be found. */
- PeerRef GetPeerRef(NodeId id) const;
+ PeerRef GetPeerRef(NodeId id) const EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Get a shared pointer to the Peer object and remove it from m_peer_map.
* May return an empty shared_ptr if the Peer object can't be found. */
- PeerRef RemovePeer(NodeId id);
+ PeerRef RemovePeer(NodeId id) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/**
* Potentially mark a node discouraged based on the contents of a BlockValidationState object
@@ -495,14 +493,16 @@ private:
* @return Returns true if the peer was punished (probably disconnected)
*/
bool MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationState& state,
- bool via_compact_block, const std::string& message = "");
+ bool via_compact_block, const std::string& message = "")
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/**
* Potentially disconnect and discourage a node based on the contents of a TxValidationState object
*
* @return Returns true if the peer was punished (probably disconnected)
*/
- bool MaybePunishNodeForTx(NodeId nodeid, const TxValidationState& state, const std::string& message = "");
+ bool MaybePunishNodeForTx(NodeId nodeid, const TxValidationState& state, const std::string& message = "")
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Maybe disconnect a peer and discourage future connections from its address.
*
@@ -512,13 +512,16 @@ private:
*/
bool MaybeDiscourageAndDisconnect(CNode& pnode, Peer& peer);
- void ProcessOrphanTx(std::set<uint256>& orphan_work_set) EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans);
+ void ProcessOrphanTx(std::set<uint256>& orphan_work_set) EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans)
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Process a single headers message from a peer. */
void ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
const std::vector<CBlockHeader>& headers,
- bool via_compact_block);
+ bool via_compact_block)
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
- void SendBlockTransactions(CNode& pfrom, const CBlock& block, const BlockTransactionsRequest& req);
+ void SendBlockTransactions(CNode& pfrom, const CBlock& block, const BlockTransactionsRequest& req)
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Register with TxRequestTracker that an INV has been received from a
* peer. The announcement parameters are decided in PeerManager and then
@@ -545,7 +548,7 @@ private:
* @param[in] fReachable Whether the address' network is reachable. We relay unreachable
* addresses less.
*/
- void RelayAddress(NodeId originator, const CAddress& addr, bool fReachable);
+ void RelayAddress(NodeId originator, const CAddress& addr, bool fReachable) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Send `feefilter` message. */
void MaybeSendFeefilter(CNode& node, Peer& peer, std::chrono::microseconds current_time);
@@ -615,7 +618,8 @@ private:
/** Number of preferable block download peers. */
int m_num_preferred_download_peers GUARDED_BY(cs_main){0};
- bool AlreadyHaveTx(const GenTxid& gtxid) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ bool AlreadyHaveTx(const GenTxid& gtxid)
+ EXCLUSIVE_LOCKS_REQUIRED(cs_main, !m_recent_confirmed_transactions_mutex);
/**
* Filter for transactions that were recently rejected by the mempool.
@@ -687,7 +691,6 @@ private:
std::shared_ptr<const CBlock> m_most_recent_block GUARDED_BY(m_most_recent_block_mutex);
std::shared_ptr<const CBlockHeaderAndShortTxIDs> m_most_recent_compact_block GUARDED_BY(m_most_recent_block_mutex);
uint256 m_most_recent_block_hash GUARDED_BY(m_most_recent_block_mutex);
- bool m_most_recent_compact_block_has_witnesses GUARDED_BY(m_most_recent_block_mutex){false};
/** Height of the highest block announced using BIP 152 high-bandwidth mode. */
int m_highest_fast_announce{0};
@@ -974,54 +977,52 @@ void PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid)
if (m_ignore_incoming_txs) return;
CNodeState* nodestate = State(nodeid);
- if (!nodestate || !nodestate->fSupportsDesiredCmpctVersion) {
- // Never ask from peers who can't provide witnesses.
+ if (!nodestate || !nodestate->m_provides_cmpctblocks) {
+ // Don't request compact blocks if the peer has not signalled support
return;
}
- if (nodestate->fProvidesHeaderAndIDs) {
- int num_outbound_hb_peers = 0;
- for (std::list<NodeId>::iterator it = lNodesAnnouncingHeaderAndIDs.begin(); it != lNodesAnnouncingHeaderAndIDs.end(); it++) {
- if (*it == nodeid) {
- lNodesAnnouncingHeaderAndIDs.erase(it);
- lNodesAnnouncingHeaderAndIDs.push_back(nodeid);
- return;
- }
- CNodeState *state = State(*it);
- if (state != nullptr && !state->m_is_inbound) ++num_outbound_hb_peers;
- }
- if (nodestate->m_is_inbound) {
- // If we're adding an inbound HB peer, make sure we're not removing
- // our last outbound HB peer in the process.
- if (lNodesAnnouncingHeaderAndIDs.size() >= 3 && num_outbound_hb_peers == 1) {
- CNodeState *remove_node = State(lNodesAnnouncingHeaderAndIDs.front());
- if (remove_node != nullptr && !remove_node->m_is_inbound) {
- // Put the HB outbound peer in the second slot, so that it
- // doesn't get removed.
- std::swap(lNodesAnnouncingHeaderAndIDs.front(), *std::next(lNodesAnnouncingHeaderAndIDs.begin()));
- }
- }
+
+ int num_outbound_hb_peers = 0;
+ for (std::list<NodeId>::iterator it = lNodesAnnouncingHeaderAndIDs.begin(); it != lNodesAnnouncingHeaderAndIDs.end(); it++) {
+ if (*it == nodeid) {
+ lNodesAnnouncingHeaderAndIDs.erase(it);
+ lNodesAnnouncingHeaderAndIDs.push_back(nodeid);
+ return;
}
- m_connman.ForNode(nodeid, [this](CNode* pfrom) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
- AssertLockHeld(::cs_main);
- uint64_t nCMPCTBLOCKVersion = 2;
- if (lNodesAnnouncingHeaderAndIDs.size() >= 3) {
- // As per BIP152, we only get 3 of our peers to announce
- // blocks using compact encodings.
- m_connman.ForNode(lNodesAnnouncingHeaderAndIDs.front(), [this, nCMPCTBLOCKVersion](CNode* pnodeStop){
- m_connman.PushMessage(pnodeStop, CNetMsgMaker(pnodeStop->GetCommonVersion()).Make(NetMsgType::SENDCMPCT, /*fAnnounceUsingCMPCTBLOCK=*/false, nCMPCTBLOCKVersion));
- // save BIP152 bandwidth state: we select peer to be low-bandwidth
- pnodeStop->m_bip152_highbandwidth_to = false;
- return true;
- });
- lNodesAnnouncingHeaderAndIDs.pop_front();
+ CNodeState *state = State(*it);
+ if (state != nullptr && !state->m_is_inbound) ++num_outbound_hb_peers;
+ }
+ if (nodestate->m_is_inbound) {
+ // If we're adding an inbound HB peer, make sure we're not removing
+ // our last outbound HB peer in the process.
+ if (lNodesAnnouncingHeaderAndIDs.size() >= 3 && num_outbound_hb_peers == 1) {
+ CNodeState *remove_node = State(lNodesAnnouncingHeaderAndIDs.front());
+ if (remove_node != nullptr && !remove_node->m_is_inbound) {
+ // Put the HB outbound peer in the second slot, so that it
+ // doesn't get removed.
+ std::swap(lNodesAnnouncingHeaderAndIDs.front(), *std::next(lNodesAnnouncingHeaderAndIDs.begin()));
}
- m_connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetCommonVersion()).Make(NetMsgType::SENDCMPCT, /*fAnnounceUsingCMPCTBLOCK=*/true, nCMPCTBLOCKVersion));
- // save BIP152 bandwidth state: we select peer to be high-bandwidth
- pfrom->m_bip152_highbandwidth_to = true;
- lNodesAnnouncingHeaderAndIDs.push_back(pfrom->GetId());
- return true;
- });
+ }
}
+ m_connman.ForNode(nodeid, [this](CNode* pfrom) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
+ AssertLockHeld(::cs_main);
+ if (lNodesAnnouncingHeaderAndIDs.size() >= 3) {
+ // As per BIP152, we only get 3 of our peers to announce
+ // blocks using compact encodings.
+ m_connman.ForNode(lNodesAnnouncingHeaderAndIDs.front(), [this](CNode* pnodeStop){
+ m_connman.PushMessage(pnodeStop, CNetMsgMaker(pnodeStop->GetCommonVersion()).Make(NetMsgType::SENDCMPCT, /*high_bandwidth=*/false, /*version=*/CMPCTBLOCKS_VERSION));
+ // save BIP152 bandwidth state: we select peer to be low-bandwidth
+ pnodeStop->m_bip152_highbandwidth_to = false;
+ return true;
+ });
+ lNodesAnnouncingHeaderAndIDs.pop_front();
+ }
+ m_connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetCommonVersion()).Make(NetMsgType::SENDCMPCT, /*high_bandwidth=*/true, /*version=*/CMPCTBLOCKS_VERSION));
+ // save BIP152 bandwidth state: we select peer to be high-bandwidth
+ pfrom->m_bip152_highbandwidth_to = true;
+ lNodesAnnouncingHeaderAndIDs.push_back(pfrom->GetId());
+ return true;
+ });
}
bool PeerManagerImpl::TipMayBeStale()
@@ -1110,7 +1111,6 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
return;
- const Consensus::Params& consensusParams = m_chainparams.GetConsensus();
std::vector<const CBlockIndex*> vToFetch;
const CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
// Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
@@ -1140,7 +1140,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
// We consider the chain that this peer is on invalid.
return;
}
- if (!State(nodeid)->fHaveWitness && DeploymentActiveAt(*pindex, consensusParams, Consensus::DEPLOYMENT_SEGWIT)) {
+ if (!State(nodeid)->fHaveWitness && DeploymentActiveAt(*pindex, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) {
// We wouldn't download this block or its descendants from this peer.
return;
}
@@ -1641,7 +1641,8 @@ void PeerManagerImpl::NewPoWValidBlock(const CBlockIndex *pindex, const std::sha
return;
m_highest_fast_announce = pindex->nHeight;
- bool fWitnessEnabled = DeploymentActiveAt(*pindex, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT);
+ if (!DeploymentActiveAt(*pindex, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) return;
+
uint256 hashBlock(pblock->GetHash());
const std::shared_future<CSerializedNetMsg> lazy_ser{
std::async(std::launch::deferred, [&] { return msgMaker.Make(NetMsgType::CMPCTBLOCK, *pcmpctblock); })};
@@ -1651,10 +1652,9 @@ void PeerManagerImpl::NewPoWValidBlock(const CBlockIndex *pindex, const std::sha
m_most_recent_block_hash = hashBlock;
m_most_recent_block = pblock;
m_most_recent_compact_block = pcmpctblock;
- m_most_recent_compact_block_has_witnesses = fWitnessEnabled;
}
- m_connman.ForEachNode([this, pindex, fWitnessEnabled, &lazy_ser, &hashBlock](CNode* pnode) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
+ m_connman.ForEachNode([this, pindex, &lazy_ser, &hashBlock](CNode* pnode) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
AssertLockHeld(::cs_main);
if (pnode->GetCommonVersion() < INVALID_CB_NO_BAN_VERSION || pnode->fDisconnect)
@@ -1663,8 +1663,7 @@ void PeerManagerImpl::NewPoWValidBlock(const CBlockIndex *pindex, const std::sha
CNodeState &state = *State(pnode->GetId());
// If the peer has, or we announced to them the previous block already,
// but we don't think they have this one, go ahead and announce it
- if (state.fPreferHeaderAndIDs && (!fWitnessEnabled || state.fWantsCmpctWitness) &&
- !PeerHasHeader(&state, pindex) && PeerHasHeader(&state, pindex->pprev)) {
+ if (state.m_requested_hb_cmpctblocks && !PeerHasHeader(&state, pindex) && PeerHasHeader(&state, pindex->pprev)) {
LogPrint(BCLog::NET, "%s sending header-and-ids %s to peer=%d\n", "PeerManager::NewPoWValidBlock",
hashBlock.ToString(), pnode->GetId());
@@ -1859,12 +1858,10 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
{
std::shared_ptr<const CBlock> a_recent_block;
std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block;
- bool fWitnessesPresentInARecentCompactBlock;
{
LOCK(m_most_recent_block_mutex);
a_recent_block = m_most_recent_block;
a_recent_compact_block = m_most_recent_compact_block;
- fWitnessesPresentInARecentCompactBlock = m_most_recent_compact_block_has_witnesses;
}
bool need_activate_chain = false;
@@ -1977,17 +1974,15 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
// they won't have a useful mempool to match against a compact block,
// and we don't feel like constructing the object for them, so
// instead we respond with the full, non-compact block.
- bool fPeerWantsWitness = State(pfrom.GetId())->fWantsCmpctWitness;
- int nSendFlags = fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
if (CanDirectFetch() && pindex->nHeight >= m_chainman.ActiveChain().Height() - MAX_CMPCTBLOCK_DEPTH) {
- if ((fPeerWantsWitness || !fWitnessesPresentInARecentCompactBlock) && a_recent_compact_block && a_recent_compact_block->header.GetHash() == pindex->GetBlockHash()) {
- m_connman.PushMessage(&pfrom, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, *a_recent_compact_block));
+ if (a_recent_compact_block && a_recent_compact_block->header.GetHash() == pindex->GetBlockHash()) {
+ m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::CMPCTBLOCK, *a_recent_compact_block));
} else {
- CBlockHeaderAndShortTxIDs cmpctblock(*pblock, fPeerWantsWitness);
- m_connman.PushMessage(&pfrom, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, cmpctblock));
+ CBlockHeaderAndShortTxIDs cmpctblock(*pblock, true);
+ m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::CMPCTBLOCK, cmpctblock));
}
} else {
- m_connman.PushMessage(&pfrom, msgMaker.Make(nSendFlags, NetMsgType::BLOCK, *pblock));
+ m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::BLOCK, *pblock));
}
}
}
@@ -2146,10 +2141,9 @@ void PeerManagerImpl::SendBlockTransactions(CNode& pfrom, const CBlock& block, c
}
resp.txn[i] = block.vtx[req.indexes[i]];
}
- LOCK(cs_main);
+
const CNetMsgMaker msgMaker(pfrom.GetCommonVersion());
- int nSendFlags = State(pfrom.GetId())->fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
- m_connman.PushMessage(&pfrom, msgMaker.Make(nSendFlags, NetMsgType::BLOCKTXN, resp));
+ m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::BLOCKTXN, resp));
}
void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
@@ -2214,7 +2208,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
}
BlockValidationState state;
- if (!m_chainman.ProcessNewBlockHeaders(headers, state, m_chainparams, &pindexLast)) {
+ if (!m_chainman.ProcessNewBlockHeaders(headers, state, &pindexLast)) {
if (state.IsInvalid()) {
MaybePunishNodeForBlock(pfrom.GetId(), state, via_compact_block, "invalid header received");
return;
@@ -2258,7 +2252,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
while (pindexWalk && !m_chainman.ActiveChain().Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
if (!(pindexWalk->nStatus & BLOCK_HAVE_DATA) &&
!IsBlockRequested(pindexWalk->GetBlockHash()) &&
- (!DeploymentActiveAt(*pindexWalk, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT) || State(pfrom.GetId())->fHaveWitness)) {
+ (!DeploymentActiveAt(*pindexWalk, m_chainman, Consensus::DEPLOYMENT_SEGWIT) || State(pfrom.GetId())->fHaveWitness)) {
// We don't have this block, and it's not yet in flight.
vToFetch.push_back(pindexWalk);
}
@@ -2292,7 +2286,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
}
if (vGetData.size() > 0) {
if (!m_ignore_incoming_txs &&
- nodestate->fSupportsDesiredCmpctVersion &&
+ nodestate->m_provides_cmpctblocks &&
vGetData.size() == 1 &&
mapBlocksInFlight.size() == 1 &&
pindexLast->pprev->IsValid(BLOCK_VALID_CHAIN)) {
@@ -2591,7 +2585,7 @@ void PeerManagerImpl::ProcessGetCFCheckPt(CNode& peer, CDataStream& vRecv)
void PeerManagerImpl::ProcessBlock(CNode& node, const std::shared_ptr<const CBlock>& block, bool force_processing)
{
bool new_block{false};
- m_chainman.ProcessNewBlock(m_chainparams, block, force_processing, &new_block);
+ m_chainman.ProcessNewBlock(block, force_processing, &new_block);
if (new_block) {
node.m_last_block_time = GetTime<std::chrono::seconds>();
} else {
@@ -2862,16 +2856,12 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::SENDHEADERS));
}
if (pfrom.GetCommonVersion() >= SHORT_IDS_BLOCKS_VERSION) {
- // Tell our peer we are willing to provide version 1 or 2 cmpctblocks
+ // Tell our peer we are willing to provide version 2 cmpctblocks.
// However, we do not request new block announcements using
// cmpctblock messages.
// We send this to non-NODE NETWORK peers as well, because
// they may wish to request compact blocks from us
- bool fAnnounceUsingCMPCTBLOCK = false;
- uint64_t nCMPCTBLOCKVersion = 2;
- m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion));
- nCMPCTBLOCKVersion = 1;
- m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion));
+ m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::SENDCMPCT, /*high_bandwidth=*/false, /*version=*/CMPCTBLOCKS_VERSION));
}
pfrom.fSuccessfullyConnected = true;
return;
@@ -2884,26 +2874,20 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
}
if (msg_type == NetMsgType::SENDCMPCT) {
- bool fAnnounceUsingCMPCTBLOCK = false;
- uint64_t nCMPCTBLOCKVersion = 0;
- vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion;
- if (nCMPCTBLOCKVersion == 1 || nCMPCTBLOCKVersion == 2) {
- LOCK(cs_main);
- // fProvidesHeaderAndIDs is used to "lock in" version of compact blocks we send (fWantsCmpctWitness)
- if (!State(pfrom.GetId())->fProvidesHeaderAndIDs) {
- State(pfrom.GetId())->fProvidesHeaderAndIDs = true;
- State(pfrom.GetId())->fWantsCmpctWitness = nCMPCTBLOCKVersion == 2;
- }
- if (State(pfrom.GetId())->fWantsCmpctWitness == (nCMPCTBLOCKVersion == 2)) { // ignore later version announces
- State(pfrom.GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK;
- // save whether peer selects us as BIP152 high-bandwidth peer
- // (receiving sendcmpct(1) signals high-bandwidth, sendcmpct(0) low-bandwidth)
- pfrom.m_bip152_highbandwidth_from = fAnnounceUsingCMPCTBLOCK;
- }
- if (!State(pfrom.GetId())->fSupportsDesiredCmpctVersion) {
- State(pfrom.GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 2);
- }
- }
+ bool sendcmpct_hb{false};
+ uint64_t sendcmpct_version{0};
+ vRecv >> sendcmpct_hb >> sendcmpct_version;
+
+ // Only support compact block relay with witnesses
+ if (sendcmpct_version != CMPCTBLOCKS_VERSION) return;
+
+ LOCK(cs_main);
+ CNodeState* nodestate = State(pfrom.GetId());
+ nodestate->m_provides_cmpctblocks = true;
+ nodestate->m_requested_hb_cmpctblocks = sendcmpct_hb;
+ // save whether peer selects us as BIP152 high-bandwidth peer
+ // (receiving sendcmpct(1) signals high-bandwidth, sendcmpct(0) low-bandwidth)
+ pfrom.m_bip152_highbandwidth_from = sendcmpct_hb;
return;
}
@@ -3252,9 +3236,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
// expensive disk reads, because it will require the peer to
// actually receive all the data read from disk over the network.
LogPrint(BCLog::NET, "Peer %d sent us a getblocktxn for a block > %i deep\n", pfrom.GetId(), MAX_BLOCKTXN_DEPTH);
- CInv inv;
- WITH_LOCK(cs_main, inv.type = State(pfrom.GetId())->fWantsCmpctWitness ? MSG_WITNESS_BLOCK : MSG_BLOCK);
- inv.hash = req.blockhash;
+ CInv inv{MSG_WITNESS_BLOCK, req.blockhash};
WITH_LOCK(peer->m_getdata_requests_mutex, peer->m_getdata_requests.push_back(inv));
// The message processing loop will go around again (without pausing) and we'll respond then
return;
@@ -3569,7 +3551,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
const CBlockIndex *pindex = nullptr;
BlockValidationState state;
- if (!m_chainman.ProcessNewBlockHeaders({cmpctblock.header}, state, m_chainparams, &pindex)) {
+ if (!m_chainman.ProcessNewBlockHeaders({cmpctblock.header}, state, &pindex)) {
if (state.IsInvalid()) {
MaybePunishNodeForBlock(pfrom.GetId(), state, /*via_compact_block=*/true, "invalid header via cmpctblock");
return;
@@ -3629,12 +3611,6 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
return;
}
- if (DeploymentActiveAt(*pindex, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT) && !nodestate->fSupportsDesiredCmpctVersion) {
- // Don't bother trying to process compact blocks from v1 peers
- // after segwit activates.
- return;
- }
-
// We want to be a bit conservative just to be extra careful about DoS
// possibilities in compact block processing...
if (pindex->nHeight <= m_chainman.ActiveChain().Height() + 2) {
@@ -4724,7 +4700,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
LOCK(peer->m_block_inv_mutex);
std::vector<CBlock> vHeaders;
bool fRevertToInv = ((!state.fPreferHeaders &&
- (!state.fPreferHeaderAndIDs || peer->m_blocks_for_headers_relay.size() > 1)) ||
+ (!state.m_requested_hb_cmpctblocks || peer->m_blocks_for_headers_relay.size() > 1)) ||
peer->m_blocks_for_headers_relay.size() > MAX_BLOCKS_TO_ANNOUNCE);
const CBlockIndex *pBestIndex = nullptr; // last header queued for delivery
ProcessBlockAvailability(pto->GetId()); // ensure pindexBestKnownBlock is up-to-date
@@ -4777,24 +4753,17 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
}
}
if (!fRevertToInv && !vHeaders.empty()) {
- if (vHeaders.size() == 1 && state.fPreferHeaderAndIDs) {
+ if (vHeaders.size() == 1 && state.m_requested_hb_cmpctblocks) {
// We only send up to 1 block as header-and-ids, as otherwise
// probably means we're doing an initial-ish-sync or they're slow
LogPrint(BCLog::NET, "%s sending header-and-ids %s to peer=%d\n", __func__,
vHeaders.front().GetHash().ToString(), pto->GetId());
- int nSendFlags = state.fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
-
bool fGotBlockFromCache = false;
{
LOCK(m_most_recent_block_mutex);
if (m_most_recent_block_hash == pBestIndex->GetBlockHash()) {
- if (state.fWantsCmpctWitness || !m_most_recent_compact_block_has_witnesses)
- m_connman.PushMessage(pto, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, *m_most_recent_compact_block));
- else {
- CBlockHeaderAndShortTxIDs cmpctblock(*m_most_recent_block, state.fWantsCmpctWitness);
- m_connman.PushMessage(pto, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, cmpctblock));
- }
+ m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::CMPCTBLOCK, *m_most_recent_compact_block));
fGotBlockFromCache = true;
}
}
@@ -4802,8 +4771,8 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
CBlock block;
bool ret = ReadBlockFromDisk(block, pBestIndex, consensusParams);
assert(ret);
- CBlockHeaderAndShortTxIDs cmpctblock(block, state.fWantsCmpctWitness);
- m_connman.PushMessage(pto, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, cmpctblock));
+ CBlockHeaderAndShortTxIDs cmpctblock(block, true);
+ m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::CMPCTBLOCK, cmpctblock));
}
state.pindexBestHeaderSent = pBestIndex;
} else if (state.fPreferHeaders) {
diff --git a/src/node/miner.cpp b/src/node/miner.cpp
index be5d58527b..770ccdbe1a 100644
--- a/src/node/miner.cpp
+++ b/src/node/miner.cpp
@@ -51,7 +51,7 @@ void RegenerateCommitments(CBlock& block, ChainstateManager& chainman)
block.vtx.at(0) = MakeTransactionRef(tx);
const CBlockIndex* prev_block = WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock));
- GenerateCoinbaseCommitment(block, prev_block, Params().GetConsensus());
+ chainman.GenerateCoinbaseCommitment(block, prev_block);
block.hashMerkleRoot = BlockMerkleRoot(block);
}
@@ -126,7 +126,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
assert(pindexPrev != nullptr);
nHeight = pindexPrev->nHeight + 1;
- pblock->nVersion = g_versionbitscache.ComputeBlockVersion(pindexPrev, chainparams.GetConsensus());
+ pblock->nVersion = m_chainstate.m_chainman.m_versionbitscache.ComputeBlockVersion(pindexPrev, chainparams.GetConsensus());
// -regtest only: allow overriding block.nVersion with
// -blockversion=N to test forking scenarios
if (chainparams.MineBlocksOnDemand()) {
@@ -154,7 +154,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus());
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx));
- pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus());
+ pblocktemplate->vchCoinbaseCommitment = m_chainstate.m_chainman.GenerateCoinbaseCommitment(*pblock, pindexPrev);
pblocktemplate->vTxFees[0] = -nFees;
LogPrintf("CreateNewBlock(): block weight: %u txs: %u fees: %ld sigops %d\n", GetBlockWeight(*pblock), nBlockTx, nFees, nBlockSigOpsCost);
diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h
index 846691c0c0..1c8116738d 100644
--- a/src/qt/clientmodel.h
+++ b/src/qt/clientmodel.h
@@ -61,7 +61,7 @@ public:
//! Return number of connections, default is in- and outbound (total)
int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const;
int getNumBlocks() const;
- uint256 getBestBlockHash();
+ uint256 getBestBlockHash() EXCLUSIVE_LOCKS_REQUIRED(!m_cached_tip_mutex);
int getHeaderTipHeight() const;
int64_t getHeaderTipTime() const;
diff --git a/src/random.cpp b/src/random.cpp
index ad8568bef0..ec4e44ccc2 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -374,7 +374,7 @@ public:
{
}
- void AddEvent(uint32_t event_info) noexcept
+ void AddEvent(uint32_t event_info) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_events_mutex)
{
LOCK(m_events_mutex);
@@ -388,7 +388,7 @@ public:
/**
* Feed (the hash of) all events added through AddEvent() to hasher.
*/
- void SeedEvents(CSHA512& hasher) noexcept
+ void SeedEvents(CSHA512& hasher) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_events_mutex)
{
// We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,
// since we want it to be fast as network peers may be able to trigger it repeatedly.
@@ -407,7 +407,7 @@ public:
*
* If this function has never been called with strong_seed = true, false is returned.
*/
- bool MixExtract(unsigned char* out, size_t num, CSHA512&& hasher, bool strong_seed) noexcept
+ bool MixExtract(unsigned char* out, size_t num, CSHA512&& hasher, bool strong_seed) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{
assert(num <= 32);
unsigned char buf[64];
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 352df4d902..fb79e84c15 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -1063,26 +1063,26 @@ static RPCHelpMan verifychain()
};
}
-static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softforks, const Consensus::Params& params, Consensus::BuriedDeployment dep)
+static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softforks, const ChainstateManager& chainman, Consensus::BuriedDeployment dep)
{
// For buried deployments.
- if (!DeploymentEnabled(params, dep)) return;
+ if (!DeploymentEnabled(chainman, dep)) return;
UniValue rv(UniValue::VOBJ);
rv.pushKV("type", "buried");
// getdeploymentinfo reports the softfork as active from when the chain height is
// one below the activation height
- rv.pushKV("active", DeploymentActiveAfter(blockindex, params, dep));
- rv.pushKV("height", params.DeploymentHeight(dep));
+ rv.pushKV("active", DeploymentActiveAfter(blockindex, chainman, dep));
+ rv.pushKV("height", chainman.GetConsensus().DeploymentHeight(dep));
softforks.pushKV(DeploymentName(dep), rv);
}
-static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softforks, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
+static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softforks, const ChainstateManager& chainman, Consensus::DeploymentPos id)
{
// For BIP9 deployments.
- if (!DeploymentEnabled(consensusParams, id)) return;
+ if (!DeploymentEnabled(chainman, id)) return;
if (blockindex == nullptr) return;
auto get_state_name = [](const ThresholdState state) -> std::string {
@@ -1098,29 +1098,29 @@ static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softfo
UniValue bip9(UniValue::VOBJ);
- const ThresholdState next_state = g_versionbitscache.State(blockindex, consensusParams, id);
- const ThresholdState current_state = g_versionbitscache.State(blockindex->pprev, consensusParams, id);
+ const ThresholdState next_state = chainman.m_versionbitscache.State(blockindex, chainman.GetConsensus(), id);
+ const ThresholdState current_state = chainman.m_versionbitscache.State(blockindex->pprev, chainman.GetConsensus(), id);
const bool has_signal = (ThresholdState::STARTED == current_state || ThresholdState::LOCKED_IN == current_state);
// BIP9 parameters
if (has_signal) {
- bip9.pushKV("bit", consensusParams.vDeployments[id].bit);
+ bip9.pushKV("bit", chainman.GetConsensus().vDeployments[id].bit);
}
- bip9.pushKV("start_time", consensusParams.vDeployments[id].nStartTime);
- bip9.pushKV("timeout", consensusParams.vDeployments[id].nTimeout);
- bip9.pushKV("min_activation_height", consensusParams.vDeployments[id].min_activation_height);
+ bip9.pushKV("start_time", chainman.GetConsensus().vDeployments[id].nStartTime);
+ bip9.pushKV("timeout", chainman.GetConsensus().vDeployments[id].nTimeout);
+ bip9.pushKV("min_activation_height", chainman.GetConsensus().vDeployments[id].min_activation_height);
// BIP9 status
bip9.pushKV("status", get_state_name(current_state));
- bip9.pushKV("since", g_versionbitscache.StateSinceHeight(blockindex->pprev, consensusParams, id));
+ bip9.pushKV("since", chainman.m_versionbitscache.StateSinceHeight(blockindex->pprev, chainman.GetConsensus(), id));
bip9.pushKV("status_next", get_state_name(next_state));
// BIP9 signalling status, if applicable
if (has_signal) {
UniValue statsUV(UniValue::VOBJ);
std::vector<bool> signals;
- BIP9Stats statsStruct = g_versionbitscache.Statistics(blockindex, consensusParams, id, &signals);
+ BIP9Stats statsStruct = chainman.m_versionbitscache.Statistics(blockindex, chainman.GetConsensus(), id, &signals);
statsUV.pushKV("period", statsStruct.period);
statsUV.pushKV("elapsed", statsStruct.elapsed);
statsUV.pushKV("count", statsStruct.count);
@@ -1141,7 +1141,7 @@ static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softfo
UniValue rv(UniValue::VOBJ);
rv.pushKV("type", "bip9");
if (ThresholdState::ACTIVE == next_state) {
- rv.pushKV("height", g_versionbitscache.StateSinceHeight(blockindex, consensusParams, id));
+ rv.pushKV("height", chainman.m_versionbitscache.StateSinceHeight(blockindex, chainman.GetConsensus(), id));
}
rv.pushKV("active", ThresholdState::ACTIVE == next_state);
rv.pushKV("bip9", bip9);
@@ -1151,7 +1151,7 @@ static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softfo
namespace {
/* TODO: when -deprecatedrpc=softforks is removed, drop these */
-UniValue DeploymentInfo(const CBlockIndex* tip, const Consensus::Params& consensusParams);
+UniValue DeploymentInfo(const CBlockIndex* tip, const ChainstateManager& chainman);
extern const std::vector<RPCResult> RPCHelpForDeployment;
}
@@ -1177,7 +1177,7 @@ RPCHelpMan getblockchaininfo()
{RPCResult::Type::STR_HEX, "chainwork", "total amount of work in active chain, in hexadecimal"},
{RPCResult::Type::NUM, "size_on_disk", "the estimated size of the block and undo files on disk"},
{RPCResult::Type::BOOL, "pruned", "if the blocks are subject to pruning"},
- {RPCResult::Type::NUM, "pruneheight", /*optional=*/true, "lowest-height complete block stored (only present if pruning is enabled)"},
+ {RPCResult::Type::NUM, "pruneheight", /*optional=*/true, "height of the last block pruned, plus one (only present if pruning is enabled)"},
{RPCResult::Type::BOOL, "automatic_pruning", /*optional=*/true, "whether automatic pruning is enabled (only present if pruning is enabled)"},
{RPCResult::Type::NUM, "prune_target_size", /*optional=*/true, "the target size used by pruning (only present if automatic pruning is enabled)"},
{RPCResult::Type::OBJ_DYN, "softforks", /*optional=*/true, "(DEPRECATED, returned only if config option -deprecatedrpc=softforks is passed) status of softforks",
@@ -1226,8 +1226,7 @@ RPCHelpMan getblockchaininfo()
}
if (IsDeprecatedRPCEnabled("softforks")) {
- const Consensus::Params& consensusParams = Params().GetConsensus();
- obj.pushKV("softforks", DeploymentInfo(&tip, consensusParams));
+ obj.pushKV("softforks", DeploymentInfo(&tip, chainman));
}
obj.pushKV("warnings", GetWarnings(false).original);
@@ -1262,16 +1261,16 @@ const std::vector<RPCResult> RPCHelpForDeployment{
}},
};
-UniValue DeploymentInfo(const CBlockIndex* blockindex, const Consensus::Params& consensusParams)
+UniValue DeploymentInfo(const CBlockIndex* blockindex, const ChainstateManager& chainman)
{
UniValue softforks(UniValue::VOBJ);
- SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB);
- SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_DERSIG);
- SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_CLTV);
- SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_CSV);
- SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_SEGWIT);
- SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
- SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_TAPROOT);
+ SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_HEIGHTINCB);
+ SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_DERSIG);
+ SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_CLTV);
+ SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_CSV);
+ SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_SEGWIT);
+ SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_TESTDUMMY);
+ SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_TAPROOT);
return softforks;
}
} // anon namespace
@@ -1310,12 +1309,10 @@ static RPCHelpMan getdeploymentinfo()
}
}
- const Consensus::Params& consensusParams = Params().GetConsensus();
-
UniValue deploymentinfo(UniValue::VOBJ);
deploymentinfo.pushKV("hash", blockindex->GetBlockHash().ToString());
deploymentinfo.pushKV("height", blockindex->nHeight);
- deploymentinfo.pushKV("deployments", DeploymentInfo(blockindex, consensusParams));
+ deploymentinfo.pushKV("deployments", DeploymentInfo(blockindex, chainman));
return deploymentinfo;
},
};
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index b552528951..568474fcb9 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -133,7 +133,7 @@ static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t&
}
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
- if (!chainman.ProcessNewBlock(chainparams, shared_pblock, true, nullptr)) {
+ if (!chainman.ProcessNewBlock(shared_pblock, true, nullptr)) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
}
@@ -770,7 +770,7 @@ static RPCHelpMan getblocktemplate()
pblock->nNonce = 0;
// NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration
- const bool fPreSegWit = !DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT);
+ const bool fPreSegWit = !DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_SEGWIT);
UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
@@ -836,7 +836,7 @@ static RPCHelpMan getblocktemplate()
UniValue vbavailable(UniValue::VOBJ);
for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
Consensus::DeploymentPos pos = Consensus::DeploymentPos(j);
- ThresholdState state = g_versionbitscache.State(pindexPrev, consensusParams, pos);
+ ThresholdState state = chainman.m_versionbitscache.State(pindexPrev, consensusParams, pos);
switch (state) {
case ThresholdState::DEFINED:
case ThresholdState::FAILED:
@@ -844,7 +844,7 @@ static RPCHelpMan getblocktemplate()
break;
case ThresholdState::LOCKED_IN:
// Ensure bit is set in block version
- pblock->nVersion |= g_versionbitscache.Mask(consensusParams, pos);
+ pblock->nVersion |= chainman.m_versionbitscache.Mask(consensusParams, pos);
[[fallthrough]];
case ThresholdState::STARTED:
{
@@ -853,7 +853,7 @@ static RPCHelpMan getblocktemplate()
if (setClientRules.find(vbinfo.name) == setClientRules.end()) {
if (!vbinfo.gbt_force) {
// If the client doesn't support this, don't indicate it in the [default] version
- pblock->nVersion &= ~g_versionbitscache.Mask(consensusParams, pos);
+ pblock->nVersion &= ~chainman.m_versionbitscache.Mask(consensusParams, pos);
}
}
break;
@@ -993,14 +993,14 @@ static RPCHelpMan submitblock()
LOCK(cs_main);
const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock);
if (pindex) {
- UpdateUncommittedBlockStructures(block, pindex, Params().GetConsensus());
+ chainman.UpdateUncommittedBlockStructures(block, pindex);
}
}
bool new_block;
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
RegisterSharedValidationInterface(sc);
- bool accepted = chainman.ProcessNewBlock(Params(), blockptr, /*force_processing=*/true, /*new_block=*/&new_block);
+ bool accepted = chainman.ProcessNewBlock(blockptr, /*force_processing=*/true, /*new_block=*/&new_block);
UnregisterSharedValidationInterface(sc);
if (!new_block && accepted) {
return "duplicate";
@@ -1042,7 +1042,7 @@ static RPCHelpMan submitheader()
}
BlockValidationState state;
- chainman.ProcessNewBlockHeaders({h}, state, Params());
+ chainman.ProcessNewBlockHeaders({h}, state);
if (state.IsValid()) return NullUniValue;
if (state.IsError()) {
throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString());
diff --git a/src/scheduler.h b/src/scheduler.h
index b8245f97ed..749e5442b0 100644
--- a/src/scheduler.h
+++ b/src/scheduler.h
@@ -46,10 +46,10 @@ public:
typedef std::function<void()> Function;
/** Call func at/after time t */
- void schedule(Function f, std::chrono::steady_clock::time_point t);
+ void schedule(Function f, std::chrono::steady_clock::time_point t) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex);
/** Call f once after the delta has passed */
- void scheduleFromNow(Function f, std::chrono::milliseconds delta)
+ void scheduleFromNow(Function f, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
{
schedule(std::move(f), std::chrono::steady_clock::now() + delta);
}
@@ -60,29 +60,29 @@ public:
* The timing is not exact: Every time f is finished, it is rescheduled to run again after delta. If you need more
* accurate scheduling, don't use this method.
*/
- void scheduleEvery(Function f, std::chrono::milliseconds delta);
+ void scheduleEvery(Function f, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex);
/**
* Mock the scheduler to fast forward in time.
* Iterates through items on taskQueue and reschedules them
* to be delta_seconds sooner.
*/
- void MockForward(std::chrono::seconds delta_seconds);
+ void MockForward(std::chrono::seconds delta_seconds) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex);
/**
* Services the queue 'forever'. Should be run in a thread.
*/
- void serviceQueue();
+ void serviceQueue() EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex);
/** Tell any threads running serviceQueue to stop as soon as the current task is done */
- void stop()
+ void stop() EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
{
WITH_LOCK(newTaskMutex, stopRequested = true);
newTaskScheduled.notify_all();
if (m_service_thread.joinable()) m_service_thread.join();
}
/** Tell any threads running serviceQueue to stop when there is no work left to be done */
- void StopWhenDrained()
+ void StopWhenDrained() EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
{
WITH_LOCK(newTaskMutex, stopWhenEmpty = true);
newTaskScheduled.notify_all();
@@ -94,10 +94,11 @@ public:
* and first and last task times
*/
size_t getQueueInfo(std::chrono::steady_clock::time_point& first,
- std::chrono::steady_clock::time_point& last) const;
+ std::chrono::steady_clock::time_point& last) const
+ EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex);
/** Returns true if there are threads actively running in serviceQueue() */
- bool AreThreadsServicingQueue() const;
+ bool AreThreadsServicingQueue() const EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex);
private:
mutable Mutex newTaskMutex;
@@ -128,8 +129,8 @@ private:
std::list<std::function<void()>> m_callbacks_pending GUARDED_BY(m_callbacks_mutex);
bool m_are_callbacks_running GUARDED_BY(m_callbacks_mutex) = false;
- void MaybeScheduleProcessQueue();
- void ProcessQueue();
+ void MaybeScheduleProcessQueue() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex);
+ void ProcessQueue() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex);
public:
explicit SingleThreadedSchedulerClient(CScheduler& scheduler LIFETIMEBOUND) : m_scheduler{scheduler} {}
@@ -140,15 +141,15 @@ public:
* Practically, this means that callbacks can behave as if they are executed
* in order by a single thread.
*/
- void AddToProcessQueue(std::function<void()> func);
+ void AddToProcessQueue(std::function<void()> func) EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex);
/**
* Processes all remaining queue members on the calling thread, blocking until queue is empty
* Must be called after the CScheduler has no remaining processing threads!
*/
- void EmptyQueue();
+ void EmptyQueue() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex);
- size_t CallbacksPending();
+ size_t CallbacksPending() EXCLUSIVE_LOCKS_REQUIRED(!m_callbacks_mutex);
};
#endif // BITCOIN_SCHEDULER_H
diff --git a/src/sync.h b/src/sync.h
index c69b58741b..a175926113 100644
--- a/src/sync.h
+++ b/src/sync.h
@@ -83,8 +83,6 @@ void AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLi
inline void DeleteLock(void* cs) {}
inline bool LockStackEmpty() { return true; }
#endif
-#define AssertLockHeld(cs) AssertLockHeldInternal(#cs, __FILE__, __LINE__, &cs)
-#define AssertLockNotHeld(cs) AssertLockNotHeldInternal(#cs, __FILE__, __LINE__, &cs)
/**
* Template mixin that adds -Wthread-safety locking annotations and lock order
@@ -129,7 +127,13 @@ public:
using RecursiveMutex = AnnotatedMixin<std::recursive_mutex>;
/** Wrapped mutex: supports waiting but not recursive locking */
-typedef AnnotatedMixin<std::mutex> Mutex;
+using Mutex = AnnotatedMixin<std::mutex>;
+
+#define AssertLockHeld(cs) AssertLockHeldInternal(#cs, __FILE__, __LINE__, &cs)
+
+inline void AssertLockNotHeldInline(const char* name, const char* file, int line, Mutex* cs) EXCLUSIVE_LOCKS_REQUIRED(!cs) { AssertLockNotHeldInternal(name, file, line, cs); }
+inline void AssertLockNotHeldInline(const char* name, const char* file, int line, RecursiveMutex* cs) LOCKS_EXCLUDED(cs) { AssertLockNotHeldInternal(name, file, line, cs); }
+#define AssertLockNotHeld(cs) AssertLockNotHeldInline(#cs, __FILE__, __LINE__, &cs)
/** Wrapper around std::unique_lock style lock for Mutex. */
template <typename Mutex, typename Base = typename Mutex::UniqueLock>
diff --git a/src/test/blockfilter_index_tests.cpp b/src/test/blockfilter_index_tests.cpp
index 82b9617384..ffb9fb55d9 100644
--- a/src/test/blockfilter_index_tests.cpp
+++ b/src/test/blockfilter_index_tests.cpp
@@ -101,7 +101,7 @@ bool BuildChainTestingSetup::BuildChain(const CBlockIndex* pindex,
CBlockHeader header = block->GetBlockHeader();
BlockValidationState state;
- if (!Assert(m_node.chainman)->ProcessNewBlockHeaders({header}, state, Params(), &pindex)) {
+ if (!Assert(m_node.chainman)->ProcessNewBlockHeaders({header}, state, &pindex)) {
return false;
}
}
@@ -178,7 +178,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
uint256 chainA_last_header = last_header;
for (size_t i = 0; i < 2; i++) {
const auto& block = chainA[i];
- BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr));
+ BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(block, true, nullptr));
}
for (size_t i = 0; i < 2; i++) {
const auto& block = chainA[i];
@@ -196,7 +196,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
uint256 chainB_last_header = last_header;
for (size_t i = 0; i < 3; i++) {
const auto& block = chainB[i];
- BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr));
+ BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(block, true, nullptr));
}
for (size_t i = 0; i < 3; i++) {
const auto& block = chainB[i];
@@ -227,7 +227,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
// Reorg back to chain A.
for (size_t i = 2; i < 4; i++) {
const auto& block = chainA[i];
- BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr));
+ BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(block, true, nullptr));
}
// Check that chain A and B blocks can be retrieved.
diff --git a/src/test/fuzz/utxo_snapshot.cpp b/src/test/fuzz/utxo_snapshot.cpp
index e513f1883c..33496a457e 100644
--- a/src/test/fuzz/utxo_snapshot.cpp
+++ b/src/test/fuzz/utxo_snapshot.cpp
@@ -58,7 +58,7 @@ FUZZ_TARGET_INIT(utxo_snapshot, initialize_chain)
if (fuzzed_data_provider.ConsumeBool()) {
for (const auto& block : *g_chain) {
BlockValidationState dummy;
- bool processed{chainman.ProcessNewBlockHeaders({*block}, dummy, ::Params())};
+ bool processed{chainman.ProcessNewBlockHeaders({*block}, dummy)};
Assert(processed);
const auto* index{WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(block->GetHash()))};
Assert(index);
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index cafa5710fa..0c3a13c5f8 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -587,7 +587,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
pblock->nNonce = bi.nonce;
}
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock);
- BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlock(chainparams, shared_pblock, true, nullptr));
+ BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlock(shared_pblock, true, nullptr));
pblock->hashPrevBlock = pblock->GetHash();
}
diff --git a/src/test/util/mining.cpp b/src/test/util/mining.cpp
index 5ed8598e8e..52e02c4fa4 100644
--- a/src/test/util/mining.cpp
+++ b/src/test/util/mining.cpp
@@ -68,7 +68,7 @@ CTxIn MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
assert(block->nNonce);
}
- bool processed{Assert(node.chainman)->ProcessNewBlock(Params(), block, true, nullptr)};
+ bool processed{Assert(node.chainman)->ProcessNewBlock(block, true, nullptr)};
assert(processed);
return CTxIn{block->vtx[0]->GetHash(), 0};
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
index 2fc71c2a6e..6891629f8e 100644
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -151,6 +151,8 @@ BasicTestingSetup::~BasicTestingSetup()
ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::vector<const char*>& extra_args)
: BasicTestingSetup(chainName, extra_args)
{
+ const CChainParams& chainparams = Params();
+
// We have to run a scheduler thread to prevent ActivateBestChain
// from blocking due to queue overrun.
m_node.scheduler = std::make_unique<CScheduler>();
@@ -162,7 +164,7 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve
m_cache_sizes = CalculateCacheSizes(m_args);
- m_node.chainman = std::make_unique<ChainstateManager>();
+ m_node.chainman = std::make_unique<ChainstateManager>(chainparams);
m_node.chainman->m_blockman.m_block_tree_db = std::make_unique<CBlockTreeDB>(m_cache_sizes.block_tree_db, true);
// Start script-checking threads. Set g_parallel_script_checks to true so they are used.
@@ -298,10 +300,9 @@ CBlock TestChain100Setup::CreateAndProcessBlock(
chainstate = &Assert(m_node.chainman)->ActiveChainstate();
}
- const CChainParams& chainparams = Params();
const CBlock block = this->CreateBlock(txns, scriptPubKey, *chainstate);
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
- Assert(m_node.chainman)->ProcessNewBlock(chainparams, shared_pblock, true, nullptr);
+ Assert(m_node.chainman)->ProcessNewBlock(shared_pblock, true, nullptr);
return block;
}
diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp
index c5b1dabcb7..18882929a8 100644
--- a/src/test/validation_block_tests.cpp
+++ b/src/test/validation_block_tests.cpp
@@ -89,7 +89,7 @@ std::shared_ptr<CBlock> MinerTestingSetup::Block(const uint256& prev_hash)
std::shared_ptr<CBlock> MinerTestingSetup::FinalizeBlock(std::shared_ptr<CBlock> pblock)
{
const CBlockIndex* prev_block{WITH_LOCK(::cs_main, return m_node.chainman->m_blockman.LookupBlockIndex(pblock->hashPrevBlock))};
- GenerateCoinbaseCommitment(*pblock, prev_block, Params().GetConsensus());
+ m_node.chainman->GenerateCoinbaseCommitment(*pblock, prev_block);
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
@@ -100,7 +100,7 @@ std::shared_ptr<CBlock> MinerTestingSetup::FinalizeBlock(std::shared_ptr<CBlock>
// submit block header, so that miner can get the block height from the
// global state and the node has the topology of the chain
BlockValidationState ignored;
- BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlockHeaders({pblock->GetBlockHeader()}, ignored, Params()));
+ BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlockHeaders({pblock->GetBlockHeader()}, ignored));
return pblock;
}
@@ -157,7 +157,7 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
bool ignored;
// Connect the genesis block and drain any outstanding events
- BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlock(Params(), std::make_shared<CBlock>(Params().GenesisBlock()), true, &ignored));
+ BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlock(std::make_shared<CBlock>(Params().GenesisBlock()), true, &ignored));
SyncWithValidationInterfaceQueue();
// subscribe to events (this subscriber will validate event ordering)
@@ -179,13 +179,13 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
FastRandomContext insecure;
for (int i = 0; i < 1000; i++) {
auto block = blocks[insecure.randrange(blocks.size() - 1)];
- Assert(m_node.chainman)->ProcessNewBlock(Params(), block, true, &ignored);
+ Assert(m_node.chainman)->ProcessNewBlock(block, true, &ignored);
}
// to make sure that eventually we process the full chain - do it here
for (auto block : blocks) {
if (block->vtx.size() == 1) {
- bool processed = Assert(m_node.chainman)->ProcessNewBlock(Params(), block, true, &ignored);
+ bool processed = Assert(m_node.chainman)->ProcessNewBlock(block, true, &ignored);
assert(processed);
}
}
@@ -224,7 +224,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
{
bool ignored;
auto ProcessBlock = [&](std::shared_ptr<const CBlock> block) -> bool {
- return Assert(m_node.chainman)->ProcessNewBlock(Params(), block, /*force_processing=*/true, /*new_block=*/&ignored);
+ return Assert(m_node.chainman)->ProcessNewBlock(block, /*force_processing=*/true, /*new_block=*/&ignored);
};
// Process all mined blocks
diff --git a/src/test/validation_chainstate_tests.cpp b/src/test/validation_chainstate_tests.cpp
index 2a3990bb7c..e7c7584f1c 100644
--- a/src/test/validation_chainstate_tests.cpp
+++ b/src/test/validation_chainstate_tests.cpp
@@ -22,7 +22,8 @@ BOOST_FIXTURE_TEST_SUITE(validation_chainstate_tests, TestingSetup)
//!
BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
{
- ChainstateManager manager;
+ const CChainParams& chainparams = Params();
+ ChainstateManager manager(chainparams);
WITH_LOCK(::cs_main, manager.m_blockman.m_block_tree_db = std::make_unique<CBlockTreeDB>(1 << 20, true));
CTxMemPool mempool;
diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp
index bf87812a8a..faea0ce7af 100644
--- a/src/test/versionbits_tests.cpp
+++ b/src/test/versionbits_tests.cpp
@@ -5,7 +5,6 @@
#include <chain.h>
#include <chainparams.h>
#include <consensus/params.h>
-#include <deploymentstatus.h>
#include <test/util/setup_common.h>
#include <validation.h>
#include <versionbits.h>
@@ -257,10 +256,10 @@ BOOST_AUTO_TEST_CASE(versionbits_test)
}
/** Check that ComputeBlockVersion will set the appropriate bit correctly */
-static void check_computeblockversion(const Consensus::Params& params, Consensus::DeploymentPos dep)
+static void check_computeblockversion(VersionBitsCache& versionbitscache, const Consensus::Params& params, Consensus::DeploymentPos dep)
{
- // This implicitly uses g_versionbitscache, so clear it every time
- g_versionbitscache.Clear();
+ // Clear the cache everytime
+ versionbitscache.Clear();
int64_t bit = params.vDeployments[dep].bit;
int64_t nStartTime = params.vDeployments[dep].nStartTime;
@@ -268,7 +267,7 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
int min_activation_height = params.vDeployments[dep].min_activation_height;
// should not be any signalling for first block
- BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(nullptr, params), VERSIONBITS_TOP_BITS);
+ BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(nullptr, params), VERSIONBITS_TOP_BITS);
// always/never active deployments shouldn't need to be tested further
if (nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE ||
@@ -288,7 +287,7 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
// Check min_activation_height is on a retarget boundary
BOOST_REQUIRE_EQUAL(min_activation_height % params.nMinerConfirmationWindow, 0U);
- const uint32_t bitmask{g_versionbitscache.Mask(params, dep)};
+ const uint32_t bitmask{versionbitscache.Mask(params, dep)};
BOOST_CHECK_EQUAL(bitmask, uint32_t{1} << bit);
// In the first chain, test that the bit is set by CBV until it has failed.
@@ -307,9 +306,9 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
// earlier time, so will transition from DEFINED to STARTED at the
// end of the first period by mining blocks at nTime == 0
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
+ BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
// then we'll keep mining at nStartTime...
} else {
// use a time 1s earlier than start time to check we stay DEFINED
@@ -317,28 +316,28 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
// Start generating blocks before nStartTime
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
+ BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
// Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet.
for (uint32_t i = 1; i < params.nMinerConfirmationWindow - 4; i++) {
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
+ BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
}
// Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
// CBV should still not yet set the bit.
nTime = nStartTime;
for (uint32_t i = params.nMinerConfirmationWindow - 4; i <= params.nMinerConfirmationWindow; i++) {
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
+ BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
}
// Next we will advance to the next period and transition to STARTED,
}
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
// so ComputeBlockVersion should now set the bit,
- BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
// and should also be using the VERSIONBITS_TOP_BITS.
- BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
+ BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
// Check that ComputeBlockVersion will set the bit until nTimeout
nTime += 600;
@@ -347,8 +346,8 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
// These blocks are all before nTimeout is reached.
while (nTime < nTimeout && blocksToMine > 0) {
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
- BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
+ BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
blocksToMine--;
nTime += 600;
nHeight += 1;
@@ -362,7 +361,7 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
// finish the last period before we start timing out
while (nHeight % params.nMinerConfirmationWindow != 0) {
lastBlock = firstChain.Mine(nHeight+1, nTime - 1, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
nHeight += 1;
}
@@ -370,12 +369,12 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
// the bit until the period transition.
for (uint32_t i = 0; i < params.nMinerConfirmationWindow - 1; i++) {
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
nHeight += 1;
}
// The next block should trigger no longer setting the bit.
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
+ BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
}
// On a new chain:
@@ -386,34 +385,36 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
// Mine one period worth of blocks, and check that the bit will be on for the
// next period.
lastBlock = secondChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
// Mine another period worth of blocks, signaling the new bit.
lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 2, nTime, VERSIONBITS_TOP_BITS | (1<<bit)).Tip();
// After one period of setting the bit on each block, it should have locked in.
// We keep setting the bit for one more period though, until activation.
- BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
// Now check that we keep mining the block until the end of this period, and
// then stop at the beginning of the next period.
lastBlock = secondChain.Mine((params.nMinerConfirmationWindow * 3) - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
if (lastBlock->nHeight + 1 < min_activation_height) {
// check signalling continues while min_activation_height is not reached
lastBlock = secondChain.Mine(min_activation_height - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
// then reach min_activation_height, which was already REQUIRE'd to start a new period
lastBlock = secondChain.Mine(min_activation_height, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
}
// Check that we don't signal after activation
- BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
+ BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
}
BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
{
+ VersionBitsCache vbcache; // don't use chainman versionbitscache since we want custom chain params
+
// check that any deployment on any chain can conceivably reach both
// ACTIVE and FAILED states in roughly the way we expect
for (const auto& chain_name : {CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::SIGNET, CBaseChainParams::REGTEST}) {
@@ -426,10 +427,10 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
// not take precedence over STARTED/LOCKED_IN. So all softforks on
// the same bit might overlap, even when non-overlapping start-end
// times are picked.
- const uint32_t dep_mask{g_versionbitscache.Mask(chainParams->GetConsensus(), dep)};
+ const uint32_t dep_mask{vbcache.Mask(chainParams->GetConsensus(), dep)};
BOOST_CHECK(!(chain_all_vbits & dep_mask));
chain_all_vbits |= dep_mask;
- check_computeblockversion(chainParams->GetConsensus(), dep);
+ check_computeblockversion(vbcache, chainParams->GetConsensus(), dep);
}
}
@@ -439,7 +440,7 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
ArgsManager args;
args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999"); // January 1, 2008 - December 31, 2008
const auto chainParams = CreateChainParams(args, CBaseChainParams::REGTEST);
- check_computeblockversion(chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
+ check_computeblockversion(vbcache, chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
}
{
@@ -449,7 +450,7 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
ArgsManager args;
args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999:403200"); // January 1, 2008 - December 31, 2008, min act height 403200
const auto chainParams = CreateChainParams(args, CBaseChainParams::REGTEST);
- check_computeblockversion(chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
+ check_computeblockversion(vbcache, chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
}
}
diff --git a/src/threadinterrupt.h b/src/threadinterrupt.h
index cb9a5fbf8b..992016b4f6 100644
--- a/src/threadinterrupt.h
+++ b/src/threadinterrupt.h
@@ -21,11 +21,11 @@ class CThreadInterrupt
public:
CThreadInterrupt();
explicit operator bool() const;
- void operator()();
+ void operator()() EXCLUSIVE_LOCKS_REQUIRED(!mut);
void reset();
- bool sleep_for(std::chrono::milliseconds rel_time);
- bool sleep_for(std::chrono::seconds rel_time);
- bool sleep_for(std::chrono::minutes rel_time);
+ bool sleep_for(std::chrono::milliseconds rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut);
+ bool sleep_for(std::chrono::seconds rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut);
+ bool sleep_for(std::chrono::minutes rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut);
private:
std::condition_variable cond;
diff --git a/src/validation.cpp b/src/validation.cpp
index b5d6a66088..51d77b7945 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -16,7 +16,6 @@
#include <consensus/tx_verify.h>
#include <consensus/validation.h>
#include <cuckoocache.h>
-#include <deploymentstatus.h>
#include <flatfile.h>
#include <hash.h>
#include <logging.h>
@@ -262,7 +261,7 @@ bool CheckSequenceLocksAtTip(CBlockIndex* tip,
}
// Returns the script flags which should be checked for a given block
-static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Consensus::Params& chainparams);
+static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const ChainstateManager& chainman);
static void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache, size_t limit, std::chrono::seconds age)
EXCLUSIVE_LOCKS_REQUIRED(::cs_main, pool.cs)
@@ -1027,7 +1026,6 @@ bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws)
const CTransaction& tx = *ws.m_ptx;
const uint256& hash = ws.m_hash;
TxValidationState& state = ws.m_state;
- const CChainParams& chainparams = args.m_chainparams;
// Check again against the current block tip's script verification
// flags to cache our script execution flags. This is, of course,
@@ -1044,7 +1042,7 @@ bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws)
// There is a similar check in CreateNewBlock() to prevent creating
// invalid blocks (using TestBlockValidity), however allowing such
// transactions into the mempool can be exploited as a DoS attack.
- unsigned int currentBlockScriptVerifyFlags{GetBlockScriptFlags(*m_active_chainstate.m_chain.Tip(), chainparams.GetConsensus())};
+ unsigned int currentBlockScriptVerifyFlags{GetBlockScriptFlags(*m_active_chainstate.m_chain.Tip(), m_active_chainstate.m_chainman)};
if (!CheckInputsFromMempoolAndCache(tx, state, m_view, m_pool, currentBlockScriptVerifyFlags,
ws.m_precomputed_txdata, m_active_chainstate.CoinsTip())) {
LogPrintf("BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s\n", hash.ToString(), state.ToString());
@@ -1457,7 +1455,7 @@ PackageMempoolAcceptResult ProcessNewPackage(CChainState& active_chainstate, CTx
assert(std::all_of(package.cbegin(), package.cend(), [](const auto& tx){return tx != nullptr;}));
std::vector<COutPoint> coins_to_uncache;
- const CChainParams& chainparams = Params();
+ const CChainParams& chainparams = active_chainstate.m_params;
const auto result = [&]() EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
AssertLockHeld(cs_main);
if (test_accept) {
@@ -1515,7 +1513,7 @@ CChainState::CChainState(
std::optional<uint256> from_snapshot_blockhash)
: m_mempool(mempool),
m_blockman(blockman),
- m_params(::Params()),
+ m_params(chainman.GetParams()),
m_chainman(chainman),
m_from_snapshot_blockhash(from_snapshot_blockhash) {}
@@ -1909,10 +1907,11 @@ void StopScriptCheckWorkerThreads()
class WarningBitsConditionChecker : public AbstractThresholdConditionChecker
{
private:
- int bit;
+ const ChainstateManager& m_chainman;
+ int m_bit;
public:
- explicit WarningBitsConditionChecker(int bitIn) : bit(bitIn) {}
+ explicit WarningBitsConditionChecker(const ChainstateManager& chainman, int bit) : m_chainman{chainman}, m_bit(bit) {}
int64_t BeginTime(const Consensus::Params& params) const override { return 0; }
int64_t EndTime(const Consensus::Params& params) const override { return std::numeric_limits<int64_t>::max(); }
@@ -1923,15 +1922,17 @@ public:
{
return pindex->nHeight >= params.MinBIP9WarningHeight &&
((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) &&
- ((pindex->nVersion >> bit) & 1) != 0 &&
- ((g_versionbitscache.ComputeBlockVersion(pindex->pprev, params) >> bit) & 1) == 0;
+ ((pindex->nVersion >> m_bit) & 1) != 0 &&
+ ((m_chainman.m_versionbitscache.ComputeBlockVersion(pindex->pprev, params) >> m_bit) & 1) == 0;
}
};
static std::array<ThresholdConditionCache, VERSIONBITS_NUM_BITS> warningcache GUARDED_BY(cs_main);
-static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Consensus::Params& consensusparams)
+static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const ChainstateManager& chainman)
{
+ const Consensus::Params& consensusparams = chainman.GetConsensus();
+
// BIP16 didn't become active until Apr 1 2012 (on mainnet, and
// retroactively applied to testnet)
// However, only one historical block violated the P2SH rules (on both
@@ -1947,22 +1948,22 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Co
}
// Enforce the DERSIG (BIP66) rule
- if (DeploymentActiveAt(block_index, consensusparams, Consensus::DEPLOYMENT_DERSIG)) {
+ if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_DERSIG)) {
flags |= SCRIPT_VERIFY_DERSIG;
}
// Enforce CHECKLOCKTIMEVERIFY (BIP65)
- if (DeploymentActiveAt(block_index, consensusparams, Consensus::DEPLOYMENT_CLTV)) {
+ if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_CLTV)) {
flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
}
// Enforce CHECKSEQUENCEVERIFY (BIP112)
- if (DeploymentActiveAt(block_index, consensusparams, Consensus::DEPLOYMENT_CSV)) {
+ if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_CSV)) {
flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
}
// Enforce BIP147 NULLDUMMY (activated simultaneously with segwit)
- if (DeploymentActiveAt(block_index, consensusparams, Consensus::DEPLOYMENT_SEGWIT)) {
+ if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_SEGWIT)) {
flags |= SCRIPT_VERIFY_NULLDUMMY;
}
@@ -2153,12 +2154,12 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
// Enforce BIP68 (sequence locks)
int nLockTimeFlags = 0;
- if (DeploymentActiveAt(*pindex, m_params.GetConsensus(), Consensus::DEPLOYMENT_CSV)) {
+ if (DeploymentActiveAt(*pindex, m_chainman, Consensus::DEPLOYMENT_CSV)) {
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
}
// Get the script flags for this block
- unsigned int flags{GetBlockScriptFlags(*pindex, m_params.GetConsensus())};
+ unsigned int flags{GetBlockScriptFlags(*pindex, m_chainman)};
int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1;
LogPrint(BCLog::BENCH, " - Fork checks: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime2 - nTime1), nTimeForks * MICRO, nTimeForks * MILLI / nBlocksTotal);
@@ -2454,9 +2455,9 @@ bool CChainState::FlushStateToDisk(
full_flush_completed = true;
TRACE5(utxocache, flush,
(int64_t)(GetTimeMicros() - nNow.count()), // in microseconds (µs)
- (u_int32_t)mode,
- (u_int64_t)coins_count,
- (u_int64_t)coins_mem_usage,
+ (uint32_t)mode,
+ (uint64_t)coins_count,
+ (uint64_t)coins_mem_usage,
(bool)fFlushForPrune);
}
}
@@ -2556,7 +2557,7 @@ void CChainState::UpdateTip(const CBlockIndex* pindexNew)
if (!this->IsInitialBlockDownload()) {
const CBlockIndex* pindex = pindexNew;
for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) {
- WarningBitsConditionChecker checker(bit);
+ WarningBitsConditionChecker checker(m_chainman, bit);
ThresholdState state = checker.GetStateFor(pindex, m_params.GetConsensus(), warningcache.at(bit));
if (state == ThresholdState::ACTIVE || state == ThresholdState::LOCKED_IN) {
const bilingual_str warning = strprintf(_("Unknown new rules activated (versionbit %i)"), bit);
@@ -3280,7 +3281,7 @@ void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pi
pindexNew->nDataPos = pos.nPos;
pindexNew->nUndoPos = 0;
pindexNew->nStatus |= BLOCK_HAVE_DATA;
- if (DeploymentActiveAt(*pindexNew, m_params.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) {
+ if (DeploymentActiveAt(*pindexNew, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) {
pindexNew->nStatus |= BLOCK_OPT_WITNESS;
}
pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
@@ -3398,11 +3399,11 @@ bool CheckBlock(const CBlock& block, BlockValidationState& state, const Consensu
return true;
}
-void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams)
+void ChainstateManager::UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev) const
{
int commitpos = GetWitnessCommitmentIndex(block);
static const std::vector<unsigned char> nonce(32, 0x00);
- if (commitpos != NO_WITNESS_COMMITMENT && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT) && !block.vtx[0]->HasWitness()) {
+ if (commitpos != NO_WITNESS_COMMITMENT && DeploymentActiveAfter(pindexPrev, *this, Consensus::DEPLOYMENT_SEGWIT) && !block.vtx[0]->HasWitness()) {
CMutableTransaction tx(*block.vtx[0]);
tx.vin[0].scriptWitness.stack.resize(1);
tx.vin[0].scriptWitness.stack[0] = nonce;
@@ -3410,7 +3411,7 @@ void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPr
}
}
-std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams)
+std::vector<unsigned char> ChainstateManager::GenerateCoinbaseCommitment(CBlock& block, const CBlockIndex* pindexPrev) const
{
std::vector<unsigned char> commitment;
int commitpos = GetWitnessCommitmentIndex(block);
@@ -3433,7 +3434,7 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc
tx.vout.push_back(out);
block.vtx[0] = MakeTransactionRef(std::move(tx));
}
- UpdateUncommittedBlockStructures(block, pindexPrev, consensusParams);
+ UpdateUncommittedBlockStructures(block, pindexPrev);
return commitment;
}
@@ -3446,14 +3447,14 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc
* in ConnectBlock().
* Note that -reindex-chainstate skips the validation that happens here!
*/
-static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidationState& state, BlockManager& blockman, const CChainParams& params, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
+static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidationState& state, BlockManager& blockman, const ChainstateManager& chainman, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
{
AssertLockHeld(::cs_main);
assert(pindexPrev != nullptr);
const int nHeight = pindexPrev->nHeight + 1;
// Check proof of work
- const Consensus::Params& consensusParams = params.GetConsensus();
+ const Consensus::Params& consensusParams = chainman.GetConsensus();
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-diffbits", "incorrect proof of work");
@@ -3462,7 +3463,7 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
// Don't accept any forks from the main chain prior to last checkpoint.
// GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our
// BlockIndex().
- const CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(params.Checkpoints());
+ const CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(chainman.GetParams().Checkpoints());
if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
LogPrintf("ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__, nHeight);
return state.Invalid(BlockValidationResult::BLOCK_CHECKPOINT, "bad-fork-prior-to-checkpoint");
@@ -3478,9 +3479,9 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, "time-too-new", "block timestamp too far in the future");
// Reject blocks with outdated version
- if ((block.nVersion < 2 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB)) ||
- (block.nVersion < 3 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_DERSIG)) ||
- (block.nVersion < 4 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CLTV))) {
+ if ((block.nVersion < 2 && DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_HEIGHTINCB)) ||
+ (block.nVersion < 3 && DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_DERSIG)) ||
+ (block.nVersion < 4 && DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_CLTV))) {
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, strprintf("bad-version(0x%08x)", block.nVersion),
strprintf("rejected nVersion=0x%08x block", block.nVersion));
}
@@ -3494,13 +3495,13 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
* in ConnectBlock().
* Note that -reindex-chainstate skips the validation that happens here!
*/
-static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& state, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
+static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& state, const ChainstateManager& chainman, const CBlockIndex* pindexPrev)
{
const int nHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;
// Enforce BIP113 (Median Time Past).
int nLockTimeFlags = 0;
- if (DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CSV)) {
+ if (DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_CSV)) {
assert(pindexPrev != nullptr);
nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST;
}
@@ -3517,7 +3518,7 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
}
// Enforce rule that the coinbase starts with serialized block height
- if (DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB))
+ if (DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_HEIGHTINCB))
{
CScript expect = CScript() << nHeight;
if (block.vtx[0]->vin[0].scriptSig.size() < expect.size() ||
@@ -3535,7 +3536,7 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
// {0xaa, 0x21, 0xa9, 0xed}, and the following 32 bytes are SHA256^2(witness root, witness reserved value). In case there are
// multiple, the last one is used.
bool fHaveWitness = false;
- if (DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT)) {
+ if (DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_SEGWIT)) {
int commitpos = GetWitnessCommitmentIndex(block);
if (commitpos != NO_WITNESS_COMMITMENT) {
bool malleated = false;
@@ -3576,13 +3577,13 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
return true;
}
-bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex)
+bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationState& state, CBlockIndex** ppindex)
{
AssertLockHeld(cs_main);
// Check for duplicate
uint256 hash = block.GetHash();
BlockMap::iterator miSelf{m_blockman.m_block_index.find(hash)};
- if (hash != chainparams.GetConsensus().hashGenesisBlock) {
+ if (hash != GetConsensus().hashGenesisBlock) {
if (miSelf != m_blockman.m_block_index.end()) {
// Block header is already known.
CBlockIndex* pindex = &(miSelf->second);
@@ -3595,7 +3596,7 @@ bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValida
return true;
}
- if (!CheckBlockHeader(block, state, chainparams.GetConsensus())) {
+ if (!CheckBlockHeader(block, state, GetConsensus())) {
LogPrint(BCLog::VALIDATION, "%s: Consensus::CheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString());
return false;
}
@@ -3612,7 +3613,7 @@ bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValida
LogPrint(BCLog::VALIDATION, "%s: %s prev block invalid\n", __func__, hash.ToString());
return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-prevblk");
}
- if (!ContextualCheckBlockHeader(block, state, m_blockman, chainparams, pindexPrev, GetAdjustedTime())) {
+ if (!ContextualCheckBlockHeader(block, state, m_blockman, *this, pindexPrev, GetAdjustedTime())) {
LogPrint(BCLog::VALIDATION, "%s: Consensus::ContextualCheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString());
return false;
}
@@ -3665,14 +3666,14 @@ bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValida
}
// Exposed wrapper for AcceptBlockHeader
-bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex)
+bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, BlockValidationState& state, const CBlockIndex** ppindex)
{
AssertLockNotHeld(cs_main);
{
LOCK(cs_main);
for (const CBlockHeader& header : headers) {
CBlockIndex *pindex = nullptr; // Use a temp pindex instead of ppindex to avoid a const_cast
- bool accepted{AcceptBlockHeader(header, state, chainparams, &pindex)};
+ bool accepted{AcceptBlockHeader(header, state, &pindex)};
ActiveChainstate().CheckBlockIndex();
if (!accepted) {
@@ -3686,7 +3687,7 @@ bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>&
if (NotifyHeaderTip(ActiveChainstate())) {
if (ActiveChainstate().IsInitialBlockDownload() && ppindex && *ppindex) {
const CBlockIndex& last_accepted{**ppindex};
- const int64_t blocks_left{(GetTime() - last_accepted.GetBlockTime()) / chainparams.GetConsensus().nPowTargetSpacing};
+ const int64_t blocks_left{(GetTime() - last_accepted.GetBlockTime()) / GetConsensus().nPowTargetSpacing};
const double progress{100.0 * last_accepted.nHeight / (last_accepted.nHeight + blocks_left)};
LogPrintf("Synchronizing blockheaders, height: %d (~%.2f%%)\n", last_accepted.nHeight, progress);
}
@@ -3705,7 +3706,7 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
CBlockIndex *pindexDummy = nullptr;
CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
- bool accepted_header{m_chainman.AcceptBlockHeader(block, state, m_params, &pindex)};
+ bool accepted_header{m_chainman.AcceptBlockHeader(block, state, &pindex)};
CheckBlockIndex();
if (!accepted_header)
@@ -3745,7 +3746,7 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
}
if (!CheckBlock(block, state, m_params.GetConsensus()) ||
- !ContextualCheckBlock(block, state, m_params.GetConsensus(), pindex->pprev)) {
+ !ContextualCheckBlock(block, state, m_chainman, pindex->pprev)) {
if (state.IsInvalid() && state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
pindex->nStatus |= BLOCK_FAILED_VALID;
m_blockman.m_dirty_blockindex.insert(pindex);
@@ -3778,7 +3779,7 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
return true;
}
-bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock>& block, bool force_processing, bool* new_block)
+bool ChainstateManager::ProcessNewBlock(const std::shared_ptr<const CBlock>& block, bool force_processing, bool* new_block)
{
AssertLockNotHeld(cs_main);
@@ -3796,7 +3797,7 @@ bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const s
// malleability that cause CheckBlock() to fail; see e.g. CVE-2012-2459 and
// https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-February/016697.html. Because CheckBlock() is
// not very expensive, the anti-DoS benefits of caching failure (of a definitely-invalid block) are not substantial.
- bool ret = CheckBlock(*block, state, chainparams.GetConsensus());
+ bool ret = CheckBlock(*block, state, GetConsensus());
if (ret) {
// Store to disk
ret = ActiveChainstate().AcceptBlock(block, state, &pindex, force_processing, nullptr, new_block);
@@ -3849,11 +3850,11 @@ bool TestBlockValidity(BlockValidationState& state,
indexDummy.phashBlock = &block_hash;
// NOTE: CheckBlockHeader is called by CheckBlock
- if (!ContextualCheckBlockHeader(block, state, chainstate.m_blockman, chainparams, pindexPrev, GetAdjustedTime()))
+ if (!ContextualCheckBlockHeader(block, state, chainstate.m_blockman, chainstate.m_chainman, pindexPrev, GetAdjustedTime()))
return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.ToString());
if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot))
return error("%s: Consensus::CheckBlock: %s", __func__, state.ToString());
- if (!ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindexPrev))
+ if (!ContextualCheckBlock(block, state, chainstate.m_chainman, pindexPrev))
return error("%s: Consensus::ContextualCheckBlock: %s", __func__, state.ToString());
if (!chainstate.ConnectBlock(block, state, &indexDummy, viewNew, true)) {
return false;
@@ -4133,7 +4134,7 @@ bool CChainState::NeedsRedownload() const
// At and above m_params.SegwitHeight, segwit consensus rules must be validated
CBlockIndex* block{m_chain.Tip()};
- while (block != nullptr && DeploymentActiveAt(*block, m_params.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) {
+ while (block != nullptr && DeploymentActiveAt(*block, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) {
if (!(block->nStatus & BLOCK_OPT_WITNESS)) {
// block is insufficiently validated for a segwit client
return true;
@@ -4993,7 +4994,7 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
}
int base_height = snapshot_start_block->nHeight;
- auto maybe_au_data = ExpectedAssumeutxo(base_height, ::Params());
+ auto maybe_au_data = ExpectedAssumeutxo(base_height, GetParams());
if (!maybe_au_data) {
LogPrintf("[snapshot] assumeutxo height in snapshot metadata not recognized " /* Continued */
@@ -5147,7 +5148,7 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
// Fake BLOCK_OPT_WITNESS so that CChainState::NeedsRedownload()
// won't ask to rewind the entire assumed-valid chain on startup.
- if (DeploymentActiveAt(*index, ::Params().GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) {
+ if (DeploymentActiveAt(*index, *this, Consensus::DEPLOYMENT_SEGWIT)) {
index->nStatus |= BLOCK_OPT_WITNESS;
}
@@ -5216,9 +5217,9 @@ ChainstateManager::~ChainstateManager()
{
LOCK(::cs_main);
- // TODO: The version bits cache and warning cache should probably become
- // non-globals
- g_versionbitscache.Clear();
+ m_versionbitscache.Clear();
+
+ // TODO: The warning cache should probably become non-global
for (auto& i : warningcache) {
i.clear();
}
diff --git a/src/validation.h b/src/validation.h
index 42e41502f9..04745a6e36 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -13,7 +13,9 @@
#include <arith_uint256.h>
#include <attributes.h>
#include <chain.h>
+#include <chainparams.h>
#include <consensus/amount.h>
+#include <deploymentstatus.h>
#include <fs.h>
#include <node/blockstorage.h>
#include <policy/feerate.h>
@@ -26,6 +28,7 @@
#include <util/check.h>
#include <util/hasher.h>
#include <util/translation.h>
+#include <versionbits.h>
#include <atomic>
#include <map>
@@ -40,7 +43,6 @@
class CChainState;
class CBlockTreeDB;
-class CChainParams;
class CTxMemPool;
class ChainstateManager;
struct ChainTxData;
@@ -51,6 +53,9 @@ struct AssumeutxoData;
namespace node {
class SnapshotMetadata;
} // namespace node
+namespace Consensus {
+struct Params;
+} // namespace Consensus
/** Default for -minrelaytxfee, minimum relay fee for transactions */
static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 1000;
@@ -359,12 +364,6 @@ bool TestBlockValidity(BlockValidationState& state,
bool fCheckPOW = true,
bool fCheckMerkleRoot = true) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
-/** Update uncommitted block structures (currently: only the witness reserved value). This is safe for submitted blocks. */
-void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams);
-
-/** Produce the necessary coinbase commitment for a block (modifies the hash, don't call for mined blocks). */
-std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams);
-
/** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */
class CVerifyDB {
public:
@@ -495,6 +494,7 @@ public:
node::BlockManager& m_blockman;
/** Chain parameters for this chainstate */
+ /* TODO: replace with m_chainman.GetParams() */
const CChainParams& m_params;
//! The chainstate manager that owns this chainstate. The reference is
@@ -834,6 +834,8 @@ private:
CBlockIndex* m_best_invalid GUARDED_BY(::cs_main){nullptr};
+ const CChainParams& m_chainparams;
+
//! Internal helper for ActivateSnapshot().
[[nodiscard]] bool PopulateAndValidateSnapshot(
CChainState& snapshot_chainstate,
@@ -847,11 +849,15 @@ private:
bool AcceptBlockHeader(
const CBlockHeader& block,
BlockValidationState& state,
- const CChainParams& chainparams,
CBlockIndex** ppindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
friend CChainState;
public:
+ explicit ChainstateManager(const CChainParams& chainparams) : m_chainparams{chainparams} { }
+
+ const CChainParams& GetParams() const { return m_chainparams; }
+ const Consensus::Params& GetConsensus() const { return m_chainparams.GetConsensus(); }
+
std::thread m_load_block;
//! A single BlockManager instance is shared across each constructed
//! chainstate to avoid duplicating block metadata.
@@ -932,6 +938,11 @@ public:
return m_blockman.m_block_index;
}
+ /**
+ * Track versionbit status
+ */
+ mutable VersionBitsCache m_versionbitscache;
+
//! @returns true if a snapshot-based chainstate is in use. Also implies
//! that a background validation chainstate is also in use.
bool IsSnapshotActive() const;
@@ -960,7 +971,7 @@ public:
* @param[out] new_block A boolean which is set to indicate if the block was first received via this call
* @returns If the block was processed, independently of block validity
*/
- bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock>& block, bool force_processing, bool* new_block) LOCKS_EXCLUDED(cs_main);
+ bool ProcessNewBlock(const std::shared_ptr<const CBlock>& block, bool force_processing, bool* new_block) LOCKS_EXCLUDED(cs_main);
/**
* Process incoming block headers.
@@ -970,10 +981,9 @@ public:
*
* @param[in] block The block headers themselves
* @param[out] state This may be set to an Error state if any error occurred processing them
- * @param[in] chainparams The params for the chain we want to connect to
* @param[out] ppindex If set, the pointer will be set to point to the last new block index object for the given headers
*/
- bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex = nullptr) LOCKS_EXCLUDED(cs_main);
+ bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, BlockValidationState& state, const CBlockIndex** ppindex = nullptr) LOCKS_EXCLUDED(cs_main);
/**
* Try to add a transaction to the memory pool.
@@ -991,9 +1001,34 @@ public:
//! ResizeCoinsCaches() as needed.
void MaybeRebalanceCaches() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
+ /** Update uncommitted block structures (currently: only the witness reserved value). This is safe for submitted blocks. */
+ void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev) const;
+
+ /** Produce the necessary coinbase commitment for a block (modifies the hash, don't call for mined blocks). */
+ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBlockIndex* pindexPrev) const;
+
~ChainstateManager();
};
+/** Deployment* info via ChainstateManager */
+template<typename DEP>
+bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const ChainstateManager& chainman, DEP dep)
+{
+ return DeploymentActiveAfter(pindexPrev, chainman.GetConsensus(), dep, chainman.m_versionbitscache);
+}
+
+template<typename DEP>
+bool DeploymentActiveAt(const CBlockIndex& index, const ChainstateManager& chainman, DEP dep)
+{
+ return DeploymentActiveAt(index, chainman.GetConsensus(), dep, chainman.m_versionbitscache);
+}
+
+template<typename DEP>
+bool DeploymentEnabled(const ChainstateManager& chainman, DEP dep)
+{
+ return DeploymentEnabled(chainman.GetConsensus(), dep);
+}
+
using FopenFn = std::function<FILE*(const fs::path&, const char*)>;
/** Dump the mempool to disk. */
diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp
index edc4633c01..fffab39cc1 100644
--- a/src/validationinterface.cpp
+++ b/src/validationinterface.cpp
@@ -16,14 +16,16 @@
#include <unordered_map>
#include <utility>
-//! The MainSignalsInstance manages a list of shared_ptr<CValidationInterface>
-//! callbacks.
-//!
-//! A std::unordered_map is used to track what callbacks are currently
-//! registered, and a std::list is to used to store the callbacks that are
-//! currently registered as well as any callbacks that are just unregistered
-//! and about to be deleted when they are done executing.
-struct MainSignalsInstance {
+/**
+ * MainSignalsImpl manages a list of shared_ptr<CValidationInterface> callbacks.
+ *
+ * A std::unordered_map is used to track what callbacks are currently
+ * registered, and a std::list is used to store the callbacks that are
+ * currently registered as well as any callbacks that are just unregistered
+ * and about to be deleted when they are done executing.
+ */
+class MainSignalsImpl
+{
private:
Mutex m_mutex;
//! List entries consist of a callback pointer and reference count. The
@@ -40,9 +42,9 @@ public:
// our own queue here :(
SingleThreadedSchedulerClient m_schedulerClient;
- explicit MainSignalsInstance(CScheduler& scheduler LIFETIMEBOUND) : m_schedulerClient(scheduler) {}
+ explicit MainSignalsImpl(CScheduler& scheduler LIFETIMEBOUND) : m_schedulerClient(scheduler) {}
- void Register(std::shared_ptr<CValidationInterface> callbacks)
+ void Register(std::shared_ptr<CValidationInterface> callbacks) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{
LOCK(m_mutex);
auto inserted = m_map.emplace(callbacks.get(), m_list.end());
@@ -50,7 +52,7 @@ public:
inserted.first->second->callbacks = std::move(callbacks);
}
- void Unregister(CValidationInterface* callbacks)
+ void Unregister(CValidationInterface* callbacks) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{
LOCK(m_mutex);
auto it = m_map.find(callbacks);
@@ -64,7 +66,7 @@ public:
//! map entry. After this call, the list may still contain callbacks that
//! are currently executing, but it will be cleared when they are done
//! executing.
- void Clear()
+ void Clear() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{
LOCK(m_mutex);
for (const auto& entry : m_map) {
@@ -73,7 +75,7 @@ public:
m_map.clear();
}
- template<typename F> void Iterate(F&& f)
+ template<typename F> void Iterate(F&& f) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{
WAIT_LOCK(m_mutex, lock);
for (auto it = m_list.begin(); it != m_list.end();) {
@@ -92,7 +94,7 @@ static CMainSignals g_signals;
void CMainSignals::RegisterBackgroundSignalScheduler(CScheduler& scheduler)
{
assert(!m_internals);
- m_internals = std::make_unique<MainSignalsInstance>(scheduler);
+ m_internals = std::make_unique<MainSignalsImpl>(scheduler);
}
void CMainSignals::UnregisterBackgroundSignalScheduler()
diff --git a/src/validationinterface.h b/src/validationinterface.h
index ac62f8b467..a929a3d56b 100644
--- a/src/validationinterface.h
+++ b/src/validationinterface.h
@@ -17,9 +17,7 @@ class BlockValidationState;
class CBlock;
class CBlockIndex;
struct CBlockLocator;
-class CConnman;
class CValidationInterface;
-class uint256;
class CScheduler;
enum class MemPoolRemovalReason;
@@ -177,10 +175,10 @@ protected:
friend class ValidationInterfaceTest;
};
-struct MainSignalsInstance;
+class MainSignalsImpl;
class CMainSignals {
private:
- std::unique_ptr<MainSignalsInstance> m_internals;
+ std::unique_ptr<MainSignalsImpl> m_internals;
friend void ::RegisterSharedValidationInterface(std::shared_ptr<CValidationInterface>);
friend void ::UnregisterValidationInterface(CValidationInterface*);
diff --git a/src/versionbits.h b/src/versionbits.h
index 1b3fa11e61..9f7ee1b48e 100644
--- a/src/versionbits.h
+++ b/src/versionbits.h
@@ -92,16 +92,16 @@ public:
static uint32_t Mask(const Consensus::Params& params, Consensus::DeploymentPos pos);
/** Get the BIP9 state for a given deployment for the block after pindexPrev. */
- ThresholdState State(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos);
+ ThresholdState State(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
/** Get the block height at which the BIP9 deployment switched into the state for the block after pindexPrev. */
- int StateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos);
+ int StateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
/** Determine what nVersion a new block should use
*/
- int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params);
+ int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
- void Clear();
+ void Clear() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
};
#endif // BITCOIN_VERSIONBITS_H
diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp
index 1aa0339445..f8230f7a1d 100644
--- a/src/wallet/bdb.cpp
+++ b/src/wallet/bdb.cpp
@@ -99,7 +99,7 @@ void BerkeleyEnvironment::Close()
if (ret != 0)
LogPrintf("BerkeleyEnvironment::Close: Error %d closing database environment: %s\n", ret, DbEnv::strerror(ret));
if (!fMockDb)
- DbEnv((u_int32_t)0).remove(strPath.c_str(), 0);
+ DbEnv((uint32_t)0).remove(strPath.c_str(), 0);
if (error_file) fclose(error_file);
@@ -248,7 +248,7 @@ const void* BerkeleyBatch::SafeDbt::get_data() const
return m_dbt.get_data();
}
-u_int32_t BerkeleyBatch::SafeDbt::get_size() const
+uint32_t BerkeleyBatch::SafeDbt::get_size() const
{
return m_dbt.get_size();
}
diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h
index 1c99e1f9af..ddab85521b 100644
--- a/src/wallet/bdb.h
+++ b/src/wallet/bdb.h
@@ -34,7 +34,7 @@ struct bilingual_str;
namespace wallet {
struct WalletDatabaseFileId {
- u_int8_t value[DB_FILE_ID_LEN];
+ uint8_t value[DB_FILE_ID_LEN];
bool operator==(const WalletDatabaseFileId& rhs) const;
};
@@ -182,7 +182,7 @@ class BerkeleyBatch : public DatabaseBatch
// delegate to Dbt
const void* get_data() const;
- u_int32_t get_size() const;
+ uint32_t get_size() const;
// conversion operator to access the underlying Dbt
operator Dbt*();