Changeset View
Changeset View
Standalone View
Standalone View
src/interfaces/chain.cpp
Show First 20 Lines • Show All 211 Lines • ▼ Show 20 Lines | public: | ||||
const CChain &active = Assert(m_node.chainman)->ActiveChain(); | const CChain &active = Assert(m_node.chainman)->ActiveChain(); | ||||
return ContextualCheckTransactionForCurrentBlock( | return ContextualCheckTransactionForCurrentBlock( | ||||
active.Tip(), m_params.GetConsensus(), tx, state); | active.Tip(), m_params.GetConsensus(), tx, state); | ||||
} | } | ||||
std::optional<int> | std::optional<int> | ||||
findLocatorFork(const CBlockLocator &locator) override { | findLocatorFork(const CBlockLocator &locator) override { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
const CChain &active = Assert(m_node.chainman)->ActiveChain(); | const CChain &active = Assert(m_node.chainman)->ActiveChain(); | ||||
assert(std::addressof(g_chainman) == | |||||
std::addressof(*m_node.chainman)); | |||||
if (CBlockIndex *fork = | if (CBlockIndex *fork = | ||||
m_node.chainman->m_blockman.FindForkInGlobalIndex( | m_node.chainman->m_blockman.FindForkInGlobalIndex( | ||||
active, locator)) { | active, locator)) { | ||||
return fork->nHeight; | return fork->nHeight; | ||||
} | } | ||||
return std::nullopt; | return std::nullopt; | ||||
} | } | ||||
bool findBlock(const BlockHash &hash, | bool findBlock(const BlockHash &hash, | ||||
const FoundBlock &block) override { | const FoundBlock &block) override { | ||||
WAIT_LOCK(cs_main, lock); | WAIT_LOCK(cs_main, lock); | ||||
const CChain &active = Assert(m_node.chainman)->ActiveChain(); | const CChain &active = Assert(m_node.chainman)->ActiveChain(); | ||||
assert(std::addressof(g_chainman) == | |||||
std::addressof(*m_node.chainman)); | |||||
return FillBlock(m_node.chainman->m_blockman.LookupBlockIndex(hash), | return FillBlock(m_node.chainman->m_blockman.LookupBlockIndex(hash), | ||||
block, lock, active); | block, lock, active); | ||||
} | } | ||||
bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, | bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, | ||||
const FoundBlock &block) override { | const FoundBlock &block) override { | ||||
WAIT_LOCK(cs_main, lock); | WAIT_LOCK(cs_main, lock); | ||||
const CChain &active = Assert(m_node.chainman)->ActiveChain(); | const CChain &active = Assert(m_node.chainman)->ActiveChain(); | ||||
return FillBlock( | return FillBlock( | ||||
ChainActive().FindEarliestAtLeast(min_time, min_height), block, | ChainActive().FindEarliestAtLeast(min_time, min_height), block, | ||||
lock, active); | lock, active); | ||||
} | } | ||||
bool findAncestorByHeight(const BlockHash &block_hash, | bool findAncestorByHeight(const BlockHash &block_hash, | ||||
int ancestor_height, | int ancestor_height, | ||||
const FoundBlock &ancestor_out) override { | const FoundBlock &ancestor_out) override { | ||||
WAIT_LOCK(cs_main, lock); | WAIT_LOCK(cs_main, lock); | ||||
const CChain &active = Assert(m_node.chainman)->ActiveChain(); | const CChain &active = Assert(m_node.chainman)->ActiveChain(); | ||||
assert(std::addressof(g_chainman) == | |||||
std::addressof(*m_node.chainman)); | |||||
if (const CBlockIndex *block = | if (const CBlockIndex *block = | ||||
m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) { | m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) { | ||||
if (const CBlockIndex *ancestor = | if (const CBlockIndex *ancestor = | ||||
block->GetAncestor(ancestor_height)) { | block->GetAncestor(ancestor_height)) { | ||||
return FillBlock(ancestor, ancestor_out, lock, active); | return FillBlock(ancestor, ancestor_out, lock, active); | ||||
} | } | ||||
} | } | ||||
return FillBlock(nullptr, ancestor_out, lock, active); | return FillBlock(nullptr, ancestor_out, lock, active); | ||||
} | } | ||||
bool findAncestorByHash(const BlockHash &block_hash, | bool findAncestorByHash(const BlockHash &block_hash, | ||||
const BlockHash &ancestor_hash, | const BlockHash &ancestor_hash, | ||||
const FoundBlock &ancestor_out) override { | const FoundBlock &ancestor_out) override { | ||||
WAIT_LOCK(cs_main, lock); | WAIT_LOCK(cs_main, lock); | ||||
const CChain &active = Assert(m_node.chainman)->ActiveChain(); | const CChain &active = Assert(m_node.chainman)->ActiveChain(); | ||||
assert(std::addressof(g_chainman) == | |||||
std::addressof(*m_node.chainman)); | |||||
const CBlockIndex *block = | const CBlockIndex *block = | ||||
m_node.chainman->m_blockman.LookupBlockIndex(block_hash); | m_node.chainman->m_blockman.LookupBlockIndex(block_hash); | ||||
const CBlockIndex *ancestor = | const CBlockIndex *ancestor = | ||||
m_node.chainman->m_blockman.LookupBlockIndex(ancestor_hash); | m_node.chainman->m_blockman.LookupBlockIndex(ancestor_hash); | ||||
if (block && ancestor && | if (block && ancestor && | ||||
block->GetAncestor(ancestor->nHeight) != ancestor) { | block->GetAncestor(ancestor->nHeight) != ancestor) { | ||||
ancestor = nullptr; | ancestor = nullptr; | ||||
} | } | ||||
return FillBlock(ancestor, ancestor_out, lock, active); | return FillBlock(ancestor, ancestor_out, lock, active); | ||||
} | } | ||||
bool findCommonAncestor(const BlockHash &block_hash1, | bool findCommonAncestor(const BlockHash &block_hash1, | ||||
const BlockHash &block_hash2, | const BlockHash &block_hash2, | ||||
const FoundBlock &ancestor_out, | const FoundBlock &ancestor_out, | ||||
const FoundBlock &block1_out, | const FoundBlock &block1_out, | ||||
const FoundBlock &block2_out) override { | const FoundBlock &block2_out) override { | ||||
WAIT_LOCK(cs_main, lock); | WAIT_LOCK(cs_main, lock); | ||||
const CChain &active = Assert(m_node.chainman)->ActiveChain(); | const CChain &active = Assert(m_node.chainman)->ActiveChain(); | ||||
assert(std::addressof(g_chainman) == | |||||
std::addressof(*m_node.chainman)); | |||||
const CBlockIndex *block1 = | const CBlockIndex *block1 = | ||||
m_node.chainman->m_blockman.LookupBlockIndex(block_hash1); | m_node.chainman->m_blockman.LookupBlockIndex(block_hash1); | ||||
const CBlockIndex *block2 = | const CBlockIndex *block2 = | ||||
m_node.chainman->m_blockman.LookupBlockIndex(block_hash2); | m_node.chainman->m_blockman.LookupBlockIndex(block_hash2); | ||||
const CBlockIndex *ancestor = | const CBlockIndex *ancestor = | ||||
block1 && block2 ? LastCommonAncestor(block1, block2) : nullptr; | block1 && block2 ? LastCommonAncestor(block1, block2) : nullptr; | ||||
// Using & instead of && below to avoid short circuiting and leaving | // Using & instead of && below to avoid short circuiting and leaving | ||||
// output uninitialized. Cast bool to int to avoid | // output uninitialized. Cast bool to int to avoid | ||||
// -Wbitwise-instead-of-logical compiler warnings. | // -Wbitwise-instead-of-logical compiler warnings. | ||||
return int{FillBlock(ancestor, ancestor_out, lock, active)} & | return int{FillBlock(ancestor, ancestor_out, lock, active)} & | ||||
int{FillBlock(block1, block1_out, lock, active)} & | int{FillBlock(block1, block1_out, lock, active)} & | ||||
int{FillBlock(block2, block2_out, lock, active)}; | int{FillBlock(block2, block2_out, lock, active)}; | ||||
} | } | ||||
void findCoins(std::map<COutPoint, Coin> &coins) override { | void findCoins(std::map<COutPoint, Coin> &coins) override { | ||||
return FindCoins(m_node, coins); | return FindCoins(m_node, coins); | ||||
} | } | ||||
double guessVerificationProgress(const BlockHash &block_hash) override { | double guessVerificationProgress(const BlockHash &block_hash) override { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
assert(std::addressof(g_chainman.m_blockman) == | |||||
std::addressof(chainman().m_blockman)); | |||||
return GuessVerificationProgress( | return GuessVerificationProgress( | ||||
Params().TxData(), | Params().TxData(), | ||||
chainman().m_blockman.LookupBlockIndex(block_hash)); | chainman().m_blockman.LookupBlockIndex(block_hash)); | ||||
} | } | ||||
bool hasBlocks(const BlockHash &block_hash, int min_height, | bool hasBlocks(const BlockHash &block_hash, int min_height, | ||||
std::optional<int> max_height) override { | std::optional<int> max_height) override { | ||||
// hasBlocks returns true if all ancestors of block_hash in | // hasBlocks returns true if all ancestors of block_hash in | ||||
// specified range have block data (are not pruned), false if any | // specified range have block data (are not pruned), false if any | ||||
// ancestors in specified range are missing data. | // ancestors in specified range are missing data. | ||||
// | // | ||||
// For simplicity and robustness, min_height and max_height are only | // For simplicity and robustness, min_height and max_height are only | ||||
// used to limit the range, and passing min_height that's too low or | // 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. | // max_height that's too high will not crash or change the result. | ||||
LOCK(::cs_main); | LOCK(::cs_main); | ||||
assert(std::addressof(g_chainman.m_blockman) == | |||||
std::addressof(chainman().m_blockman)); | |||||
if (CBlockIndex *block = | if (CBlockIndex *block = | ||||
chainman().m_blockman.LookupBlockIndex(block_hash)) { | chainman().m_blockman.LookupBlockIndex(block_hash)) { | ||||
if (max_height && block->nHeight >= *max_height) { | if (max_height && block->nHeight >= *max_height) { | ||||
block = block->GetAncestor(*max_height); | block = block->GetAncestor(*max_height); | ||||
} | } | ||||
for (; block->nStatus.hasData(); block = block->pprev) { | for (; block->nStatus.hasData(); block = block->pprev) { | ||||
// Check pprev to not segfault if min_height is too low | // Check pprev to not segfault if min_height is too low | ||||
if (block->nHeight <= min_height || !block->pprev) { | if (block->nHeight <= min_height || !block->pprev) { | ||||
▲ Show 20 Lines • Show All 178 Lines • Show Last 20 Lines |