mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 10:38:42 +01:00
Merge #21270: [Bundle 4/n] Prune g_chainman usage in validation-adjacent modules
a67983cd6d
net_processing: Add review-only assertion to PeerManager (Carl Dong)272d993e75
scripted-diff: net_processing: Use existing chainman (Carl Dong)021a04a469
net_processing: Move some static functions to PeerManager (Carl Dong)91c5b68acd
node/ifaces: ChainImpl: Use existing NodeContext member (Carl Dong)8a1d580b21
node/ifaces: NodeImpl: Use existing NodeContext member (Carl Dong)4cde4a701b
node: Use existing NodeContext (Carl Dong)106bcd4f39
node/coinstats: Pass in BlockManager to GetUTXOStats (Carl Dong)2c3ba00693
miner: Pass in blockman to ::RegenerateCommitments (Carl Dong)2afcf24408
miner: Remove old CreateNewBlock w/o chainstate param (Carl Dong)46b7f29340
scripted-diff: Invoke CreateNewBlock with chainstate (Carl Dong)d0de61b764
miner: Pass in chainstate to BlockAssembler::CreateNewBlock (Carl Dong)a04aac493f
validation: Remove extraneous LoadGenesisBlock function prototype (Carl Dong) Pull request description: Overall PR: #20158 (tree-wide: De-globalize ChainstateManager) Based on: - [x] #21055 | [Bundle 3/n] Prune g_chainman usage in mempool-related validation functions Note to reviewers: 1. This bundle may _apparently_ introduce usage of `g_chainman` or `::Chain(state|)Active()` globals, but these are resolved later on in the overall PR. [Commits of overall PR](https://github.com/bitcoin/bitcoin/pull/20158/commits) 2. There may be seemingly obvious local references to `ChainstateManager` or other validation objects which are not being used in callers of the current function in question, this is done intentionally to **_keep each commit centered around one function/method_** to ease review and to make the overall change systematic. We don't assume anything about our callers. Rest assured that once we are considering that particular caller in later commits, we will use the obvious local references. [Commits of overall PR](https://github.com/bitcoin/bitcoin/pull/20158/commits) 3. When changing a function/method that has many callers (e.g. `LookupBlockIndex` with 55 callers), it is sometimes easier (and less error-prone) to use a scripted-diff. When doing so, there will be 3 commits in sequence so that every commit compiles like so: 1. Add `new_function`, make `old_function` a wrapper of `new_function`, divert all calls to `old_function` to `new_function` **in the local module only** 2. Scripted-diff to divert all calls to `old_function` to `new_function` **in the rest of the codebase** 3. Remove `old_function` ACKs for top commit: laanwj: Code review ACKa67983cd6d
ryanofsky: Code review ACKa67983cd6d
. Only change since last review new first commit fixing header declaration, and rebase glozow: code review ACKa67983cd6d
Tree-SHA512: dce182a18b88be80cbf50978d4ba8fa6ab0f01e861d09bae0ae9364051bb78f9334859d164b185b07f1d70a583e739557fab6d820cac8c37b3855b85c2a6771b
This commit is contained in:
commit
767bb7d5c5
@ -39,13 +39,13 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam
|
||||
return nNewTime - nOldTime;
|
||||
}
|
||||
|
||||
void RegenerateCommitments(CBlock& block)
|
||||
void RegenerateCommitments(CBlock& block, BlockManager& blockman)
|
||||
{
|
||||
CMutableTransaction tx{*block.vtx.at(0)};
|
||||
tx.vout.erase(tx.vout.begin() + GetWitnessCommitmentIndex(block));
|
||||
block.vtx.at(0) = MakeTransactionRef(tx);
|
||||
|
||||
GenerateCoinbaseCommitment(block, WITH_LOCK(cs_main, return g_chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock)), Params().GetConsensus());
|
||||
GenerateCoinbaseCommitment(block, WITH_LOCK(::cs_main, assert(std::addressof(g_chainman.m_blockman) == std::addressof(blockman)); return blockman.LookupBlockIndex(block.hashPrevBlock)), Params().GetConsensus());
|
||||
|
||||
block.hashMerkleRoot = BlockMerkleRoot(block);
|
||||
}
|
||||
@ -99,7 +99,7 @@ void BlockAssembler::resetBlock()
|
||||
Optional<int64_t> BlockAssembler::m_last_block_num_txs{nullopt};
|
||||
Optional<int64_t> BlockAssembler::m_last_block_weight{nullopt};
|
||||
|
||||
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn)
|
||||
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(CChainState& chainstate, const CScript& scriptPubKeyIn)
|
||||
{
|
||||
int64_t nTimeStart = GetTimeMicros();
|
||||
|
||||
@ -117,7 +117,8 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
||||
pblocktemplate->vTxSigOpsCost.push_back(-1); // updated at end
|
||||
|
||||
LOCK2(cs_main, m_mempool.cs);
|
||||
CBlockIndex* pindexPrev = ::ChainActive().Tip();
|
||||
assert(std::addressof(*::ChainActive().Tip()) == std::addressof(*chainstate.m_chain.Tip()));
|
||||
CBlockIndex* pindexPrev = chainstate.m_chain.Tip();
|
||||
assert(pindexPrev != nullptr);
|
||||
nHeight = pindexPrev->nHeight + 1;
|
||||
|
||||
@ -176,7 +177,8 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
||||
pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(*pblock->vtx[0]);
|
||||
|
||||
BlockValidationState state;
|
||||
if (!TestBlockValidity(state, chainparams, ::ChainstateActive(), *pblock, pindexPrev, false, false)) {
|
||||
assert(std::addressof(::ChainstateActive()) == std::addressof(chainstate));
|
||||
if (!TestBlockValidity(state, chainparams, chainstate, *pblock, pindexPrev, false, false)) {
|
||||
throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, state.ToString()));
|
||||
}
|
||||
int64_t nTime2 = GetTimeMicros();
|
||||
|
@ -158,7 +158,7 @@ public:
|
||||
explicit BlockAssembler(const CTxMemPool& mempool, const CChainParams& params, const Options& options);
|
||||
|
||||
/** Construct a new block template with coinbase to scriptPubKeyIn */
|
||||
std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn);
|
||||
std::unique_ptr<CBlockTemplate> CreateNewBlock(CChainState& chainstate, const CScript& scriptPubKeyIn);
|
||||
|
||||
static Optional<int64_t> m_last_block_num_txs;
|
||||
static Optional<int64_t> m_last_block_weight;
|
||||
@ -202,6 +202,6 @@ void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned
|
||||
int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
|
||||
|
||||
/** Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed */
|
||||
void RegenerateCommitments(CBlock& block);
|
||||
void RegenerateCommitments(CBlock& block, BlockManager& blockman);
|
||||
|
||||
#endif // BITCOIN_MINER_H
|
||||
|
@ -472,6 +472,24 @@ private:
|
||||
std::vector<std::pair<uint256, CTransactionRef>> vExtraTxnForCompact GUARDED_BY(g_cs_orphans);
|
||||
/** Offset into vExtraTxnForCompact to insert the next tx */
|
||||
size_t vExtraTxnForCompactIt GUARDED_BY(g_cs_orphans) = 0;
|
||||
|
||||
void ProcessBlockAvailability(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
bool CanDirectFetch(const Consensus::Params &consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
bool BlockRequestAllowed(const CBlockIndex* pindex, const Consensus::Params& consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
bool AlreadyHaveBlock(const uint256& block_hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
void ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& chainparams, const CInv& inv, CConnman& connman);
|
||||
bool PrepareBlockFilterRequest(CNode& peer, const CChainParams& chain_params,
|
||||
BlockFilterType filter_type, uint32_t start_height,
|
||||
const uint256& stop_hash, uint32_t max_height_diff,
|
||||
const CBlockIndex*& stop_index,
|
||||
BlockFilterIndex*& filter_index);
|
||||
void ProcessGetCFilters(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
||||
CConnman& connman);
|
||||
void ProcessGetCFHeaders(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
||||
CConnman& connman);
|
||||
void ProcessGetCFCheckPt(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
||||
CConnman& connman);
|
||||
};
|
||||
} // namespace
|
||||
|
||||
@ -665,41 +683,6 @@ bool PeerManagerImpl::MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, co
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Check whether the last unknown block a peer advertised is not yet known. */
|
||||
static void ProcessBlockAvailability(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
|
||||
CNodeState *state = State(nodeid);
|
||||
assert(state != nullptr);
|
||||
|
||||
if (!state->hashLastUnknownBlock.IsNull()) {
|
||||
const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(state->hashLastUnknownBlock);
|
||||
if (pindex && pindex->nChainWork > 0) {
|
||||
if (state->pindexBestKnownBlock == nullptr || pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork) {
|
||||
state->pindexBestKnownBlock = pindex;
|
||||
}
|
||||
state->hashLastUnknownBlock.SetNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Update tracking information about which blocks a peer is assumed to have. */
|
||||
static void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
|
||||
CNodeState *state = State(nodeid);
|
||||
assert(state != nullptr);
|
||||
|
||||
ProcessBlockAvailability(nodeid);
|
||||
|
||||
const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(hash);
|
||||
if (pindex && pindex->nChainWork > 0) {
|
||||
// An actually better block was announced.
|
||||
if (state->pindexBestKnownBlock == nullptr || pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork) {
|
||||
state->pindexBestKnownBlock = pindex;
|
||||
}
|
||||
} else {
|
||||
// An unknown block was announced; just assume that the latest one is the best one.
|
||||
state->hashLastUnknownBlock = hash;
|
||||
}
|
||||
}
|
||||
|
||||
void PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
@ -749,9 +732,9 @@ bool PeerManagerImpl::TipMayBeStale()
|
||||
return m_last_tip_update < GetTime() - consensusParams.nPowTargetSpacing * 3 && mapBlocksInFlight.empty();
|
||||
}
|
||||
|
||||
static bool CanDirectFetch(const Consensus::Params &consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
bool PeerManagerImpl::CanDirectFetch(const Consensus::Params &consensusParams)
|
||||
{
|
||||
return ::ChainActive().Tip()->GetBlockTime() > GetAdjustedTime() - consensusParams.nPowTargetSpacing * 20;
|
||||
return m_chainman.ActiveChain().Tip()->GetBlockTime() > GetAdjustedTime() - consensusParams.nPowTargetSpacing * 20;
|
||||
}
|
||||
|
||||
static bool PeerHasHeader(CNodeState *state, const CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
@ -763,6 +746,41 @@ 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);
|
||||
|
||||
if (!state->hashLastUnknownBlock.IsNull()) {
|
||||
const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(state->hashLastUnknownBlock);
|
||||
if (pindex && pindex->nChainWork > 0) {
|
||||
if (state->pindexBestKnownBlock == nullptr || pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork) {
|
||||
state->pindexBestKnownBlock = pindex;
|
||||
}
|
||||
state->hashLastUnknownBlock.SetNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 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);
|
||||
|
||||
ProcessBlockAvailability(nodeid);
|
||||
|
||||
const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(hash);
|
||||
if (pindex && pindex->nChainWork > 0) {
|
||||
// An actually better block was announced.
|
||||
if (state->pindexBestKnownBlock == nullptr || pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork) {
|
||||
state->pindexBestKnownBlock = pindex;
|
||||
}
|
||||
} else {
|
||||
// An unknown block was announced; just assume that the latest one is the best one.
|
||||
state->hashLastUnknownBlock = hash;
|
||||
}
|
||||
}
|
||||
|
||||
void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<const CBlockIndex*>& vBlocks, NodeId& nodeStaller)
|
||||
{
|
||||
if (count == 0)
|
||||
@ -775,7 +793,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
|
||||
// Make sure pindexBestKnownBlock is up to date, we'll need it.
|
||||
ProcessBlockAvailability(nodeid);
|
||||
|
||||
if (state->pindexBestKnownBlock == nullptr || state->pindexBestKnownBlock->nChainWork < ::ChainActive().Tip()->nChainWork || state->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
|
||||
if (state->pindexBestKnownBlock == nullptr || state->pindexBestKnownBlock->nChainWork < m_chainman.ActiveChain().Tip()->nChainWork || state->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
|
||||
// This peer has nothing interesting.
|
||||
return;
|
||||
}
|
||||
@ -783,7 +801,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
|
||||
if (state->pindexLastCommonBlock == nullptr) {
|
||||
// Bootstrap quickly by guessing a parent of our best tip is the forking point.
|
||||
// Guessing wrong in either direction is not a problem.
|
||||
state->pindexLastCommonBlock = ::ChainActive()[std::min(state->pindexBestKnownBlock->nHeight, ::ChainActive().Height())];
|
||||
state->pindexLastCommonBlock = m_chainman.ActiveChain()[std::min(state->pindexBestKnownBlock->nHeight, m_chainman.ActiveChain().Height())];
|
||||
}
|
||||
|
||||
// If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor
|
||||
@ -826,7 +844,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
|
||||
// We wouldn't download this block or its descendants from this peer.
|
||||
return;
|
||||
}
|
||||
if (pindex->nStatus & BLOCK_HAVE_DATA || ::ChainActive().Contains(pindex)) {
|
||||
if (pindex->nStatus & BLOCK_HAVE_DATA || m_chainman.ActiveChain().Contains(pindex)) {
|
||||
if (pindex->HaveTxsDownloaded())
|
||||
state->pindexLastCommonBlock = pindex;
|
||||
} else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) {
|
||||
@ -1179,10 +1197,10 @@ bool PeerManagerImpl::MaybePunishNodeForTx(NodeId nodeid, const TxValidationStat
|
||||
// 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.
|
||||
static bool BlockRequestAllowed(const CBlockIndex* pindex, const Consensus::Params& consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex* pindex, const Consensus::Params& consensusParams)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
if (::ChainActive().Contains(pindex)) return true;
|
||||
if (m_chainman.ActiveChain().Contains(pindex)) return true;
|
||||
return pindex->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != nullptr) &&
|
||||
(pindexBestHeader->GetBlockTime() - pindex->GetBlockTime() < STALE_RELAY_AGE_LIMIT) &&
|
||||
(GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, *pindexBestHeader, consensusParams) < STALE_RELAY_AGE_LIMIT);
|
||||
@ -1206,6 +1224,7 @@ PeerManagerImpl::PeerManagerImpl(const CChainParams& chainparams, CConnman& conn
|
||||
m_stale_tip_check_time(0),
|
||||
m_ignore_incoming_txs(ignore_incoming_txs)
|
||||
{
|
||||
assert(std::addressof(g_chainman) == std::addressof(m_chainman));
|
||||
// Initialize global variables that cannot be constructed at startup.
|
||||
recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
|
||||
|
||||
@ -1331,7 +1350,7 @@ void PeerManagerImpl::NewPoWValidBlock(const CBlockIndex *pindex, const std::sha
|
||||
|
||||
/**
|
||||
* Update our best height and announce any block hashes which weren't previously
|
||||
* in ::ChainActive() to our peers.
|
||||
* in m_chainman.ActiveChain() to our peers.
|
||||
*/
|
||||
void PeerManagerImpl::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
|
||||
{
|
||||
@ -1393,7 +1412,7 @@ void PeerManagerImpl::BlockChecked(const CBlock& block, const BlockValidationSta
|
||||
// the tip yet so we have no way to check this directly here. Instead we
|
||||
// just check that there are currently no other blocks in flight.
|
||||
else if (state.IsValid() &&
|
||||
!::ChainstateActive().IsInitialBlockDownload() &&
|
||||
!m_chainman.ActiveChainstate().IsInitialBlockDownload() &&
|
||||
mapBlocksInFlight.count(hash) == mapBlocksInFlight.size()) {
|
||||
if (it != mapBlockSource.end()) {
|
||||
MaybeSetPeerAsAnnouncingHeaderAndIDs(it->second.first);
|
||||
@ -1412,12 +1431,12 @@ void PeerManagerImpl::BlockChecked(const CBlock& block, const BlockValidationSta
|
||||
bool PeerManagerImpl::AlreadyHaveTx(const GenTxid& gtxid)
|
||||
{
|
||||
assert(recentRejects);
|
||||
if (::ChainActive().Tip()->GetBlockHash() != hashRecentRejectsChainTip) {
|
||||
if (m_chainman.ActiveChain().Tip()->GetBlockHash() != hashRecentRejectsChainTip) {
|
||||
// If the chain tip has changed previously rejected transactions
|
||||
// might be now valid, e.g. due to a nLockTime'd tx becoming valid,
|
||||
// or a double-spend. Reset the rejects filter and give those
|
||||
// txs a second chance.
|
||||
hashRecentRejectsChainTip = ::ChainActive().Tip()->GetBlockHash();
|
||||
hashRecentRejectsChainTip = m_chainman.ActiveChain().Tip()->GetBlockHash();
|
||||
recentRejects->reset();
|
||||
}
|
||||
|
||||
@ -1433,9 +1452,9 @@ bool PeerManagerImpl::AlreadyHaveTx(const GenTxid& gtxid)
|
||||
return recentRejects->contains(hash) || m_mempool.exists(gtxid);
|
||||
}
|
||||
|
||||
bool static AlreadyHaveBlock(const uint256& block_hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
bool PeerManagerImpl::AlreadyHaveBlock(const uint256& block_hash)
|
||||
{
|
||||
return g_chainman.m_blockman.LookupBlockIndex(block_hash) != nullptr;
|
||||
return m_chainman.m_blockman.LookupBlockIndex(block_hash) != nullptr;
|
||||
}
|
||||
|
||||
void PeerManagerImpl::SendPings()
|
||||
@ -1514,7 +1533,7 @@ static void RelayAddress(const CNode& originator,
|
||||
connman.ForEachNodeThen(std::move(sortfunc), std::move(pushfunc));
|
||||
}
|
||||
|
||||
void static ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& chainparams, const CInv& inv, CConnman& connman)
|
||||
void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& chainparams, const CInv& inv, CConnman& connman)
|
||||
{
|
||||
bool send = false;
|
||||
std::shared_ptr<const CBlock> a_recent_block;
|
||||
@ -1531,7 +1550,7 @@ void static ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& ch
|
||||
bool need_activate_chain = false;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(inv.hash);
|
||||
const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(inv.hash);
|
||||
if (pindex) {
|
||||
if (pindex->HaveTxsDownloaded() && !pindex->IsValid(BLOCK_VALID_SCRIPTS) &&
|
||||
pindex->IsValid(BLOCK_VALID_TREE)) {
|
||||
@ -1546,13 +1565,13 @@ void static ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& ch
|
||||
} // release cs_main before calling ActivateBestChain
|
||||
if (need_activate_chain) {
|
||||
BlockValidationState state;
|
||||
if (!::ChainstateActive().ActivateBestChain(state, chainparams, a_recent_block)) {
|
||||
if (!m_chainman.ActiveChainstate().ActivateBestChain(state, chainparams, a_recent_block)) {
|
||||
LogPrint(BCLog::NET, "failed to activate chain (%s)\n", state.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
LOCK(cs_main);
|
||||
const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(inv.hash);
|
||||
const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(inv.hash);
|
||||
if (pindex) {
|
||||
send = BlockRequestAllowed(pindex, consensusParams);
|
||||
if (!send) {
|
||||
@ -1574,7 +1593,7 @@ void static ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& ch
|
||||
}
|
||||
// Avoid leaking prune-height by never sending blocks below the NODE_NETWORK_LIMITED threshold
|
||||
if (send && !pfrom.HasPermission(PF_NOBAN) && (
|
||||
(((pfrom.GetLocalServices() & NODE_NETWORK_LIMITED) == NODE_NETWORK_LIMITED) && ((pfrom.GetLocalServices() & NODE_NETWORK) != NODE_NETWORK) && (::ChainActive().Tip()->nHeight - pindex->nHeight > (int)NODE_NETWORK_LIMITED_MIN_BLOCKS + 2 /* add two blocks buffer extension for possible races */) )
|
||||
(((pfrom.GetLocalServices() & NODE_NETWORK_LIMITED) == NODE_NETWORK_LIMITED) && ((pfrom.GetLocalServices() & NODE_NETWORK) != NODE_NETWORK) && (m_chainman.ActiveChain().Tip()->nHeight - pindex->nHeight > (int)NODE_NETWORK_LIMITED_MIN_BLOCKS + 2 /* add two blocks buffer extension for possible races */) )
|
||||
)) {
|
||||
LogPrint(BCLog::NET, "Ignore block request below NODE_NETWORK_LIMITED threshold from peer=%d\n", pfrom.GetId());
|
||||
|
||||
@ -1641,7 +1660,7 @@ void static ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& ch
|
||||
// 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(consensusParams) && pindex->nHeight >= ::ChainActive().Height() - MAX_CMPCTBLOCK_DEPTH) {
|
||||
if (CanDirectFetch(consensusParams) && pindex->nHeight >= m_chainman.ActiveChain().Height() - MAX_CMPCTBLOCK_DEPTH) {
|
||||
if ((fPeerWantsWitness || !fWitnessesPresentInARecentCompactBlock) && a_recent_compact_block && a_recent_compact_block->header.GetHash() == pindex->GetBlockHash()) {
|
||||
connman.PushMessage(&pfrom, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, *a_recent_compact_block));
|
||||
} else {
|
||||
@ -1662,7 +1681,7 @@ void static ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& ch
|
||||
// and we want it right after the last block so they don't
|
||||
// wait for other stuff first.
|
||||
std::vector<CInv> vInv;
|
||||
vInv.push_back(CInv(MSG_BLOCK, ::ChainActive().Tip()->GetBlockHash()));
|
||||
vInv.push_back(CInv(MSG_BLOCK, m_chainman.ActiveChain().Tip()->GetBlockHash()));
|
||||
connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::INV, vInv));
|
||||
peer.m_continuation_block.SetNull();
|
||||
}
|
||||
@ -1841,9 +1860,9 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
|
||||
// don't connect before giving DoS points
|
||||
// - Once a headers message is received that is valid and does connect,
|
||||
// nUnconnectingHeaders gets reset back to 0.
|
||||
if (!g_chainman.m_blockman.LookupBlockIndex(headers[0].hashPrevBlock) && nCount < MAX_BLOCKS_TO_ANNOUNCE) {
|
||||
if (!m_chainman.m_blockman.LookupBlockIndex(headers[0].hashPrevBlock) && nCount < MAX_BLOCKS_TO_ANNOUNCE) {
|
||||
nodestate->nUnconnectingHeaders++;
|
||||
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, ::ChainActive().GetLocator(pindexBestHeader), uint256()));
|
||||
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, m_chainman.ActiveChain().GetLocator(pindexBestHeader), uint256()));
|
||||
LogPrint(BCLog::NET, "received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d, nUnconnectingHeaders=%d)\n",
|
||||
headers[0].GetHash().ToString(),
|
||||
headers[0].hashPrevBlock.ToString(),
|
||||
@ -1871,7 +1890,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
|
||||
|
||||
// If we don't have the last header, then they'll have given us
|
||||
// something new (if these headers are valid).
|
||||
if (!g_chainman.m_blockman.LookupBlockIndex(hashLastBlock)) {
|
||||
if (!m_chainman.m_blockman.LookupBlockIndex(hashLastBlock)) {
|
||||
received_new_header = true;
|
||||
}
|
||||
}
|
||||
@ -1899,27 +1918,27 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
|
||||
// because it is set in UpdateBlockAvailability. Some nullptr checks
|
||||
// are still present, however, as belt-and-suspenders.
|
||||
|
||||
if (received_new_header && pindexLast->nChainWork > ::ChainActive().Tip()->nChainWork) {
|
||||
if (received_new_header && pindexLast->nChainWork > m_chainman.ActiveChain().Tip()->nChainWork) {
|
||||
nodestate->m_last_block_announcement = GetTime();
|
||||
}
|
||||
|
||||
if (nCount == MAX_HEADERS_RESULTS) {
|
||||
// Headers message had its maximum size; the peer may have more headers.
|
||||
// TODO: optimize: if pindexLast is an ancestor of ::ChainActive().Tip or pindexBestHeader, continue
|
||||
// TODO: optimize: if pindexLast is an ancestor of m_chainman.ActiveChain().Tip or pindexBestHeader, continue
|
||||
// from there instead.
|
||||
LogPrint(BCLog::NET, "more getheaders (%d) to end to peer=%d (startheight:%d)\n",
|
||||
pindexLast->nHeight, pfrom.GetId(), peer.m_starting_height);
|
||||
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, ::ChainActive().GetLocator(pindexLast), uint256()));
|
||||
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, m_chainman.ActiveChain().GetLocator(pindexLast), uint256()));
|
||||
}
|
||||
|
||||
bool fCanDirectFetch = CanDirectFetch(m_chainparams.GetConsensus());
|
||||
// If this set of headers is valid and ends in a block with at least as
|
||||
// much work as our tip, download as much as possible.
|
||||
if (fCanDirectFetch && pindexLast->IsValid(BLOCK_VALID_TREE) && ::ChainActive().Tip()->nChainWork <= pindexLast->nChainWork) {
|
||||
if (fCanDirectFetch && pindexLast->IsValid(BLOCK_VALID_TREE) && m_chainman.ActiveChain().Tip()->nChainWork <= pindexLast->nChainWork) {
|
||||
std::vector<const CBlockIndex*> vToFetch;
|
||||
const CBlockIndex *pindexWalk = pindexLast;
|
||||
// Calculate all the blocks we'd need to switch to pindexLast, up to a limit.
|
||||
while (pindexWalk && !::ChainActive().Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
|
||||
while (pindexWalk && !m_chainman.ActiveChain().Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
|
||||
if (!(pindexWalk->nStatus & BLOCK_HAVE_DATA) &&
|
||||
!mapBlocksInFlight.count(pindexWalk->GetBlockHash()) &&
|
||||
(!IsWitnessEnabled(pindexWalk->pprev, m_chainparams.GetConsensus()) || State(pfrom.GetId())->fHaveWitness)) {
|
||||
@ -1932,7 +1951,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
|
||||
// very large reorg at a time we think we're close to caught up to
|
||||
// the main chain -- this shouldn't really happen. Bail out on the
|
||||
// direct fetch and rely on parallel download instead.
|
||||
if (!::ChainActive().Contains(pindexWalk)) {
|
||||
if (!m_chainman.ActiveChain().Contains(pindexWalk)) {
|
||||
LogPrint(BCLog::NET, "Large reorg, won't direct fetch to %s (%d)\n",
|
||||
pindexLast->GetBlockHash().ToString(),
|
||||
pindexLast->nHeight);
|
||||
@ -1965,7 +1984,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
|
||||
}
|
||||
// If we're in IBD, we want outbound peers that will serve us a useful
|
||||
// chain. Disconnect peers that are on chains with insufficient work.
|
||||
if (::ChainstateActive().IsInitialBlockDownload() && nCount != MAX_HEADERS_RESULTS) {
|
||||
if (m_chainman.ActiveChainstate().IsInitialBlockDownload() && nCount != MAX_HEADERS_RESULTS) {
|
||||
// When nCount < MAX_HEADERS_RESULTS, we know we have no more
|
||||
// headers to fetch from this peer.
|
||||
if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
|
||||
@ -1973,7 +1992,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
|
||||
// us sync -- disconnect if it is an outbound disconnection
|
||||
// candidate.
|
||||
// Note: We compare their tip to nMinimumChainWork (rather than
|
||||
// ::ChainActive().Tip()) because we won't start block download
|
||||
// m_chainman.ActiveChain().Tip()) because we won't start block download
|
||||
// until we have a headers chain that has at least
|
||||
// nMinimumChainWork, even if a peer has a chain past our tip,
|
||||
// as an anti-DoS measure.
|
||||
@ -1990,7 +2009,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
|
||||
// thus always subject to eviction under the bad/lagging chain logic.
|
||||
// See ChainSyncTimeoutState.
|
||||
if (!pfrom.fDisconnect && pfrom.IsFullOutboundConn() && nodestate->pindexBestKnownBlock != nullptr) {
|
||||
if (m_outbound_peers_with_protect_from_disconnect < MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT && nodestate->pindexBestKnownBlock->nChainWork >= ::ChainActive().Tip()->nChainWork && !nodestate->m_chain_sync.m_protect) {
|
||||
if (m_outbound_peers_with_protect_from_disconnect < MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT && nodestate->pindexBestKnownBlock->nChainWork >= m_chainman.ActiveChain().Tip()->nChainWork && !nodestate->m_chain_sync.m_protect) {
|
||||
LogPrint(BCLog::NET, "Protecting outbound peer=%d from eviction\n", pfrom.GetId());
|
||||
nodestate->m_chain_sync.m_protect = true;
|
||||
++m_outbound_peers_with_protect_from_disconnect;
|
||||
@ -2021,7 +2040,7 @@ void PeerManagerImpl::ProcessOrphanTx(std::set<uint256>& orphan_work_set)
|
||||
const auto [porphanTx, from_peer] = m_orphanage.GetTx(orphanHash);
|
||||
if (porphanTx == nullptr) continue;
|
||||
|
||||
const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), m_mempool, porphanTx, false /* bypass_limits */);
|
||||
const MempoolAcceptResult result = AcceptToMemoryPool(m_chainman.ActiveChainstate(), m_mempool, porphanTx, false /* bypass_limits */);
|
||||
const TxValidationState& state = result.m_state;
|
||||
|
||||
if (result.m_result_type == MempoolAcceptResult::ResultType::VALID) {
|
||||
@ -2097,7 +2116,7 @@ void PeerManagerImpl::ProcessOrphanTx(std::set<uint256>& orphan_work_set)
|
||||
* @param[out] filter_index The filter index, if the request can be serviced.
|
||||
* @return True if the request can be serviced.
|
||||
*/
|
||||
static bool PrepareBlockFilterRequest(CNode& peer, const CChainParams& chain_params,
|
||||
bool PeerManagerImpl::PrepareBlockFilterRequest(CNode& peer, const CChainParams& chain_params,
|
||||
BlockFilterType filter_type, uint32_t start_height,
|
||||
const uint256& stop_hash, uint32_t max_height_diff,
|
||||
const CBlockIndex*& stop_index,
|
||||
@ -2115,7 +2134,7 @@ static bool PrepareBlockFilterRequest(CNode& peer, const CChainParams& chain_par
|
||||
|
||||
{
|
||||
LOCK(cs_main);
|
||||
stop_index = g_chainman.m_blockman.LookupBlockIndex(stop_hash);
|
||||
stop_index = m_chainman.m_blockman.LookupBlockIndex(stop_hash);
|
||||
|
||||
// Check that the stop block exists and the peer would be allowed to fetch it.
|
||||
if (!stop_index || !BlockRequestAllowed(stop_index, chain_params.GetConsensus())) {
|
||||
@ -2160,7 +2179,7 @@ static bool PrepareBlockFilterRequest(CNode& peer, const CChainParams& chain_par
|
||||
* @param[in] chain_params Chain parameters
|
||||
* @param[in] connman Pointer to the connection manager
|
||||
*/
|
||||
static void ProcessGetCFilters(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
||||
void PeerManagerImpl::ProcessGetCFilters(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
||||
CConnman& connman)
|
||||
{
|
||||
uint8_t filter_type_ser;
|
||||
@ -2202,7 +2221,7 @@ static void ProcessGetCFilters(CNode& peer, CDataStream& vRecv, const CChainPara
|
||||
* @param[in] chain_params Chain parameters
|
||||
* @param[in] connman Pointer to the connection manager
|
||||
*/
|
||||
static void ProcessGetCFHeaders(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
||||
void PeerManagerImpl::ProcessGetCFHeaders(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
||||
CConnman& connman)
|
||||
{
|
||||
uint8_t filter_type_ser;
|
||||
@ -2257,7 +2276,7 @@ static void ProcessGetCFHeaders(CNode& peer, CDataStream& vRecv, const CChainPar
|
||||
* @param[in] chain_params Chain parameters
|
||||
* @param[in] connman Pointer to the connection manager
|
||||
*/
|
||||
static void ProcessGetCFCheckPt(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
||||
void PeerManagerImpl::ProcessGetCFCheckPt(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
||||
CConnman& connman)
|
||||
{
|
||||
uint8_t filter_type_ser;
|
||||
@ -2440,7 +2459,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||
//
|
||||
// We skip this for block-relay-only peers to avoid potentially leaking
|
||||
// information about our block-relay-only connections via address relay.
|
||||
if (fListen && !::ChainstateActive().IsInitialBlockDownload())
|
||||
if (fListen && !m_chainman.ActiveChainstate().IsInitialBlockDownload())
|
||||
{
|
||||
CAddress addr = GetLocalAddress(&pfrom.addr, pfrom.GetLocalServices());
|
||||
FastRandomContext insecure_rand;
|
||||
@ -2757,7 +2776,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||
}
|
||||
|
||||
if (best_block != nullptr) {
|
||||
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, ::ChainActive().GetLocator(pindexBestHeader), *best_block));
|
||||
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, m_chainman.ActiveChain().GetLocator(pindexBestHeader), *best_block));
|
||||
LogPrint(BCLog::NET, "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, best_block->ToString(), pfrom.GetId());
|
||||
}
|
||||
|
||||
@ -2813,7 +2832,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||
a_recent_block = most_recent_block;
|
||||
}
|
||||
BlockValidationState state;
|
||||
if (!::ChainstateActive().ActivateBestChain(state, m_chainparams, a_recent_block)) {
|
||||
if (!m_chainman.ActiveChainstate().ActivateBestChain(state, m_chainparams, a_recent_block)) {
|
||||
LogPrint(BCLog::NET, "failed to activate chain (%s)\n", state.ToString());
|
||||
}
|
||||
}
|
||||
@ -2821,14 +2840,14 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||
LOCK(cs_main);
|
||||
|
||||
// Find the last block the caller has in the main chain
|
||||
const CBlockIndex* pindex = g_chainman.m_blockman.FindForkInGlobalIndex(::ChainActive(), locator);
|
||||
const CBlockIndex* pindex = m_chainman.m_blockman.FindForkInGlobalIndex(m_chainman.ActiveChain(), locator);
|
||||
|
||||
// Send the rest of the chain
|
||||
if (pindex)
|
||||
pindex = ::ChainActive().Next(pindex);
|
||||
pindex = m_chainman.ActiveChain().Next(pindex);
|
||||
int nLimit = 500;
|
||||
LogPrint(BCLog::NET, "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit, pfrom.GetId());
|
||||
for (; pindex; pindex = ::ChainActive().Next(pindex))
|
||||
for (; pindex; pindex = m_chainman.ActiveChain().Next(pindex))
|
||||
{
|
||||
if (pindex->GetBlockHash() == hashStop)
|
||||
{
|
||||
@ -2838,7 +2857,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||
// If pruning, don't inv blocks unless we have on disk and are likely to still have
|
||||
// for some reasonable time window (1 hour) that block relay might require.
|
||||
const int nPrunedBlocksLikelyToHave = MIN_BLOCKS_TO_KEEP - 3600 / m_chainparams.GetConsensus().nPowTargetSpacing;
|
||||
if (fPruneMode && (!(pindex->nStatus & BLOCK_HAVE_DATA) || pindex->nHeight <= ::ChainActive().Tip()->nHeight - nPrunedBlocksLikelyToHave))
|
||||
if (fPruneMode && (!(pindex->nStatus & BLOCK_HAVE_DATA) || pindex->nHeight <= m_chainman.ActiveChain().Tip()->nHeight - nPrunedBlocksLikelyToHave))
|
||||
{
|
||||
LogPrint(BCLog::NET, " getblocks stopping, pruned or too old block at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
|
||||
break;
|
||||
@ -2874,13 +2893,13 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||
{
|
||||
LOCK(cs_main);
|
||||
|
||||
const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(req.blockhash);
|
||||
const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(req.blockhash);
|
||||
if (!pindex || !(pindex->nStatus & BLOCK_HAVE_DATA)) {
|
||||
LogPrint(BCLog::NET, "Peer %d sent us a getblocktxn for a block we don't have\n", pfrom.GetId());
|
||||
return;
|
||||
}
|
||||
|
||||
if (pindex->nHeight >= ::ChainActive().Height() - MAX_BLOCKTXN_DEPTH) {
|
||||
if (pindex->nHeight >= m_chainman.ActiveChain().Height() - MAX_BLOCKTXN_DEPTH) {
|
||||
CBlock block;
|
||||
bool ret = ReadBlockFromDisk(block, pindex, m_chainparams.GetConsensus());
|
||||
assert(ret);
|
||||
@ -2918,7 +2937,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||
}
|
||||
|
||||
LOCK(cs_main);
|
||||
if (::ChainstateActive().IsInitialBlockDownload() && !pfrom.HasPermission(PF_DOWNLOAD)) {
|
||||
if (m_chainman.ActiveChainstate().IsInitialBlockDownload() && !pfrom.HasPermission(PF_DOWNLOAD)) {
|
||||
LogPrint(BCLog::NET, "Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom.GetId());
|
||||
return;
|
||||
}
|
||||
@ -2928,7 +2947,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||
if (locator.IsNull())
|
||||
{
|
||||
// If locator is null, return the hashStop block
|
||||
pindex = g_chainman.m_blockman.LookupBlockIndex(hashStop);
|
||||
pindex = m_chainman.m_blockman.LookupBlockIndex(hashStop);
|
||||
if (!pindex) {
|
||||
return;
|
||||
}
|
||||
@ -2941,23 +2960,23 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||
else
|
||||
{
|
||||
// Find the last block the caller has in the main chain
|
||||
pindex = g_chainman.m_blockman.FindForkInGlobalIndex(::ChainActive(), locator);
|
||||
pindex = m_chainman.m_blockman.FindForkInGlobalIndex(m_chainman.ActiveChain(), locator);
|
||||
if (pindex)
|
||||
pindex = ::ChainActive().Next(pindex);
|
||||
pindex = m_chainman.ActiveChain().Next(pindex);
|
||||
}
|
||||
|
||||
// we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end
|
||||
std::vector<CBlock> vHeaders;
|
||||
int nLimit = MAX_HEADERS_RESULTS;
|
||||
LogPrint(BCLog::NET, "getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), pfrom.GetId());
|
||||
for (; pindex; pindex = ::ChainActive().Next(pindex))
|
||||
for (; pindex; pindex = m_chainman.ActiveChain().Next(pindex))
|
||||
{
|
||||
vHeaders.push_back(pindex->GetBlockHeader());
|
||||
if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
|
||||
break;
|
||||
}
|
||||
// pindex can be nullptr either if we sent ::ChainActive().Tip() OR
|
||||
// if our peer has ::ChainActive().Tip() (and thus we are sending an empty
|
||||
// pindex can be nullptr either if we sent m_chainman.ActiveChain().Tip() OR
|
||||
// if our peer has m_chainman.ActiveChain().Tip() (and thus we are sending an empty
|
||||
// headers message). In both cases it's safe to update
|
||||
// pindexBestHeaderSent to be our tip.
|
||||
//
|
||||
@ -2968,7 +2987,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||
// without the new block. By resetting the BestHeaderSent, we ensure we
|
||||
// will re-announce the new block via headers (or compact blocks again)
|
||||
// in the SendMessages logic.
|
||||
nodestate->pindexBestHeaderSent = pindex ? pindex : ::ChainActive().Tip();
|
||||
nodestate->pindexBestHeaderSent = pindex ? pindex : m_chainman.ActiveChain().Tip();
|
||||
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::HEADERS, vHeaders));
|
||||
return;
|
||||
}
|
||||
@ -3036,7 +3055,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||
return;
|
||||
}
|
||||
|
||||
const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), m_mempool, ptx, false /* bypass_limits */);
|
||||
const MempoolAcceptResult result = AcceptToMemoryPool(m_chainman.ActiveChainstate(), m_mempool, ptx, false /* bypass_limits */);
|
||||
const TxValidationState& state = result.m_state;
|
||||
|
||||
if (result.m_result_type == MempoolAcceptResult::ResultType::VALID) {
|
||||
@ -3201,14 +3220,14 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||
{
|
||||
LOCK(cs_main);
|
||||
|
||||
if (!g_chainman.m_blockman.LookupBlockIndex(cmpctblock.header.hashPrevBlock)) {
|
||||
if (!m_chainman.m_blockman.LookupBlockIndex(cmpctblock.header.hashPrevBlock)) {
|
||||
// Doesn't connect (or is genesis), instead of DoSing in AcceptBlockHeader, request deeper headers
|
||||
if (!::ChainstateActive().IsInitialBlockDownload())
|
||||
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, ::ChainActive().GetLocator(pindexBestHeader), uint256()));
|
||||
if (!m_chainman.ActiveChainstate().IsInitialBlockDownload())
|
||||
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, m_chainman.ActiveChain().GetLocator(pindexBestHeader), uint256()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_chainman.m_blockman.LookupBlockIndex(cmpctblock.header.GetHash())) {
|
||||
if (!m_chainman.m_blockman.LookupBlockIndex(cmpctblock.header.GetHash())) {
|
||||
received_new_header = true;
|
||||
}
|
||||
}
|
||||
@ -3248,7 +3267,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||
|
||||
// If this was a new header with more work than our tip, update the
|
||||
// peer's last block announcement time
|
||||
if (received_new_header && pindex->nChainWork > ::ChainActive().Tip()->nChainWork) {
|
||||
if (received_new_header && pindex->nChainWork > m_chainman.ActiveChain().Tip()->nChainWork) {
|
||||
nodestate->m_last_block_announcement = GetTime();
|
||||
}
|
||||
|
||||
@ -3258,7 +3277,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||
if (pindex->nStatus & BLOCK_HAVE_DATA) // Nothing to do here
|
||||
return;
|
||||
|
||||
if (pindex->nChainWork <= ::ChainActive().Tip()->nChainWork || // We know something better
|
||||
if (pindex->nChainWork <= m_chainman.ActiveChain().Tip()->nChainWork || // We know something better
|
||||
pindex->nTx != 0) { // We had this block at some point, but pruned it
|
||||
if (fAlreadyInFlight) {
|
||||
// We requested this block for some reason, but our mempool will probably be useless
|
||||
@ -3282,7 +3301,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||
|
||||
// We want to be a bit conservative just to be extra careful about DoS
|
||||
// possibilities in compact block processing...
|
||||
if (pindex->nHeight <= ::ChainActive().Height() + 2) {
|
||||
if (pindex->nHeight <= m_chainman.ActiveChain().Height() + 2) {
|
||||
if ((!fAlreadyInFlight && nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) ||
|
||||
(fAlreadyInFlight && blockInFlightIt->second.first == pfrom.GetId())) {
|
||||
std::list<QueuedBlock>::iterator* queuedBlockIt = nullptr;
|
||||
@ -3930,7 +3949,7 @@ void PeerManagerImpl::ConsiderEviction(CNode& pto, int64_t time_in_seconds)
|
||||
// their chain has more work than ours, we should sync to it,
|
||||
// unless it's invalid, in which case we should find that out and
|
||||
// disconnect from them elsewhere).
|
||||
if (state.pindexBestKnownBlock != nullptr && state.pindexBestKnownBlock->nChainWork >= ::ChainActive().Tip()->nChainWork) {
|
||||
if (state.pindexBestKnownBlock != nullptr && state.pindexBestKnownBlock->nChainWork >= m_chainman.ActiveChain().Tip()->nChainWork) {
|
||||
if (state.m_chain_sync.m_timeout != 0) {
|
||||
state.m_chain_sync.m_timeout = 0;
|
||||
state.m_chain_sync.m_work_header = nullptr;
|
||||
@ -3942,7 +3961,7 @@ void PeerManagerImpl::ConsiderEviction(CNode& pto, int64_t time_in_seconds)
|
||||
// where we checked against our tip.
|
||||
// Either way, set a new timeout based on current tip.
|
||||
state.m_chain_sync.m_timeout = time_in_seconds + CHAIN_SYNC_TIMEOUT;
|
||||
state.m_chain_sync.m_work_header = ::ChainActive().Tip();
|
||||
state.m_chain_sync.m_work_header = m_chainman.ActiveChain().Tip();
|
||||
state.m_chain_sync.m_sent_getheaders = false;
|
||||
} else if (state.m_chain_sync.m_timeout > 0 && time_in_seconds > state.m_chain_sync.m_timeout) {
|
||||
// No evidence yet that our peer has synced to a chain with work equal to that
|
||||
@ -3955,7 +3974,7 @@ void PeerManagerImpl::ConsiderEviction(CNode& pto, int64_t time_in_seconds)
|
||||
} else {
|
||||
assert(state.m_chain_sync.m_work_header);
|
||||
LogPrint(BCLog::NET, "sending getheaders to outbound peer=%d to verify chain work (current best known block:%s, benchmark blockhash: %s)\n", pto.GetId(), state.pindexBestKnownBlock != nullptr ? state.pindexBestKnownBlock->GetBlockHash().ToString() : "<none>", state.m_chain_sync.m_work_header->GetBlockHash().ToString());
|
||||
m_connman.PushMessage(&pto, msgMaker.Make(NetMsgType::GETHEADERS, ::ChainActive().GetLocator(state.m_chain_sync.m_work_header->pprev), uint256()));
|
||||
m_connman.PushMessage(&pto, msgMaker.Make(NetMsgType::GETHEADERS, m_chainman.ActiveChain().GetLocator(state.m_chain_sync.m_work_header->pprev), uint256()));
|
||||
state.m_chain_sync.m_sent_getheaders = true;
|
||||
constexpr int64_t HEADERS_RESPONSE_TIME = 120; // 2 minutes
|
||||
// Bump the timeout to allow a response, which could clear the timeout
|
||||
@ -4192,7 +4211,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
||||
auto current_time = GetTime<std::chrono::microseconds>();
|
||||
|
||||
if (fListen && pto->RelayAddrsWithConn() &&
|
||||
!::ChainstateActive().IsInitialBlockDownload() &&
|
||||
!m_chainman.ActiveChainstate().IsInitialBlockDownload() &&
|
||||
pto->m_next_local_addr_send < current_time) {
|
||||
// If we've sent before, clear the bloom filter for the peer, so that our
|
||||
// self-announcement will actually go out.
|
||||
@ -4253,7 +4272,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
||||
|
||||
// Start block sync
|
||||
if (pindexBestHeader == nullptr)
|
||||
pindexBestHeader = ::ChainActive().Tip();
|
||||
pindexBestHeader = m_chainman.ActiveChain().Tip();
|
||||
bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->IsAddrFetchConn()); // Download if this is a nice peer, or we have no nice peers and this one might do.
|
||||
if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
|
||||
// Only actively request headers from a single peer, unless we're close to today.
|
||||
@ -4278,7 +4297,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
||||
if (pindexStart->pprev)
|
||||
pindexStart = pindexStart->pprev;
|
||||
LogPrint(BCLog::NET, "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->GetId(), peer->m_starting_height);
|
||||
m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::GETHEADERS, ::ChainActive().GetLocator(pindexStart), uint256()));
|
||||
m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::GETHEADERS, m_chainman.ActiveChain().GetLocator(pindexStart), uint256()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -4305,11 +4324,11 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
||||
bool fFoundStartingHeader = false;
|
||||
// Try to find first header that our peer doesn't have, and
|
||||
// then send all headers past that one. If we come across any
|
||||
// headers that aren't on ::ChainActive(), give up.
|
||||
// headers that aren't on m_chainman.ActiveChain(), give up.
|
||||
for (const uint256& hash : peer->m_blocks_for_headers_relay) {
|
||||
const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(hash);
|
||||
const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(hash);
|
||||
assert(pindex);
|
||||
if (::ChainActive()[pindex->nHeight] != pindex) {
|
||||
if (m_chainman.ActiveChain()[pindex->nHeight] != pindex) {
|
||||
// Bail out if we reorged away from this block
|
||||
fRevertToInv = true;
|
||||
break;
|
||||
@ -4399,15 +4418,15 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
||||
// in the past.
|
||||
if (!peer->m_blocks_for_headers_relay.empty()) {
|
||||
const uint256& hashToAnnounce = peer->m_blocks_for_headers_relay.back();
|
||||
const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(hashToAnnounce);
|
||||
const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(hashToAnnounce);
|
||||
assert(pindex);
|
||||
|
||||
// Warn if we're announcing a block that is not on the main chain.
|
||||
// This should be very rare and could be optimized out.
|
||||
// Just log for now.
|
||||
if (::ChainActive()[pindex->nHeight] != pindex) {
|
||||
if (m_chainman.ActiveChain()[pindex->nHeight] != pindex) {
|
||||
LogPrint(BCLog::NET, "Announcing block %s not on main chain (tip=%s)\n",
|
||||
hashToAnnounce.ToString(), ::ChainActive().Tip()->GetBlockHash().ToString());
|
||||
hashToAnnounce.ToString(), m_chainman.ActiveChain().Tip()->GetBlockHash().ToString());
|
||||
}
|
||||
|
||||
// If the peer's chain has this block, don't inv it back.
|
||||
@ -4637,7 +4656,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
||||
// Message: getdata (blocks)
|
||||
//
|
||||
std::vector<CInv> vGetData;
|
||||
if (!pto->fClient && ((fFetch && !pto->m_limited_node) || !::ChainstateActive().IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
|
||||
if (!pto->fClient && ((fFetch && !pto->m_limited_node) || !m_chainman.ActiveChainstate().IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
|
||||
std::vector<const CBlockIndex*> vToDownload;
|
||||
NodeId staller = -1;
|
||||
FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
|
||||
@ -4726,4 +4745,3 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
||||
} // release cs_main
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,8 @@ void FindCoins(const NodeContext& node, std::map<COutPoint, Coin>& coins)
|
||||
{
|
||||
assert(node.mempool);
|
||||
LOCK2(cs_main, node.mempool->cs);
|
||||
CCoinsViewCache& chain_view = ::ChainstateActive().CoinsTip();
|
||||
assert(std::addressof(::ChainstateActive()) == std::addressof(node.chainman->ActiveChainstate()));
|
||||
CCoinsViewCache& chain_view = node.chainman->ActiveChainstate().CoinsTip();
|
||||
CCoinsViewMemPool mempool_view(&chain_view, *node.mempool);
|
||||
for (auto& coin : coins) {
|
||||
if (!mempool_view.GetCoin(coin.first, coin.second)) {
|
||||
|
@ -83,7 +83,7 @@ static void ApplyStats(CCoinsStats& stats, T& hash_obj, const uint256& hash, con
|
||||
|
||||
//! Calculate statistics about the unspent transaction output set
|
||||
template <typename T>
|
||||
static bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, const std::function<void()>& interruption_point)
|
||||
static bool GetUTXOStats(CCoinsView* view, BlockManager& blockman, CCoinsStats& stats, T hash_obj, const std::function<void()>& interruption_point)
|
||||
{
|
||||
stats = CCoinsStats();
|
||||
std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
|
||||
@ -92,7 +92,8 @@ static bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, const
|
||||
stats.hashBlock = pcursor->GetBestBlock();
|
||||
{
|
||||
LOCK(cs_main);
|
||||
stats.nHeight = g_chainman.m_blockman.LookupBlockIndex(stats.hashBlock)->nHeight;
|
||||
assert(std::addressof(g_chainman.m_blockman) == std::addressof(blockman));
|
||||
stats.nHeight = blockman.LookupBlockIndex(stats.hashBlock)->nHeight;
|
||||
}
|
||||
|
||||
PrepareHash(hash_obj, stats);
|
||||
@ -126,19 +127,19 @@ static bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, CoinStatsHashType hash_type, const std::function<void()>& interruption_point)
|
||||
bool GetUTXOStats(CCoinsView* view, BlockManager& blockman, CCoinsStats& stats, CoinStatsHashType hash_type, const std::function<void()>& interruption_point)
|
||||
{
|
||||
switch (hash_type) {
|
||||
case(CoinStatsHashType::HASH_SERIALIZED): {
|
||||
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
|
||||
return GetUTXOStats(view, stats, ss, interruption_point);
|
||||
return GetUTXOStats(view, blockman, stats, ss, interruption_point);
|
||||
}
|
||||
case(CoinStatsHashType::MUHASH): {
|
||||
MuHash3072 muhash;
|
||||
return GetUTXOStats(view, stats, muhash, interruption_point);
|
||||
return GetUTXOStats(view, blockman, stats, muhash, interruption_point);
|
||||
}
|
||||
case(CoinStatsHashType::NONE): {
|
||||
return GetUTXOStats(view, stats, nullptr, interruption_point);
|
||||
return GetUTXOStats(view, blockman, stats, nullptr, interruption_point);
|
||||
}
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
assert(false);
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <amount.h>
|
||||
#include <uint256.h>
|
||||
#include <validation.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
@ -36,6 +37,6 @@ struct CCoinsStats
|
||||
};
|
||||
|
||||
//! Calculate statistics about the unspent transaction output set
|
||||
bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, const CoinStatsHashType hash_type, const std::function<void()>& interruption_point = {});
|
||||
bool GetUTXOStats(CCoinsView* view, BlockManager& blockman, CCoinsStats& stats, const CoinStatsHashType hash_type, const std::function<void()>& interruption_point = {});
|
||||
|
||||
#endif // BITCOIN_NODE_COINSTATS_H
|
||||
|
@ -182,18 +182,21 @@ public:
|
||||
int getNumBlocks() override
|
||||
{
|
||||
LOCK(::cs_main);
|
||||
return ::ChainActive().Height();
|
||||
assert(std::addressof(::ChainActive()) == std::addressof(m_context->chainman->ActiveChain()));
|
||||
return m_context->chainman->ActiveChain().Height();
|
||||
}
|
||||
uint256 getBestBlockHash() override
|
||||
{
|
||||
const CBlockIndex* tip = WITH_LOCK(::cs_main, return ::ChainActive().Tip());
|
||||
assert(std::addressof(::ChainActive()) == std::addressof(m_context->chainman->ActiveChain()));
|
||||
const CBlockIndex* tip = WITH_LOCK(::cs_main, return m_context->chainman->ActiveChain().Tip());
|
||||
return tip ? tip->GetBlockHash() : Params().GenesisBlock().GetHash();
|
||||
}
|
||||
int64_t getLastBlockTime() override
|
||||
{
|
||||
LOCK(::cs_main);
|
||||
if (::ChainActive().Tip()) {
|
||||
return ::ChainActive().Tip()->GetBlockTime();
|
||||
assert(std::addressof(::ChainActive()) == std::addressof(m_context->chainman->ActiveChain()));
|
||||
if (m_context->chainman->ActiveChain().Tip()) {
|
||||
return m_context->chainman->ActiveChain().Tip()->GetBlockTime();
|
||||
}
|
||||
return Params().GenesisBlock().GetBlockTime(); // Genesis block's time of current network
|
||||
}
|
||||
@ -202,11 +205,15 @@ public:
|
||||
const CBlockIndex* tip;
|
||||
{
|
||||
LOCK(::cs_main);
|
||||
tip = ::ChainActive().Tip();
|
||||
assert(std::addressof(::ChainActive()) == std::addressof(m_context->chainman->ActiveChain()));
|
||||
tip = m_context->chainman->ActiveChain().Tip();
|
||||
}
|
||||
return GuessVerificationProgress(Params().TxData(), tip);
|
||||
}
|
||||
bool isInitialBlockDownload() override { return ::ChainstateActive().IsInitialBlockDownload(); }
|
||||
bool isInitialBlockDownload() override {
|
||||
assert(std::addressof(::ChainstateActive()) == std::addressof(m_context->chainman->ActiveChainstate()));
|
||||
return m_context->chainman->ActiveChainstate().IsInitialBlockDownload();
|
||||
}
|
||||
bool getReindex() override { return ::fReindex; }
|
||||
bool getImporting() override { return ::fImporting; }
|
||||
void setNetworkActive(bool active) override
|
||||
@ -231,7 +238,8 @@ public:
|
||||
bool getUnspentOutput(const COutPoint& output, Coin& coin) override
|
||||
{
|
||||
LOCK(::cs_main);
|
||||
return ::ChainstateActive().CoinsTip().GetCoin(output, coin);
|
||||
assert(std::addressof(::ChainstateActive()) == std::addressof(m_context->chainman->ActiveChainstate()));
|
||||
return m_context->chainman->ActiveChainstate().CoinsTip().GetCoin(output, coin);
|
||||
}
|
||||
WalletClient& walletClient() override
|
||||
{
|
||||
@ -441,13 +449,15 @@ public:
|
||||
bool checkFinalTx(const CTransaction& tx) override
|
||||
{
|
||||
LOCK(cs_main);
|
||||
return CheckFinalTx(::ChainActive().Tip(), tx);
|
||||
assert(std::addressof(::ChainActive()) == std::addressof(m_node.chainman->ActiveChain()));
|
||||
return CheckFinalTx(m_node.chainman->ActiveChain().Tip(), tx);
|
||||
}
|
||||
Optional<int> findLocatorFork(const CBlockLocator& locator) override
|
||||
{
|
||||
LOCK(cs_main);
|
||||
const CChain& active = Assert(m_node.chainman)->ActiveChain();
|
||||
if (CBlockIndex* fork = g_chainman.m_blockman.FindForkInGlobalIndex(active, locator)) {
|
||||
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
|
||||
if (CBlockIndex* fork = m_node.chainman->m_blockman.FindForkInGlobalIndex(active, locator)) {
|
||||
return fork->nHeight;
|
||||
}
|
||||
return nullopt;
|
||||
@ -456,7 +466,8 @@ public:
|
||||
{
|
||||
WAIT_LOCK(cs_main, lock);
|
||||
const CChain& active = Assert(m_node.chainman)->ActiveChain();
|
||||
return FillBlock(g_chainman.m_blockman.LookupBlockIndex(hash), block, lock, active);
|
||||
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
|
||||
return FillBlock(m_node.chainman->m_blockman.LookupBlockIndex(hash), block, lock, active);
|
||||
}
|
||||
bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock& block) override
|
||||
{
|
||||
@ -468,7 +479,8 @@ public:
|
||||
{
|
||||
WAIT_LOCK(cs_main, lock);
|
||||
const CChain& active = Assert(m_node.chainman)->ActiveChain();
|
||||
if (const CBlockIndex* block = g_chainman.m_blockman.LookupBlockIndex(block_hash)) {
|
||||
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
|
||||
if (const CBlockIndex* block = m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) {
|
||||
if (const CBlockIndex* ancestor = block->GetAncestor(ancestor_height)) {
|
||||
return FillBlock(ancestor, ancestor_out, lock, active);
|
||||
}
|
||||
@ -479,8 +491,10 @@ public:
|
||||
{
|
||||
WAIT_LOCK(cs_main, lock);
|
||||
const CChain& active = Assert(m_node.chainman)->ActiveChain();
|
||||
const CBlockIndex* block = g_chainman.m_blockman.LookupBlockIndex(block_hash);
|
||||
const CBlockIndex* ancestor = g_chainman.m_blockman.LookupBlockIndex(ancestor_hash);
|
||||
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
|
||||
const CBlockIndex* block = m_node.chainman->m_blockman.LookupBlockIndex(block_hash);
|
||||
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
|
||||
const CBlockIndex* ancestor = m_node.chainman->m_blockman.LookupBlockIndex(ancestor_hash);
|
||||
if (block && ancestor && block->GetAncestor(ancestor->nHeight) != ancestor) ancestor = nullptr;
|
||||
return FillBlock(ancestor, ancestor_out, lock, active);
|
||||
}
|
||||
@ -488,8 +502,10 @@ public:
|
||||
{
|
||||
WAIT_LOCK(cs_main, lock);
|
||||
const CChain& active = Assert(m_node.chainman)->ActiveChain();
|
||||
const CBlockIndex* block1 = g_chainman.m_blockman.LookupBlockIndex(block_hash1);
|
||||
const CBlockIndex* block2 = g_chainman.m_blockman.LookupBlockIndex(block_hash2);
|
||||
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
|
||||
const CBlockIndex* block1 = m_node.chainman->m_blockman.LookupBlockIndex(block_hash1);
|
||||
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
|
||||
const CBlockIndex* block2 = m_node.chainman->m_blockman.LookupBlockIndex(block_hash2);
|
||||
const CBlockIndex* ancestor = block1 && block2 ? LastCommonAncestor(block1, block2) : nullptr;
|
||||
// Using & instead of && below to avoid short circuiting and leaving
|
||||
// output uninitialized.
|
||||
@ -499,7 +515,8 @@ public:
|
||||
double guessVerificationProgress(const uint256& block_hash) override
|
||||
{
|
||||
LOCK(cs_main);
|
||||
return GuessVerificationProgress(Params().TxData(), g_chainman.m_blockman.LookupBlockIndex(block_hash));
|
||||
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
|
||||
return GuessVerificationProgress(Params().TxData(), m_node.chainman->m_blockman.LookupBlockIndex(block_hash));
|
||||
}
|
||||
bool hasBlocks(const uint256& block_hash, int min_height, Optional<int> max_height) override
|
||||
{
|
||||
@ -511,7 +528,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);
|
||||
if (CBlockIndex* block = g_chainman.m_blockman.LookupBlockIndex(block_hash)) {
|
||||
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
|
||||
if (CBlockIndex* block = m_node.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
|
||||
@ -601,7 +619,10 @@ public:
|
||||
return ::fHavePruned;
|
||||
}
|
||||
bool isReadyToBroadcast() override { return !::fImporting && !::fReindex && !isInitialBlockDownload(); }
|
||||
bool isInitialBlockDownload() override { return ::ChainstateActive().IsInitialBlockDownload(); }
|
||||
bool isInitialBlockDownload() override {
|
||||
assert(std::addressof(::ChainstateActive()) == std::addressof(m_node.chainman->ActiveChainstate()));
|
||||
return m_node.chainman->ActiveChainstate().IsInitialBlockDownload();
|
||||
}
|
||||
bool shutdownRequested() override { return ShutdownRequested(); }
|
||||
int64_t getAdjustedTime() override { return GetAdjustedTime(); }
|
||||
void initMessage(const std::string& message) override { ::uiInterface.InitMessage(message); }
|
||||
|
@ -39,9 +39,10 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
|
||||
|
||||
{ // cs_main scope
|
||||
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
|
||||
// and return early.
|
||||
CCoinsViewCache &view = ::ChainstateActive().CoinsTip();
|
||||
CCoinsViewCache &view = node.chainman->ActiveChainstate().CoinsTip();
|
||||
for (size_t o = 0; o < tx->vout.size(); o++) {
|
||||
const Coin& existingCoin = view.AccessCoin(COutPoint(hashTx, o));
|
||||
// IsSpent doesn't mean the coin is spent, it means the output doesn't exist.
|
||||
@ -53,7 +54,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
|
||||
if (max_tx_fee > 0) {
|
||||
// First, call ATMP with test_accept and check the fee. If ATMP
|
||||
// fails here, return error immediately.
|
||||
const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), *node.mempool, tx, false /* bypass_limits */,
|
||||
const MempoolAcceptResult result = AcceptToMemoryPool(node.chainman->ActiveChainstate(), *node.mempool, tx, false /* bypass_limits */,
|
||||
true /* test_accept */);
|
||||
if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
|
||||
return HandleATMPError(result.m_state, err_string);
|
||||
@ -62,7 +63,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
|
||||
}
|
||||
}
|
||||
// Try to submit the transaction to the mempool.
|
||||
const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), *node.mempool, tx, false /* bypass_limits */,
|
||||
const MempoolAcceptResult result = AcceptToMemoryPool(node.chainman->ActiveChainstate(), *node.mempool, tx, false /* bypass_limits */,
|
||||
false /* test_accept */);
|
||||
if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
|
||||
return HandleATMPError(result.m_state, err_string);
|
||||
|
@ -1073,9 +1073,9 @@ static RPCHelpMan gettxoutsetinfo()
|
||||
|
||||
const CoinStatsHashType hash_type{request.params[0].isNull() ? CoinStatsHashType::HASH_SERIALIZED : ParseHashType(request.params[0].get_str())};
|
||||
|
||||
CCoinsView* coins_view = WITH_LOCK(cs_main, return &ChainstateActive().CoinsDB());
|
||||
CCoinsView* coins_view = WITH_LOCK(::cs_main, return &::ChainstateActive().CoinsDB());
|
||||
NodeContext& node = EnsureNodeContext(request.context);
|
||||
if (GetUTXOStats(coins_view, stats, hash_type, node.rpc_interruption_point)) {
|
||||
if (GetUTXOStats(coins_view, WITH_LOCK(::cs_main, return std::ref(g_chainman.m_blockman)), stats, hash_type, node.rpc_interruption_point)) {
|
||||
ret.pushKV("height", (int64_t)stats.nHeight);
|
||||
ret.pushKV("bestblock", stats.hashBlock.GetHex());
|
||||
ret.pushKV("transactions", (int64_t)stats.nTransactions);
|
||||
@ -2444,7 +2444,7 @@ UniValue CreateUTXOSnapshot(NodeContext& node, CChainState& chainstate, CAutoFil
|
||||
|
||||
chainstate.ForceFlushStateToDisk();
|
||||
|
||||
if (!GetUTXOStats(&chainstate.CoinsDB(), stats, CoinStatsHashType::NONE, node.rpc_interruption_point)) {
|
||||
if (!GetUTXOStats(&chainstate.CoinsDB(), chainstate.m_blockman, stats, CoinStatsHashType::NONE, node.rpc_interruption_point)) {
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
|
||||
}
|
||||
|
||||
|
@ -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(coinbase_script));
|
||||
std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(mempool, Params()).CreateNewBlock(::ChainstateActive(), 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(coinbase_script));
|
||||
std::unique_ptr<CBlockTemplate> blocktemplate(BlockAssembler(empty_mempool, chainparams).CreateNewBlock(::ChainstateActive(), coinbase_script));
|
||||
if (!blocktemplate) {
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
|
||||
}
|
||||
@ -369,7 +369,7 @@ static RPCHelpMan generateblock()
|
||||
|
||||
// Add transactions
|
||||
block.vtx.insert(block.vtx.end(), txs.begin(), txs.end());
|
||||
RegenerateCommitments(block);
|
||||
RegenerateCommitments(block, WITH_LOCK(::cs_main, return std::ref(g_chainman.m_blockman)));
|
||||
|
||||
{
|
||||
LOCK(cs_main);
|
||||
@ -747,7 +747,7 @@ static RPCHelpMan getblocktemplate()
|
||||
|
||||
// Create new block
|
||||
CScript scriptDummy = CScript() << OP_TRUE;
|
||||
pblocktemplate = BlockAssembler(mempool, Params()).CreateNewBlock(scriptDummy);
|
||||
pblocktemplate = BlockAssembler(mempool, Params()).CreateNewBlock(::ChainstateActive(), scriptDummy);
|
||||
if (!pblocktemplate)
|
||||
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
|
||||
|
||||
|
@ -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(scriptPubKey);
|
||||
std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(*m_node.mempool, chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey);
|
||||
CBlock& block = pblocktemplate->block;
|
||||
block.hashPrevBlock = prev->GetBlockHash();
|
||||
block.nTime = prev->nTime + 1;
|
||||
|
@ -264,7 +264,7 @@ FUZZ_TARGET_INIT(coins_view, initialize_coins_view)
|
||||
CCoinsStats stats;
|
||||
bool expected_code_path = false;
|
||||
try {
|
||||
(void)GetUTXOStats(&coins_view_cache, stats, CoinStatsHashType::HASH_SERIALIZED);
|
||||
(void)GetUTXOStats(&coins_view_cache, WITH_LOCK(::cs_main, return std::ref(g_chainman.m_blockman)), stats, CoinStatsHashType::HASH_SERIALIZED);
|
||||
} catch (const std::logic_error&) {
|
||||
expected_code_path = true;
|
||||
}
|
||||
|
@ -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(scriptPubKey);
|
||||
std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey);
|
||||
pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey);
|
||||
pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey);
|
||||
pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey);
|
||||
pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey));
|
||||
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey));
|
||||
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey), std::runtime_error, HasReason("bad-blk-sigops"));
|
||||
BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey));
|
||||
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey));
|
||||
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey), std::runtime_error, HasReason("bad-txns-inputs-missingorspent"));
|
||||
BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey));
|
||||
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey), std::runtime_error, HasReason("bad-cb-multiple"));
|
||||
BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey), std::runtime_error, HasReason("bad-txns-inputs-missingorspent"));
|
||||
BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey));
|
||||
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey));
|
||||
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey), std::runtime_error, HasReason("block-validation-failed"));
|
||||
BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey));
|
||||
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), 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(scriptPubKey));
|
||||
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5U);
|
||||
|
||||
::ChainActive().Tip()->nHeight--;
|
||||
|
@ -42,7 +42,7 @@ std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node, const CScript& coi
|
||||
{
|
||||
auto block = std::make_shared<CBlock>(
|
||||
BlockAssembler{*Assert(node.mempool), Params()}
|
||||
.CreateNewBlock(coinbase_scriptPubKey)
|
||||
.CreateNewBlock(::ChainstateActive(), coinbase_scriptPubKey)
|
||||
->block);
|
||||
|
||||
LOCK(cs_main);
|
||||
|
@ -245,13 +245,13 @@ CBlock TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransa
|
||||
{
|
||||
const CChainParams& chainparams = Params();
|
||||
CTxMemPool empty_pool;
|
||||
CBlock block = BlockAssembler(empty_pool, chainparams).CreateNewBlock(scriptPubKey)->block;
|
||||
CBlock block = BlockAssembler(empty_pool, chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey)->block;
|
||||
|
||||
Assert(block.vtx.size() == 1);
|
||||
for (const CMutableTransaction& tx : txns) {
|
||||
block.vtx.push_back(MakeTransactionRef(tx));
|
||||
}
|
||||
RegenerateCommitments(block);
|
||||
RegenerateCommitments(block, WITH_LOCK(::cs_main, return std::ref(g_chainman.m_blockman)));
|
||||
|
||||
while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce;
|
||||
|
||||
|
@ -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(CScript{} << i++ << OP_TRUE);
|
||||
auto ptemplate = BlockAssembler(*m_node.mempool, Params()).CreateNewBlock(::ChainstateActive(), 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(pubKey);
|
||||
auto ptemplate = BlockAssembler(*m_node.mempool, Params()).CreateNewBlock(::ChainstateActive(), pubKey);
|
||||
CBlock pblock = ptemplate->block;
|
||||
|
||||
CTxOut witness;
|
||||
|
@ -5425,7 +5425,7 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
|
||||
// about the snapshot_chainstate.
|
||||
CCoinsViewDB* snapshot_coinsdb = WITH_LOCK(::cs_main, return &snapshot_chainstate.CoinsDB());
|
||||
|
||||
if (!GetUTXOStats(snapshot_coinsdb, stats, CoinStatsHashType::HASH_SERIALIZED, breakpoint_fnc)) {
|
||||
if (!GetUTXOStats(snapshot_coinsdb, WITH_LOCK(::cs_main, return std::ref(m_blockman)), stats, CoinStatsHashType::HASH_SERIALIZED, breakpoint_fnc)) {
|
||||
LogPrintf("[snapshot] failed to generate coins stats\n");
|
||||
return false;
|
||||
}
|
||||
|
@ -148,8 +148,6 @@ extern const std::vector<std::string> CHECKLEVEL_DOC;
|
||||
FILE* OpenBlockFile(const FlatFilePos &pos, bool fReadOnly = false);
|
||||
/** Translation to a filesystem path */
|
||||
fs::path GetBlockPosFilename(const FlatFilePos &pos);
|
||||
/** Ensures we have a genesis block in the block tree, possibly writing one to disk. */
|
||||
bool LoadGenesisBlock(const CChainParams& chainparams);
|
||||
/** Unload database information */
|
||||
void UnloadBlockIndex(CTxMemPool* mempool, ChainstateManager& chainman);
|
||||
/** Run instances of script checking worker threads */
|
||||
@ -725,6 +723,7 @@ public:
|
||||
/** Replay blocks that aren't fully applied to the database. */
|
||||
bool ReplayBlocks(const CChainParams& params);
|
||||
bool RewindBlockIndex(const CChainParams& params) LOCKS_EXCLUDED(cs_main);
|
||||
/** Ensures we have a genesis block in the block tree, possibly writing one to disk. */
|
||||
bool LoadGenesisBlock(const CChainParams& chainparams);
|
||||
|
||||
void PruneBlockIndexCandidates();
|
||||
|
Loading…
Reference in New Issue
Block a user