0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-08 10:31:50 -05:00

validation: Make ProcessNewBlock*() members of ChainstateManager

This commit is contained in:
MarcoFalke 2020-04-18 09:55:57 -04:00
parent fa24d49098
commit fa1d97b256
No known key found for this signature in database
GPG key ID: CE2B75697E69A548
11 changed files with 81 additions and 69 deletions

View file

@ -1736,7 +1736,7 @@ inline void static SendBlockTransactions(const CBlock& block, const BlockTransac
connman->PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::BLOCKTXN, resp)); connman->PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::BLOCKTXN, resp));
} }
bool static ProcessHeadersMessage(CNode* pfrom, CConnman* connman, CTxMemPool& mempool, const std::vector<CBlockHeader>& headers, const CChainParams& chainparams, bool via_compact_block) bool static ProcessHeadersMessage(CNode* pfrom, CConnman* connman, ChainstateManager& chainman, CTxMemPool& mempool, const std::vector<CBlockHeader>& headers, const CChainParams& chainparams, bool via_compact_block)
{ {
const CNetMsgMaker msgMaker(pfrom->GetSendVersion()); const CNetMsgMaker msgMaker(pfrom->GetSendVersion());
size_t nCount = headers.size(); size_t nCount = headers.size();
@ -1796,7 +1796,7 @@ bool static ProcessHeadersMessage(CNode* pfrom, CConnman* connman, CTxMemPool& m
} }
BlockValidationState state; BlockValidationState state;
if (!ProcessNewBlockHeaders(headers, state, chainparams, &pindexLast)) { if (!chainman.ProcessNewBlockHeaders(headers, state, chainparams, &pindexLast)) {
if (state.IsInvalid()) { if (state.IsInvalid()) {
MaybePunishNodeForBlock(pfrom->GetId(), state, via_compact_block, "invalid header received"); MaybePunishNodeForBlock(pfrom->GetId(), state, via_compact_block, "invalid header received");
return false; return false;
@ -2846,7 +2846,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
const CBlockIndex *pindex = nullptr; const CBlockIndex *pindex = nullptr;
BlockValidationState state; BlockValidationState state;
if (!ProcessNewBlockHeaders({cmpctblock.header}, state, chainparams, &pindex)) { if (!chainman.ProcessNewBlockHeaders({cmpctblock.header}, state, chainparams, &pindex)) {
if (state.IsInvalid()) { if (state.IsInvalid()) {
MaybePunishNodeForBlock(pfrom->GetId(), state, /*via_compact_block*/ true, "invalid header via cmpctblock"); MaybePunishNodeForBlock(pfrom->GetId(), state, /*via_compact_block*/ true, "invalid header via cmpctblock");
return true; return true;
@ -2998,7 +2998,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
// the peer if the header turns out to be for an invalid block. // the peer if the header turns out to be for an invalid block.
// Note that if a peer tries to build on an invalid chain, that // Note that if a peer tries to build on an invalid chain, that
// will be detected and the peer will be banned. // will be detected and the peer will be banned.
return ProcessHeadersMessage(pfrom, connman, mempool, {cmpctblock.header}, chainparams, /*via_compact_block=*/true); return ProcessHeadersMessage(pfrom, connman, chainman, mempool, {cmpctblock.header}, chainparams, /*via_compact_block=*/true);
} }
if (fBlockReconstructed) { if (fBlockReconstructed) {
@ -3018,7 +3018,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
// we have a chain with at least nMinimumChainWork), and we ignore // we have a chain with at least nMinimumChainWork), and we ignore
// compact blocks with less work than our tip, it is safe to treat // compact blocks with less work than our tip, it is safe to treat
// reconstructed compact blocks as having been requested. // reconstructed compact blocks as having been requested.
ProcessNewBlock(chainparams, pblock, /*fForceProcessing=*/true, &fNewBlock); chainman.ProcessNewBlock(chainparams, pblock, /*fForceProcessing=*/true, &fNewBlock);
if (fNewBlock) { if (fNewBlock) {
pfrom->nLastBlockTime = GetTime(); pfrom->nLastBlockTime = GetTime();
} else { } else {
@ -3108,7 +3108,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
// disk-space attacks), but this should be safe due to the // disk-space attacks), but this should be safe due to the
// protections in the compact block handler -- see related comment // protections in the compact block handler -- see related comment
// in compact block optimistic reconstruction handling. // in compact block optimistic reconstruction handling.
ProcessNewBlock(chainparams, pblock, /*fForceProcessing=*/true, &fNewBlock); chainman.ProcessNewBlock(chainparams, pblock, /*fForceProcessing=*/true, &fNewBlock);
if (fNewBlock) { if (fNewBlock) {
pfrom->nLastBlockTime = GetTime(); pfrom->nLastBlockTime = GetTime();
} else { } else {
@ -3142,7 +3142,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
ReadCompactSize(vRecv); // ignore tx count; assume it is 0. ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
} }
return ProcessHeadersMessage(pfrom, connman, mempool, headers, chainparams, /*via_compact_block=*/false); return ProcessHeadersMessage(pfrom, connman, chainman, mempool, headers, chainparams, /*via_compact_block=*/false);
} }
if (msg_type == NetMsgType::BLOCK) if (msg_type == NetMsgType::BLOCK)
@ -3171,7 +3171,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
mapBlockSource.emplace(hash, std::make_pair(pfrom->GetId(), true)); mapBlockSource.emplace(hash, std::make_pair(pfrom->GetId(), true));
} }
bool fNewBlock = false; bool fNewBlock = false;
ProcessNewBlock(chainparams, pblock, forceProcessing, &fNewBlock); chainman.ProcessNewBlock(chainparams, pblock, forceProcessing, &fNewBlock);
if (fNewBlock) { if (fNewBlock) {
pfrom->nLastBlockTime = GetTime(); pfrom->nLastBlockTime = GetTime();
} else { } else {

View file

@ -71,6 +71,12 @@ CTxMemPool& EnsureMemPool(const util::Ref& context)
return *node.mempool; return *node.mempool;
} }
ChainstateManager& EnsureChainman(const util::Ref& context)
{
NodeContext& node = EnsureNodeContext(context);
return EnsureChainman(node);
}
/* Calculate the difficulty for a given block index. /* Calculate the difficulty for a given block index.
*/ */
double GetDifficulty(const CBlockIndex* blockindex) double GetDifficulty(const CBlockIndex* blockindex)

View file

@ -16,6 +16,7 @@ extern RecursiveMutex cs_main;
class CBlock; class CBlock;
class CBlockIndex; class CBlockIndex;
class CTxMemPool; class CTxMemPool;
class ChainstateManager;
class UniValue; class UniValue;
struct NodeContext; struct NodeContext;
namespace util { namespace util {
@ -52,5 +53,6 @@ void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES],
NodeContext& EnsureNodeContext(const util::Ref& context); NodeContext& EnsureNodeContext(const util::Ref& context);
CTxMemPool& EnsureMemPool(const util::Ref& context); CTxMemPool& EnsureMemPool(const util::Ref& context);
ChainstateManager& EnsureChainman(const util::Ref& context);
#endif #endif

View file

@ -101,7 +101,7 @@ static UniValue getnetworkhashps(const JSONRPCRequest& request)
return GetNetworkHashPS(!request.params[0].isNull() ? request.params[0].get_int() : 120, !request.params[1].isNull() ? request.params[1].get_int() : -1); return GetNetworkHashPS(!request.params[0].isNull() ? request.params[0].get_int() : 120, !request.params[1].isNull() ? request.params[1].get_int() : -1);
} }
static bool GenerateBlock(CBlock& block, uint64_t& max_tries, unsigned int& extra_nonce, uint256& block_hash) static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t& max_tries, unsigned int& extra_nonce, uint256& block_hash)
{ {
block_hash.SetNull(); block_hash.SetNull();
@ -124,14 +124,15 @@ static bool GenerateBlock(CBlock& block, uint64_t& max_tries, unsigned int& extr
} }
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block); std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
if (!ProcessNewBlock(chainparams, shared_pblock, true, nullptr)) if (!chainman.ProcessNewBlock(chainparams, shared_pblock, true, nullptr)) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
}
block_hash = block.GetHash(); block_hash = block.GetHash();
return true; return true;
} }
static UniValue generateBlocks(const CTxMemPool& mempool, const CScript& coinbase_script, int nGenerate, uint64_t nMaxTries) static UniValue generateBlocks(ChainstateManager& chainman, const CTxMemPool& mempool, const CScript& coinbase_script, int nGenerate, uint64_t nMaxTries)
{ {
int nHeightEnd = 0; int nHeightEnd = 0;
int nHeight = 0; int nHeight = 0;
@ -151,7 +152,7 @@ static UniValue generateBlocks(const CTxMemPool& mempool, const CScript& coinbas
CBlock *pblock = &pblocktemplate->block; CBlock *pblock = &pblocktemplate->block;
uint256 block_hash; uint256 block_hash;
if (!GenerateBlock(*pblock, nMaxTries, nExtraNonce, block_hash)) { if (!GenerateBlock(chainman, *pblock, nMaxTries, nExtraNonce, block_hash)) {
break; break;
} }
@ -228,8 +229,9 @@ static UniValue generatetodescriptor(const JSONRPCRequest& request)
} }
const CTxMemPool& mempool = EnsureMemPool(request.context); const CTxMemPool& mempool = EnsureMemPool(request.context);
ChainstateManager& chainman = EnsureChainman(request.context);
return generateBlocks(mempool, coinbase_script, num_blocks, max_tries); return generateBlocks(chainman, mempool, coinbase_script, num_blocks, max_tries);
} }
static UniValue generatetoaddress(const JSONRPCRequest& request) static UniValue generatetoaddress(const JSONRPCRequest& request)
@ -266,10 +268,11 @@ static UniValue generatetoaddress(const JSONRPCRequest& request)
} }
const CTxMemPool& mempool = EnsureMemPool(request.context); const CTxMemPool& mempool = EnsureMemPool(request.context);
ChainstateManager& chainman = EnsureChainman(request.context);
CScript coinbase_script = GetScriptForDestination(destination); CScript coinbase_script = GetScriptForDestination(destination);
return generateBlocks(mempool, coinbase_script, nGenerate, nMaxTries); return generateBlocks(chainman, mempool, coinbase_script, nGenerate, nMaxTries);
} }
static UniValue generateblock(const JSONRPCRequest& request) static UniValue generateblock(const JSONRPCRequest& request)
@ -370,7 +373,7 @@ static UniValue generateblock(const JSONRPCRequest& request)
uint64_t max_tries{1000000}; uint64_t max_tries{1000000};
unsigned int extra_nonce{0}; unsigned int extra_nonce{0};
if (!GenerateBlock(block, max_tries, extra_nonce, block_hash) || block_hash.IsNull()) { if (!GenerateBlock(EnsureChainman(request.context), block, max_tries, extra_nonce, block_hash) || block_hash.IsNull()) {
throw JSONRPCError(RPC_MISC_ERROR, "Failed to make block."); throw JSONRPCError(RPC_MISC_ERROR, "Failed to make block.");
} }
@ -947,7 +950,7 @@ static UniValue submitblock(const JSONRPCRequest& request)
bool new_block; bool new_block;
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash()); auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
RegisterSharedValidationInterface(sc); RegisterSharedValidationInterface(sc);
bool accepted = ProcessNewBlock(Params(), blockptr, /* fForceProcessing */ true, /* fNewBlock */ &new_block); bool accepted = EnsureChainman(request.context).ProcessNewBlock(Params(), blockptr, /* fForceProcessing */ true, /* fNewBlock */ &new_block);
UnregisterSharedValidationInterface(sc); UnregisterSharedValidationInterface(sc);
if (!new_block && accepted) { if (!new_block && accepted) {
return "duplicate"; return "duplicate";
@ -986,7 +989,7 @@ static UniValue submitheader(const JSONRPCRequest& request)
} }
BlockValidationState state; BlockValidationState state;
ProcessNewBlockHeaders({h}, state, Params()); EnsureChainman(request.context).ProcessNewBlockHeaders({h}, state, Params());
if (state.IsValid()) return NullUniValue; if (state.IsValid()) return NullUniValue;
if (state.IsError()) { if (state.IsError()) {
throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString()); throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString());

View file

@ -94,7 +94,7 @@ bool BuildChainTestingSetup::BuildChain(const CBlockIndex* pindex,
CBlockHeader header = block->GetBlockHeader(); CBlockHeader header = block->GetBlockHeader();
BlockValidationState state; BlockValidationState state;
if (!ProcessNewBlockHeaders({header}, state, Params(), &pindex)) { if (!EnsureChainman(m_node).ProcessNewBlockHeaders({header}, state, Params(), &pindex)) {
return false; return false;
} }
} }
@ -171,7 +171,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
uint256 chainA_last_header = last_header; uint256 chainA_last_header = last_header;
for (size_t i = 0; i < 2; i++) { for (size_t i = 0; i < 2; i++) {
const auto& block = chainA[i]; const auto& block = chainA[i];
BOOST_REQUIRE(ProcessNewBlock(Params(), block, true, nullptr)); BOOST_REQUIRE(EnsureChainman(m_node).ProcessNewBlock(Params(), block, true, nullptr));
} }
for (size_t i = 0; i < 2; i++) { for (size_t i = 0; i < 2; i++) {
const auto& block = chainA[i]; const auto& block = chainA[i];
@ -189,7 +189,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
uint256 chainB_last_header = last_header; uint256 chainB_last_header = last_header;
for (size_t i = 0; i < 3; i++) { for (size_t i = 0; i < 3; i++) {
const auto& block = chainB[i]; const auto& block = chainB[i];
BOOST_REQUIRE(ProcessNewBlock(Params(), block, true, nullptr)); BOOST_REQUIRE(EnsureChainman(m_node).ProcessNewBlock(Params(), block, true, nullptr));
} }
for (size_t i = 0; i < 3; i++) { for (size_t i = 0; i < 3; i++) {
const auto& block = chainB[i]; const auto& block = chainB[i];
@ -220,7 +220,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
// Reorg back to chain A. // Reorg back to chain A.
for (size_t i = 2; i < 4; i++) { for (size_t i = 2; i < 4; i++) {
const auto& block = chainA[i]; const auto& block = chainA[i];
BOOST_REQUIRE(ProcessNewBlock(Params(), block, true, nullptr)); BOOST_REQUIRE(EnsureChainman(m_node).ProcessNewBlock(Params(), block, true, nullptr));
} }
// Check that chain A and B blocks can be retrieved. // Check that chain A and B blocks can be retrieved.

View file

@ -253,7 +253,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
pblock->nNonce = blockinfo[i].nonce; pblock->nNonce = blockinfo[i].nonce;
} }
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock); std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock);
BOOST_CHECK(ProcessNewBlock(chainparams, shared_pblock, true, nullptr)); BOOST_CHECK(EnsureChainman(m_node).ProcessNewBlock(chainparams, shared_pblock, true, nullptr));
pblock->hashPrevBlock = pblock->GetHash(); pblock->hashPrevBlock = pblock->GetHash();
} }

View file

@ -31,7 +31,7 @@ CTxIn MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
assert(block->nNonce); assert(block->nNonce);
} }
bool processed{ProcessNewBlock(Params(), block, true, nullptr)}; bool processed{EnsureChainman(node).ProcessNewBlock(Params(), block, true, nullptr)};
assert(processed); assert(processed);
return CTxIn{block->vtx[0]->GetHash(), 0}; return CTxIn{block->vtx[0]->GetHash(), 0};

View file

@ -228,7 +228,7 @@ CBlock TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransa
while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce; while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce;
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block); std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
ProcessNewBlock(chainparams, shared_pblock, true, nullptr); EnsureChainman(m_node).ProcessNewBlock(chainparams, shared_pblock, true, nullptr);
CBlock result = block; CBlock result = block;
return result; return result;

View file

@ -163,10 +163,10 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
std::transform(blocks.begin(), blocks.end(), std::back_inserter(headers), [](std::shared_ptr<const CBlock> b) { return b->GetBlockHeader(); }); std::transform(blocks.begin(), blocks.end(), std::back_inserter(headers), [](std::shared_ptr<const CBlock> b) { return b->GetBlockHeader(); });
// Process all the headers so we understand the toplogy of the chain // Process all the headers so we understand the toplogy of the chain
BOOST_CHECK(ProcessNewBlockHeaders(headers, state, Params())); BOOST_CHECK(EnsureChainman(m_node).ProcessNewBlockHeaders(headers, state, Params()));
// Connect the genesis block and drain any outstanding events // Connect the genesis block and drain any outstanding events
BOOST_CHECK(ProcessNewBlock(Params(), std::make_shared<CBlock>(Params().GenesisBlock()), true, &ignored)); BOOST_CHECK(EnsureChainman(m_node).ProcessNewBlock(Params(), std::make_shared<CBlock>(Params().GenesisBlock()), true, &ignored));
SyncWithValidationInterfaceQueue(); SyncWithValidationInterfaceQueue();
// subscribe to events (this subscriber will validate event ordering) // subscribe to events (this subscriber will validate event ordering)
@ -183,18 +183,18 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
// will subscribe to events generated during block validation and assert on ordering invariance // will subscribe to events generated during block validation and assert on ordering invariance
std::vector<std::thread> threads; std::vector<std::thread> threads;
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
threads.emplace_back([&blocks]() { threads.emplace_back([&]() {
bool ignored; bool ignored;
FastRandomContext insecure; FastRandomContext insecure;
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
auto block = blocks[insecure.randrange(blocks.size() - 1)]; auto block = blocks[insecure.randrange(blocks.size() - 1)];
ProcessNewBlock(Params(), block, true, &ignored); EnsureChainman(m_node).ProcessNewBlock(Params(), block, true, &ignored);
} }
// to make sure that eventually we process the full chain - do it here // to make sure that eventually we process the full chain - do it here
for (auto block : blocks) { for (auto block : blocks) {
if (block->vtx.size() == 1) { if (block->vtx.size() == 1) {
bool processed = ProcessNewBlock(Params(), block, true, &ignored); bool processed = EnsureChainman(m_node).ProcessNewBlock(Params(), block, true, &ignored);
assert(processed); assert(processed);
} }
} }
@ -232,8 +232,8 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
BOOST_AUTO_TEST_CASE(mempool_locks_reorg) BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
{ {
bool ignored; bool ignored;
auto ProcessBlock = [&ignored](std::shared_ptr<const CBlock> block) -> bool { auto ProcessBlock = [&](std::shared_ptr<const CBlock> block) -> bool {
return ProcessNewBlock(Params(), block, /* fForceProcessing */ true, /* fNewBlock */ &ignored); return EnsureChainman(m_node).ProcessNewBlock(Params(), block, /* fForceProcessing */ true, /* fNewBlock */ &ignored);
}; };
// Process all mined blocks // Process all mined blocks

View file

@ -3691,13 +3691,14 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationS
} }
// Exposed wrapper for AcceptBlockHeader // Exposed wrapper for AcceptBlockHeader
bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex) bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex)
{ {
AssertLockNotHeld(cs_main);
{ {
LOCK(cs_main); LOCK(cs_main);
for (const CBlockHeader& header : headers) { for (const CBlockHeader& header : headers) {
CBlockIndex *pindex = nullptr; // Use a temp pindex instead of ppindex to avoid a const_cast CBlockIndex *pindex = nullptr; // Use a temp pindex instead of ppindex to avoid a const_cast
bool accepted = g_chainman.m_blockman.AcceptBlockHeader( bool accepted = m_blockman.AcceptBlockHeader(
header, state, chainparams, &pindex); header, state, chainparams, &pindex);
::ChainstateActive().CheckBlockIndex(chainparams.GetConsensus()); ::ChainstateActive().CheckBlockIndex(chainparams.GetConsensus());
@ -3819,7 +3820,7 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
return true; return true;
} }
bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock> pblock, bool fForceProcessing, bool *fNewBlock) bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock> pblock, bool fForceProcessing, bool* fNewBlock)
{ {
AssertLockNotHeld(cs_main); AssertLockNotHeld(cs_main);

View file

@ -150,41 +150,6 @@ extern bool fPruneMode;
/** Number of MiB of block files that we're trying to stay below. */ /** Number of MiB of block files that we're trying to stay below. */
extern uint64_t nPruneTarget; extern uint64_t nPruneTarget;
/**
* Process an incoming block. This only returns after the best known valid
* block is made active. Note that it does not, however, guarantee that the
* specific block passed to it has been checked for validity!
*
* If you want to *possibly* get feedback on whether pblock is valid, you must
* install a CValidationInterface (see validationinterface.h) - this will have
* its BlockChecked method called whenever *any* block completes validation.
*
* Note that we guarantee that either the proof-of-work is valid on pblock, or
* (and possibly also) BlockChecked will have been called.
*
* May not be called in a
* validationinterface callback.
*
* @param[in] pblock The block we want to process.
* @param[in] fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers.
* @param[out] fNewBlock A boolean which is set to indicate if the block was first received via this call
* @returns If the block was processed, independently of block validity
*/
bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock> pblock, bool fForceProcessing, bool* fNewBlock) LOCKS_EXCLUDED(cs_main);
/**
* Process incoming block headers.
*
* May not be called in a
* validationinterface callback.
*
* @param[in] block The block headers themselves
* @param[out] state This may be set to an Error state if any error occurred processing them
* @param[in] chainparams The params for the chain we want to connect to
* @param[out] ppindex If set, the pointer will be set to point to the last new block index object for the given headers
*/
bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex = nullptr) LOCKS_EXCLUDED(cs_main);
/** Open a block file (blk?????.dat) */ /** Open a block file (blk?????.dat) */
FILE* OpenBlockFile(const FlatFilePos &pos, bool fReadOnly = false); FILE* OpenBlockFile(const FlatFilePos &pos, bool fReadOnly = false);
/** Translation to a filesystem path */ /** Translation to a filesystem path */
@ -860,6 +825,41 @@ public:
CChain& ValidatedChain() const { return ValidatedChainstate().m_chain; } CChain& ValidatedChain() const { return ValidatedChainstate().m_chain; }
CBlockIndex* ValidatedTip() const { return ValidatedChain().Tip(); } CBlockIndex* ValidatedTip() const { return ValidatedChain().Tip(); }
/**
* Process an incoming block. This only returns after the best known valid
* block is made active. Note that it does not, however, guarantee that the
* specific block passed to it has been checked for validity!
*
* If you want to *possibly* get feedback on whether pblock is valid, you must
* install a CValidationInterface (see validationinterface.h) - this will have
* its BlockChecked method called whenever *any* block completes validation.
*
* Note that we guarantee that either the proof-of-work is valid on pblock, or
* (and possibly also) BlockChecked will have been called.
*
* May not be called in a
* validationinterface callback.
*
* @param[in] pblock The block we want to process.
* @param[in] fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers.
* @param[out] fNewBlock A boolean which is set to indicate if the block was first received via this call
* @returns If the block was processed, independently of block validity
*/
bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock> pblock, bool fForceProcessing, bool* fNewBlock) LOCKS_EXCLUDED(cs_main);
/**
* Process incoming block headers.
*
* May not be called in a
* validationinterface callback.
*
* @param[in] block The block headers themselves
* @param[out] state This may be set to an Error state if any error occurred processing them
* @param[in] chainparams The params for the chain we want to connect to
* @param[out] ppindex If set, the pointer will be set to point to the last new block index object for the given headers
*/
bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex = nullptr) LOCKS_EXCLUDED(cs_main);
//! Mark one block file as pruned (modify associated database entries) //! Mark one block file as pruned (modify associated database entries)
void PruneOneBlockFile(const int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main); void PruneOneBlockFile(const int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main);