aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2021-04-01 10:58:37 +0200
committerMarcoFalke <falke.marco@gmail.com>2021-04-01 10:58:53 +0200
commit80a699fda9ff1129546cabbf17e955680a1cc705 (patch)
tree782dbdd906096d3b1a60ccae2f8604d8e25aa25d
parentc2caa0fc4d5668308a717de454003d3ff46a6a85 (diff)
parent693414d27181cf967f787a2ca72344e52c58c7f0 (diff)
Merge #21525: [Bundle 4.5/n] Followup fixups to bundle 4
693414d27181cf967f787a2ca72344e52c58c7f0 node/ifaces: ChainImpl: Use an accessor for ChainMan (Carl Dong) 98c4e252f0d09bebb2e4ad3289407459c2cda5d5 node/ifaces: NodeImpl: Use an accessor for ChainMan (Carl Dong) 7e8b5ee814b0b8c34acb20637ed4fc988ccba555 validation: Make BlockManager::LookupBlockIndex const (Carl Dong) 88aead263c61d86e5f836028f517cfbf2a575498 node: Avoid potential UB by asserting assumptions (Carl Dong) 1dd8ed7a8491e51b76eeb236b15b794d9254f674 net_processing: Move comments to declarations (Carl Dong) 07156eb387ea580be5e2ce4a1744992ce7575903 node/coinstats: Replace #include with fwd-declaration (Carl Dong) 7b8e976cd5ac78a22f1be2b2fed8562c693af5d9 miner: Add chainstate member to BlockAssembler (Carl Dong) e62067e7bcad5a559899afff2e4a8e8b7e9f4301 Revert "miner: Pass in chainstate to BlockAssembler::CreateNewBlock" (Carl Dong) eede0647b06b6009080c4e536a2705e911d6ee19 Revert "scripted-diff: Invoke CreateNewBlock with chainstate" (Carl Dong) 0c1b2bc549aec77b247f0103652d883227841ac5 Revert "miner: Remove old CreateNewBlock w/o chainstate param" (Carl Dong) Pull request description: Chronological history of this changeset: 1. Bundle 4 (#21270) got merged 2. Posthumous reviews were posted 3. These changes were prepended in bundle 5 4. More reviews were added in bundle 5 5. Someone suggested that we split the prepended changes up to another PR 6. This is that PR In the future, I will just do posthumous review changes in another PR instead. I apologize for the confusion. Addresses posthumous reviews on bundle 4: - From jnewbery: - https://github.com/bitcoin/bitcoin/pull/21270#issuecomment-796738048 - I didn't fix this one, but I added a `TODO` comment so that we don't lost track of it - https://github.com/bitcoin/bitcoin/pull/21270#discussion_r592291225 - https://github.com/bitcoin/bitcoin/pull/21270#discussion_r592296942 - https://github.com/bitcoin/bitcoin/pull/21270#discussion_r592299738 - https://github.com/bitcoin/bitcoin/pull/21270#discussion_r592301704 - From MarcoFalke: - https://github.com/bitcoin/bitcoin/pull/21270#discussion_r593096212 - https://github.com/bitcoin/bitcoin/pull/21270#discussion_r593097032 - https://github.com/bitcoin/bitcoin/pull/21270#discussion_r593097867 - https://github.com/bitcoin/bitcoin/pull/21270#discussion_r593100570 Addresses reviews on bundle 5: - Checking chainman existence before locking cs_main - MarcoFalke - https://github.com/bitcoin/bitcoin/pull/21391#discussion_r596601776 - https://github.com/bitcoin/bitcoin/pull/21391#discussion_r596601876 - Appropriate locking, usage of chainman, and control flow in `src/node/interfaces.cpp` - MarcoFalke - https://github.com/bitcoin/bitcoin/pull/21391#discussion_r596601383 - jnewbery - https://github.com/bitcoin/bitcoin/pull/21391#discussion_r597029360 - https://github.com/bitcoin/bitcoin/pull/21391#discussion_r597029921 - ryanofsky - https://github.com/bitcoin/bitcoin/pull/21391#discussion_r597163828 - Style/comment formatting changes - jnewbery - https://github.com/bitcoin/bitcoin/pull/21391#discussion_r597026552 - https://github.com/bitcoin/bitcoin/pull/21391#discussion_r597027186 - Making LookupBlockIndex const - jnewbery - https://github.com/bitcoin/bitcoin/pull/21391#discussion_r597035062 ACKs for top commit: MarcoFalke: review ACK 693414d27181cf967f787a2ca72344e52c58c7f0 🛐 ryanofsky: Code review ACK 693414d27181cf967f787a2ca72344e52c58c7f0. I reviewed this previously as part of #21391. I am a fan of the increasingly complicated bundle numbering, and kind of hope there in the next round there is some way we can get bundles 5.333333 and 5.666667! jamesob: ACK 693414d27181cf967f787a2ca72344e52c58c7f0 ([`jamesob/ackr/21525.1.dongcarl.bundle_4_5_n_followup_f`](https://github.com/jamesob/bitcoin/tree/ackr/21525.1.dongcarl.bundle_4_5_n_followup_f)) Tree-SHA512: 9bdc199f70400d01764e1bd03c25bdb6cff26dcef60e4ca3b649baf8d017a2dfc1f058099067962b4b6ccd32d078002b1389d733039f4c337558cb70324c0ee3
-rw-r--r--src/miner.cpp19
-rw-r--r--src/miner.h8
-rw-r--r--src/net_processing.cpp101
-rw-r--r--src/node/coin.cpp1
-rw-r--r--src/node/coinstats.h2
-rw-r--r--src/node/interfaces.cpp69
-rw-r--r--src/node/transaction.cpp1
-rw-r--r--src/rpc/mining.cpp6
-rw-r--r--src/test/blockfilter_index_tests.cpp2
-rw-r--r--src/test/miner_tests.cpp40
-rw-r--r--src/test/util/mining.cpp4
-rw-r--r--src/test/util/setup_common.cpp2
-rw-r--r--src/test/validation_block_tests.cpp4
-rw-r--r--src/validation.cpp2
-rw-r--r--src/validation.h2
15 files changed, 148 insertions, 115 deletions
diff --git a/src/miner.cpp b/src/miner.cpp
index fe7a54c052..8a9406f810 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -55,9 +55,10 @@ BlockAssembler::Options::Options() {
nBlockMaxWeight = DEFAULT_BLOCK_MAX_WEIGHT;
}
-BlockAssembler::BlockAssembler(const CTxMemPool& mempool, const CChainParams& params, const Options& options)
+BlockAssembler::BlockAssembler(CChainState& chainstate, const CTxMemPool& mempool, const CChainParams& params, const Options& options)
: chainparams(params),
- m_mempool(mempool)
+ m_mempool(mempool),
+ m_chainstate(chainstate)
{
blockMinFeeRate = options.blockMinFeeRate;
// Limit weight to between 4K and MAX_BLOCK_WEIGHT-4K for sanity:
@@ -79,8 +80,8 @@ static BlockAssembler::Options DefaultOptions()
return options;
}
-BlockAssembler::BlockAssembler(const CTxMemPool& mempool, const CChainParams& params)
- : BlockAssembler(mempool, params, DefaultOptions()) {}
+BlockAssembler::BlockAssembler(CChainState& chainstate, const CTxMemPool& mempool, const CChainParams& params)
+ : BlockAssembler(chainstate, mempool, params, DefaultOptions()) {}
void BlockAssembler::resetBlock()
{
@@ -96,7 +97,7 @@ void BlockAssembler::resetBlock()
nFees = 0;
}
-std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(CChainState& chainstate, const CScript& scriptPubKeyIn)
+std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn)
{
int64_t nTimeStart = GetTimeMicros();
@@ -114,8 +115,8 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(CChainState& chai
pblocktemplate->vTxSigOpsCost.push_back(-1); // updated at end
LOCK2(cs_main, m_mempool.cs);
- assert(std::addressof(*::ChainActive().Tip()) == std::addressof(*chainstate.m_chain.Tip()));
- CBlockIndex* pindexPrev = chainstate.m_chain.Tip();
+ assert(std::addressof(*::ChainActive().Tip()) == std::addressof(*m_chainstate.m_chain.Tip()));
+ CBlockIndex* pindexPrev = m_chainstate.m_chain.Tip();
assert(pindexPrev != nullptr);
nHeight = pindexPrev->nHeight + 1;
@@ -174,8 +175,8 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(CChainState& chai
pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(*pblock->vtx[0]);
BlockValidationState state;
- assert(std::addressof(::ChainstateActive()) == std::addressof(chainstate));
- if (!TestBlockValidity(state, chainparams, chainstate, *pblock, pindexPrev, false, false)) {
+ assert(std::addressof(::ChainstateActive()) == std::addressof(m_chainstate));
+ if (!TestBlockValidity(state, chainparams, m_chainstate, *pblock, pindexPrev, false, false)) {
throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, state.ToString()));
}
int64_t nTime2 = GetTimeMicros();
diff --git a/src/miner.h b/src/miner.h
index 023635814c..c400c90f6c 100644
--- a/src/miner.h
+++ b/src/miner.h
@@ -146,6 +146,7 @@ private:
int64_t nLockTimeCutoff;
const CChainParams& chainparams;
const CTxMemPool& m_mempool;
+ CChainState& m_chainstate;
public:
struct Options {
@@ -154,11 +155,11 @@ public:
CFeeRate blockMinFeeRate;
};
- explicit BlockAssembler(const CTxMemPool& mempool, const CChainParams& params);
- explicit BlockAssembler(const CTxMemPool& mempool, const CChainParams& params, const Options& options);
+ explicit BlockAssembler(CChainState& chainstate, const CTxMemPool& mempool, const CChainParams& params);
+ explicit BlockAssembler(CChainState& chainstate, const CTxMemPool& mempool, const CChainParams& params, const Options& options);
/** Construct a new block template with coinbase to scriptPubKeyIn */
- std::unique_ptr<CBlockTemplate> CreateNewBlock(CChainState& chainstate, const CScript& scriptPubKeyIn);
+ std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn);
inline static std::optional<int64_t> m_last_block_num_txs{};
inline static std::optional<int64_t> m_last_block_weight{};
@@ -201,6 +202,7 @@ private:
void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
+// TODO just accept a CBlockIndex*
/** Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed */
void RegenerateCommitments(CBlock& block, BlockManager& blockman);
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 14b628acf0..17d7619ff5 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -482,19 +482,70 @@ private:
/** Offset into vExtraTxnForCompact to insert the next tx */
size_t vExtraTxnForCompactIt GUARDED_BY(g_cs_orphans) = 0;
+ /** Check whether the last unknown block a peer advertised is not yet known. */
void ProcessBlockAvailability(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ /** Update tracking information about which blocks a peer is assumed to have. */
void UpdateBlockAvailability(NodeId nodeid, const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
bool CanDirectFetch() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+
+ /**
+ * To prevent fingerprinting attacks, only send blocks/headers outside of
+ * the active chain if they are no more than a month older (both in time,
+ * and in best equivalent proof of work) than the best header chain we know
+ * about and we fully-validated them at some point.
+ */
bool BlockRequestAllowed(const CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
bool AlreadyHaveBlock(const uint256& block_hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
void ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv& inv);
+
+ /**
+ * Validation logic for compact filters request handling.
+ *
+ * May disconnect from the peer in the case of a bad request.
+ *
+ * @param[in] peer The peer that we received the request from
+ * @param[in] filter_type The filter type the request is for. Must be basic filters.
+ * @param[in] start_height The start height for the request
+ * @param[in] stop_hash The stop_hash for the request
+ * @param[in] max_height_diff The maximum number of items permitted to request, as specified in BIP 157
+ * @param[out] stop_index The CBlockIndex for the stop_hash block, if the request can be serviced.
+ * @param[out] filter_index The filter index, if the request can be serviced.
+ * @return True if the request can be serviced.
+ */
bool PrepareBlockFilterRequest(CNode& peer,
BlockFilterType filter_type, uint32_t start_height,
const uint256& stop_hash, uint32_t max_height_diff,
const CBlockIndex*& stop_index,
BlockFilterIndex*& filter_index);
+
+ /**
+ * Handle a cfilters request.
+ *
+ * May disconnect from the peer in the case of a bad request.
+ *
+ * @param[in] peer The peer that we received the request from
+ * @param[in] vRecv The raw message received
+ */
void ProcessGetCFilters(CNode& peer, CDataStream& vRecv);
+
+ /**
+ * Handle a cfheaders request.
+ *
+ * May disconnect from the peer in the case of a bad request.
+ *
+ * @param[in] peer The peer that we received the request from
+ * @param[in] vRecv The raw message received
+ */
void ProcessGetCFHeaders(CNode& peer, CDataStream& vRecv);
+
+ /**
+ * Handle a getcfcheckpt request.
+ *
+ * May disconnect from the peer in the case of a bad request.
+ *
+ * @param[in] peer The peer that we received the request from
+ * @param[in] vRecv The raw message received
+ */
void ProcessGetCFCheckPt(CNode& peer, CDataStream& vRecv);
};
} // namespace
@@ -748,7 +799,6 @@ static bool PeerHasHeader(CNodeState *state, const CBlockIndex *pindex) EXCLUSIV
return false;
}
-/** Check whether the last unknown block a peer advertised is not yet known. */
void PeerManagerImpl::ProcessBlockAvailability(NodeId nodeid) {
CNodeState *state = State(nodeid);
assert(state != nullptr);
@@ -764,7 +814,6 @@ void PeerManagerImpl::ProcessBlockAvailability(NodeId nodeid) {
}
}
-/** Update tracking information about which blocks a peer is assumed to have. */
void PeerManagerImpl::UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) {
CNodeState *state = State(nodeid);
assert(state != nullptr);
@@ -1191,16 +1240,6 @@ bool PeerManagerImpl::MaybePunishNodeForTx(NodeId nodeid, const TxValidationStat
return false;
}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// blockchain -> download logic notification
-//
-
-// To prevent fingerprinting attacks, only send blocks/headers outside of the
-// active chain if they are no more than a month older (both in time, and in
-// best equivalent proof of work) than the best header chain we know about and
-// we fully-validated them at some point.
bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex* pindex)
{
AssertLockHeld(cs_main);
@@ -2101,20 +2140,6 @@ void PeerManagerImpl::ProcessOrphanTx(std::set<uint256>& orphan_work_set)
m_mempool.check(m_chainman.ActiveChainstate());
}
-/**
- * Validation logic for compact filters request handling.
- *
- * May disconnect from the peer in the case of a bad request.
- *
- * @param[in] peer The peer that we received the request from
- * @param[in] filter_type The filter type the request is for. Must be basic filters.
- * @param[in] start_height The start height for the request
- * @param[in] stop_hash The stop_hash for the request
- * @param[in] max_height_diff The maximum number of items permitted to request, as specified in BIP 157
- * @param[out] stop_index The CBlockIndex for the stop_hash block, if the request can be serviced.
- * @param[out] filter_index The filter index, if the request can be serviced.
- * @return True if the request can be serviced.
- */
bool PeerManagerImpl::PrepareBlockFilterRequest(CNode& peer,
BlockFilterType filter_type, uint32_t start_height,
const uint256& stop_hash, uint32_t max_height_diff,
@@ -2168,14 +2193,6 @@ bool PeerManagerImpl::PrepareBlockFilterRequest(CNode& peer,
return true;
}
-/**
- * Handle a cfilters request.
- *
- * May disconnect from the peer in the case of a bad request.
- *
- * @param[in] peer The peer that we received the request from
- * @param[in] vRecv The raw message received
- */
void PeerManagerImpl::ProcessGetCFilters(CNode& peer, CDataStream& vRecv)
{
uint8_t filter_type_ser;
@@ -2207,14 +2224,6 @@ void PeerManagerImpl::ProcessGetCFilters(CNode& peer, CDataStream& vRecv)
}
}
-/**
- * Handle a cfheaders request.
- *
- * May disconnect from the peer in the case of a bad request.
- *
- * @param[in] peer The peer that we received the request from
- * @param[in] vRecv The raw message received
- */
void PeerManagerImpl::ProcessGetCFHeaders(CNode& peer, CDataStream& vRecv)
{
uint8_t filter_type_ser;
@@ -2259,14 +2268,6 @@ void PeerManagerImpl::ProcessGetCFHeaders(CNode& peer, CDataStream& vRecv)
m_connman.PushMessage(&peer, std::move(msg));
}
-/**
- * Handle a getcfcheckpt request.
- *
- * May disconnect from the peer in the case of a bad request.
- *
- * @param[in] peer The peer that we received the request from
- * @param[in] vRecv The raw message received
- */
void PeerManagerImpl::ProcessGetCFCheckPt(CNode& peer, CDataStream& vRecv)
{
uint8_t filter_type_ser;
diff --git a/src/node/coin.cpp b/src/node/coin.cpp
index 263dcff657..23d4fa2aae 100644
--- a/src/node/coin.cpp
+++ b/src/node/coin.cpp
@@ -11,6 +11,7 @@
void FindCoins(const NodeContext& node, std::map<COutPoint, Coin>& coins)
{
assert(node.mempool);
+ assert(node.chainman);
LOCK2(cs_main, node.mempool->cs);
assert(std::addressof(::ChainstateActive()) == std::addressof(node.chainman->ActiveChainstate()));
CCoinsViewCache& chain_view = node.chainman->ActiveChainstate().CoinsTip();
diff --git a/src/node/coinstats.h b/src/node/coinstats.h
index 83f228aa7e..975651dcc4 100644
--- a/src/node/coinstats.h
+++ b/src/node/coinstats.h
@@ -8,11 +8,11 @@
#include <amount.h>
#include <uint256.h>
-#include <validation.h>
#include <cstdint>
#include <functional>
+class BlockManager;
class CCoinsView;
enum class CoinStatsHashType {
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
index 0f4094e14b..7ad02f81dc 100644
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -65,6 +65,8 @@ namespace node {
namespace {
class NodeImpl : public Node
{
+private:
+ ChainstateManager& chainman() { return *Assert(m_context->chainman); }
public:
explicit NodeImpl(NodeContext* context) { setContext(context); }
void initLogging() override { InitLogging(*Assert(m_context->args)); }
@@ -183,21 +185,28 @@ public:
int getNumBlocks() override
{
LOCK(::cs_main);
- assert(std::addressof(::ChainActive()) == std::addressof(m_context->chainman->ActiveChain()));
- return m_context->chainman->ActiveChain().Height();
+ assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain()));
+ return chainman().ActiveChain().Height();
}
uint256 getBestBlockHash() override
{
- assert(std::addressof(::ChainActive()) == std::addressof(m_context->chainman->ActiveChain()));
- const CBlockIndex* tip = WITH_LOCK(::cs_main, return m_context->chainman->ActiveChain().Tip());
+ const CBlockIndex* tip;
+ {
+ // TODO: Temporary scope to check correctness of refactored code.
+ // Should be removed manually after merge of
+ // https://github.com/bitcoin/bitcoin/pull/20158
+ LOCK(cs_main);
+ assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain()));
+ tip = chainman().ActiveChain().Tip();
+ }
return tip ? tip->GetBlockHash() : Params().GenesisBlock().GetHash();
}
int64_t getLastBlockTime() override
{
LOCK(::cs_main);
- assert(std::addressof(::ChainActive()) == std::addressof(m_context->chainman->ActiveChain()));
- if (m_context->chainman->ActiveChain().Tip()) {
- return m_context->chainman->ActiveChain().Tip()->GetBlockTime();
+ assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain()));
+ if (chainman().ActiveChain().Tip()) {
+ return chainman().ActiveChain().Tip()->GetBlockTime();
}
return Params().GenesisBlock().GetBlockTime(); // Genesis block's time of current network
}
@@ -206,14 +215,22 @@ public:
const CBlockIndex* tip;
{
LOCK(::cs_main);
- assert(std::addressof(::ChainActive()) == std::addressof(m_context->chainman->ActiveChain()));
- tip = m_context->chainman->ActiveChain().Tip();
+ assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain()));
+ tip = chainman().ActiveChain().Tip();
}
return GuessVerificationProgress(Params().TxData(), tip);
}
bool isInitialBlockDownload() override {
- assert(std::addressof(::ChainstateActive()) == std::addressof(m_context->chainman->ActiveChainstate()));
- return m_context->chainman->ActiveChainstate().IsInitialBlockDownload();
+ const CChainState* active_chainstate;
+ {
+ // TODO: Temporary scope to check correctness of refactored code.
+ // Should be removed manually after merge of
+ // https://github.com/bitcoin/bitcoin/pull/20158
+ LOCK(::cs_main);
+ active_chainstate = &m_context->chainman->ActiveChainstate();
+ assert(std::addressof(::ChainstateActive()) == std::addressof(*active_chainstate));
+ }
+ return active_chainstate->IsInitialBlockDownload();
}
bool getReindex() override { return ::fReindex; }
bool getImporting() override { return ::fImporting; }
@@ -239,8 +256,8 @@ public:
bool getUnspentOutput(const COutPoint& output, Coin& coin) override
{
LOCK(::cs_main);
- assert(std::addressof(::ChainstateActive()) == std::addressof(m_context->chainman->ActiveChainstate()));
- return m_context->chainman->ActiveChainstate().CoinsTip().GetCoin(output, coin);
+ assert(std::addressof(::ChainstateActive()) == std::addressof(chainman().ActiveChainstate()));
+ return chainman().ActiveChainstate().CoinsTip().GetCoin(output, coin);
}
WalletClient& walletClient() override
{
@@ -414,6 +431,8 @@ public:
class ChainImpl : public Chain
{
+private:
+ ChainstateManager& chainman() { return *Assert(m_node.chainman); }
public:
explicit ChainImpl(NodeContext& node) : m_node(node) {}
std::optional<int> getHeight() override
@@ -450,8 +469,8 @@ public:
bool checkFinalTx(const CTransaction& tx) override
{
LOCK(cs_main);
- assert(std::addressof(::ChainActive()) == std::addressof(m_node.chainman->ActiveChain()));
- return CheckFinalTx(m_node.chainman->ActiveChain().Tip(), tx);
+ assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain()));
+ return CheckFinalTx(chainman().ActiveChain().Tip(), tx);
}
std::optional<int> findLocatorFork(const CBlockLocator& locator) override
{
@@ -516,8 +535,8 @@ public:
double guessVerificationProgress(const uint256& block_hash) override
{
LOCK(cs_main);
- assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
- return GuessVerificationProgress(Params().TxData(), m_node.chainman->m_blockman.LookupBlockIndex(block_hash));
+ assert(std::addressof(g_chainman.m_blockman) == std::addressof(chainman().m_blockman));
+ return GuessVerificationProgress(Params().TxData(), chainman().m_blockman.LookupBlockIndex(block_hash));
}
bool hasBlocks(const uint256& block_hash, int min_height, std::optional<int> max_height) override
{
@@ -529,8 +548,8 @@ public:
// used to limit the range, and passing min_height that's too low or
// max_height that's too high will not crash or change the result.
LOCK(::cs_main);
- assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
- if (CBlockIndex* block = m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) {
+ assert(std::addressof(g_chainman.m_blockman) == std::addressof(chainman().m_blockman));
+ if (CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash)) {
if (max_height && block->nHeight >= *max_height) block = block->GetAncestor(*max_height);
for (; block->nStatus & BLOCK_HAVE_DATA; block = block->pprev) {
// Check pprev to not segfault if min_height is too low
@@ -621,8 +640,16 @@ public:
}
bool isReadyToBroadcast() override { return !::fImporting && !::fReindex && !isInitialBlockDownload(); }
bool isInitialBlockDownload() override {
- assert(std::addressof(::ChainstateActive()) == std::addressof(m_node.chainman->ActiveChainstate()));
- return m_node.chainman->ActiveChainstate().IsInitialBlockDownload();
+ const CChainState* active_chainstate;
+ {
+ // TODO: Temporary scope to check correctness of refactored code.
+ // Should be removed manually after merge of
+ // https://github.com/bitcoin/bitcoin/pull/20158
+ LOCK(::cs_main);
+ active_chainstate = &chainman().ActiveChainstate();
+ assert(std::addressof(::ChainstateActive()) == std::addressof(*active_chainstate));
+ }
+ return active_chainstate->IsInitialBlockDownload();
}
bool shutdownRequested() override { return ShutdownRequested(); }
int64_t getAdjustedTime() override { return GetAdjustedTime(); }
diff --git a/src/node/transaction.cpp b/src/node/transaction.cpp
index f47e85aceb..691b2791d7 100644
--- a/src/node/transaction.cpp
+++ b/src/node/transaction.cpp
@@ -38,6 +38,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
bool callback_set = false;
{ // cs_main scope
+ assert(node.chainman);
LOCK(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(node.chainman->ActiveChainstate()));
// If the transaction is already confirmed in the chain, don't do anything
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index fd780ba782..72ad0df199 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -150,7 +150,7 @@ static UniValue generateBlocks(ChainstateManager& chainman, const CTxMemPool& me
UniValue blockHashes(UniValue::VARR);
while (nHeight < nHeightEnd && !ShutdownRequested())
{
- std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(mempool, Params()).CreateNewBlock(::ChainstateActive(), coinbase_script));
+ std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(chainman.ActiveChainstate(), mempool, Params()).CreateNewBlock(coinbase_script));
if (!pblocktemplate.get())
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
CBlock *pblock = &pblocktemplate->block;
@@ -358,7 +358,7 @@ static RPCHelpMan generateblock()
LOCK(cs_main);
CTxMemPool empty_mempool;
- std::unique_ptr<CBlockTemplate> blocktemplate(BlockAssembler(empty_mempool, chainparams).CreateNewBlock(::ChainstateActive(), coinbase_script));
+ std::unique_ptr<CBlockTemplate> blocktemplate(BlockAssembler(::ChainstateActive(), empty_mempool, chainparams).CreateNewBlock(coinbase_script));
if (!blocktemplate) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
}
@@ -748,7 +748,7 @@ static RPCHelpMan getblocktemplate()
// Create new block
CScript scriptDummy = CScript() << OP_TRUE;
- pblocktemplate = BlockAssembler(mempool, Params()).CreateNewBlock(::ChainstateActive(), scriptDummy);
+ pblocktemplate = BlockAssembler(::ChainstateActive(), mempool, Params()).CreateNewBlock(scriptDummy);
if (!pblocktemplate)
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
diff --git a/src/test/blockfilter_index_tests.cpp b/src/test/blockfilter_index_tests.cpp
index 04da10715f..9903ba75cb 100644
--- a/src/test/blockfilter_index_tests.cpp
+++ b/src/test/blockfilter_index_tests.cpp
@@ -62,7 +62,7 @@ CBlock BuildChainTestingSetup::CreateBlock(const CBlockIndex* prev,
const CScript& scriptPubKey)
{
const CChainParams& chainparams = Params();
- std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(*m_node.mempool, chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey);
+ std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(::ChainstateActive(), *m_node.mempool, chainparams).CreateNewBlock(scriptPubKey);
CBlock& block = pblocktemplate->block;
block.hashPrevBlock = prev->GetBlockHash();
block.nTime = prev->nTime + 1;
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index 9acd17c463..9ba004cc38 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -44,7 +44,7 @@ BlockAssembler MinerTestingSetup::AssemblerForTest(const CChainParams& params)
options.nBlockMaxWeight = MAX_BLOCK_WEIGHT;
options.blockMinFeeRate = blockMinFeeRate;
- return BlockAssembler(*m_node.mempool, params, options);
+ return BlockAssembler(::ChainstateActive(), *m_node.mempool, params, options);
}
constexpr static struct {
@@ -122,7 +122,7 @@ void MinerTestingSetup::TestPackageSelection(const CChainParams& chainparams, co
uint256 hashHighFeeTx = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(50000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
- std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey);
+ std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 4U);
BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashParentTx);
BOOST_CHECK(pblocktemplate->block.vtx[2]->GetHash() == hashHighFeeTx);
@@ -143,7 +143,7 @@ void MinerTestingSetup::TestPackageSelection(const CChainParams& chainparams, co
tx.vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse;
uint256 hashLowFeeTx = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(feeToUse).FromTx(tx));
- pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey);
+ pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
// Verify that the free tx and the low fee tx didn't get selected
for (size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeTx);
@@ -157,7 +157,7 @@ void MinerTestingSetup::TestPackageSelection(const CChainParams& chainparams, co
tx.vout[0].nValue -= 2; // Now we should be just over the min relay fee
hashLowFeeTx = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(feeToUse+2).FromTx(tx));
- pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey);
+ pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 6U);
BOOST_CHECK(pblocktemplate->block.vtx[4]->GetHash() == hashFreeTx);
BOOST_CHECK(pblocktemplate->block.vtx[5]->GetHash() == hashLowFeeTx);
@@ -179,7 +179,7 @@ void MinerTestingSetup::TestPackageSelection(const CChainParams& chainparams, co
tx.vout[0].nValue = 5000000000LL - 100000000 - feeToUse;
uint256 hashLowFeeTx2 = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx));
- pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey);
+ pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
// Verify that this tx isn't selected.
for (size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
@@ -192,7 +192,7 @@ void MinerTestingSetup::TestPackageSelection(const CChainParams& chainparams, co
tx.vin[0].prevout.n = 1;
tx.vout[0].nValue = 100000000 - 10000; // 10k satoshi fee
m_node.mempool->addUnchecked(entry.Fee(10000).FromTx(tx));
- pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey);
+ pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 9U);
BOOST_CHECK(pblocktemplate->block.vtx[8]->GetHash() == hashLowFeeTx2);
}
@@ -215,7 +215,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
fCheckpointsEnabled = false;
// Simple block creation, nothing special yet:
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
// We can't make transactions until we have inputs
// Therefore, load 110 blocks :)
@@ -252,7 +252,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
LOCK(m_node.mempool->cs);
// Just to make sure we can still make simple blocks
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
const CAmount BLOCKSUBSIDY = 50*COIN;
const CAmount LOWFEE = CENT;
@@ -277,7 +277,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vin[0].prevout.hash = hash;
}
- BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey), std::runtime_error, HasReason("bad-blk-sigops"));
+ BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-blk-sigops"));
m_node.mempool->clear();
tx.vin[0].prevout.hash = txFirst[0]->GetHash();
@@ -291,7 +291,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
m_node.mempool->addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOpsCost(80).FromTx(tx));
tx.vin[0].prevout.hash = hash;
}
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
m_node.mempool->clear();
// block size > limit
@@ -311,13 +311,13 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
m_node.mempool->addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx));
tx.vin[0].prevout.hash = hash;
}
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
m_node.mempool->clear();
// orphan in *m_node.mempool, template creation fails
hash = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).FromTx(tx));
- BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey), std::runtime_error, HasReason("bad-txns-inputs-missingorspent"));
+ BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-txns-inputs-missingorspent"));
m_node.mempool->clear();
// child with higher feerate than parent
@@ -334,7 +334,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].nValue = tx.vout[0].nValue+BLOCKSUBSIDY-HIGHERFEE; //First txn output + fresh coinbase - new txn fee
hash = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(HIGHERFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
m_node.mempool->clear();
// coinbase in *m_node.mempool, template creation fails
@@ -346,7 +346,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
// give it a fee so it'll get mined
m_node.mempool->addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
// Should throw bad-cb-multiple
- BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey), std::runtime_error, HasReason("bad-cb-multiple"));
+ BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-cb-multiple"));
m_node.mempool->clear();
// double spend txn pair in *m_node.mempool, template creation fails
@@ -359,7 +359,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].scriptPubKey = CScript() << OP_2;
hash = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
- BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey), std::runtime_error, HasReason("bad-txns-inputs-missingorspent"));
+ BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-txns-inputs-missingorspent"));
m_node.mempool->clear();
// subsidy changing
@@ -375,7 +375,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
next->BuildSkip();
::ChainActive().SetTip(next);
}
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
// Extend to a 210000-long block chain.
while (::ChainActive().Tip()->nHeight < 210000) {
CBlockIndex* prev = ::ChainActive().Tip();
@@ -387,7 +387,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
next->BuildSkip();
::ChainActive().SetTip(next);
}
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
// invalid p2sh txn in *m_node.mempool, template creation fails
tx.vin[0].prevout.hash = txFirst[0]->GetHash();
@@ -404,7 +404,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
hash = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
// Should throw block-validation-failed
- BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey), std::runtime_error, HasReason("block-validation-failed"));
+ BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("block-validation-failed"));
m_node.mempool->clear();
// Delete the dummy blocks again.
@@ -492,7 +492,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | 1;
BOOST_CHECK(!TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks fail
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
// None of the of the absolute height/time locked tx should have made
// it into the template because we still check IsFinalTx in CreateNewBlock,
@@ -505,7 +505,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
::ChainActive().Tip()->nHeight++;
SetMockTime(::ChainActive().Tip()->GetMedianTimePast() + 1);
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5U);
::ChainActive().Tip()->nHeight--;
diff --git a/src/test/util/mining.cpp b/src/test/util/mining.cpp
index ba1edba0ae..3fc3329da2 100644
--- a/src/test/util/mining.cpp
+++ b/src/test/util/mining.cpp
@@ -41,8 +41,8 @@ CTxIn MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
{
auto block = std::make_shared<CBlock>(
- BlockAssembler{*Assert(node.mempool), Params()}
- .CreateNewBlock(::ChainstateActive(), coinbase_scriptPubKey)
+ BlockAssembler{::ChainstateActive(), *Assert(node.mempool), Params()}
+ .CreateNewBlock(coinbase_scriptPubKey)
->block);
LOCK(cs_main);
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
index bfb3466dcf..f7800aefca 100644
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -247,7 +247,7 @@ CBlock TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransa
{
const CChainParams& chainparams = Params();
CTxMemPool empty_pool;
- CBlock block = BlockAssembler(empty_pool, chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey)->block;
+ CBlock block = BlockAssembler(::ChainstateActive(), empty_pool, chainparams).CreateNewBlock(scriptPubKey)->block;
Assert(block.vtx.size() == 1);
for (const CMutableTransaction& tx : txns) {
diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp
index f3fc83078f..552be0a2da 100644
--- a/src/test/validation_block_tests.cpp
+++ b/src/test/validation_block_tests.cpp
@@ -63,7 +63,7 @@ std::shared_ptr<CBlock> MinerTestingSetup::Block(const uint256& prev_hash)
static int i = 0;
static uint64_t time = Params().GenesisBlock().nTime;
- auto ptemplate = BlockAssembler(*m_node.mempool, Params()).CreateNewBlock(::ChainstateActive(), CScript{} << i++ << OP_TRUE);
+ auto ptemplate = BlockAssembler(m_node.chainman->ActiveChainstate(), *m_node.mempool, Params()).CreateNewBlock(CScript{} << i++ << OP_TRUE);
auto pblock = std::make_shared<CBlock>(ptemplate->block);
pblock->hashPrevBlock = prev_hash;
pblock->nTime = ++time;
@@ -325,7 +325,7 @@ BOOST_AUTO_TEST_CASE(witness_commitment_index)
{
CScript pubKey;
pubKey << 1 << OP_TRUE;
- auto ptemplate = BlockAssembler(*m_node.mempool, Params()).CreateNewBlock(::ChainstateActive(), pubKey);
+ auto ptemplate = BlockAssembler(m_node.chainman->ActiveChainstate(), *m_node.mempool, Params()).CreateNewBlock(pubKey);
CBlock pblock = ptemplate->block;
CTxOut witness;
diff --git a/src/validation.cpp b/src/validation.cpp
index d1b9efe7ba..b5c19971b4 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -169,7 +169,7 @@ namespace {
std::set<int> setDirtyFileInfo;
} // anon namespace
-CBlockIndex* BlockManager::LookupBlockIndex(const uint256& hash)
+CBlockIndex* BlockManager::LookupBlockIndex(const uint256& hash) const
{
AssertLockHeld(cs_main);
assert(std::addressof(g_chainman.BlockIndex()) == std::addressof(m_block_index));
diff --git a/src/validation.h b/src/validation.h
index 2ff5f4ac87..21e63947fa 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -457,7 +457,7 @@ public:
const CChainParams& chainparams,
CBlockIndex** ppindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
- CBlockIndex* LookupBlockIndex(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ CBlockIndex* LookupBlockIndex(const uint256& hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/** Find the last common block between the parameter chain and a locator. */
CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator) EXCLUSIVE_LOCKS_REQUIRED(cs_main);