Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
| 3773 | |
| 3774 | /** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */ |
| 3775 | void ChainstateManager::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos) |
| 3776 | { |
| 3777 | AssertLockHeld(cs_main); |
| 3778 | pindexNew->nTx = block.vtx.size(); |
| 3779 | // Typically m_chain_tx_count will be 0 at this point, but it can be nonzero if this |
| 3780 | // is a pruned block which is being downloaded again, or if this is an |
| 3781 | // assumeutxo snapshot block which has a hardcoded m_chain_tx_count value from the |
| 3782 | // snapshot metadata. If the pindex is not the snapshot block and the |
| 3783 | // m_chain_tx_count value is not zero, assert that value is actually correct. |
| 3784 | auto prev_tx_sum = [](CBlockIndex& block) { return block.nTx + (block.pprev ? block.pprev->m_chain_tx_count : 0); }; |
| 3785 | if (!Assume(pindexNew->m_chain_tx_count == 0 || pindexNew->m_chain_tx_count == prev_tx_sum(*pindexNew) || |
| 3786 | std::ranges::any_of(m_chainstates, [&](const auto& cs) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { return cs->SnapshotBase() == pindexNew; }))) { |
| 3787 | LogWarning("Internal bug detected: block %d has unexpected m_chain_tx_count %i that should be %i (%s %s). Please report this issue here: %s\n", |
| 3788 | pindexNew->nHeight, pindexNew->m_chain_tx_count, prev_tx_sum(*pindexNew), CLIENT_NAME, FormatFullVersion(), CLIENT_BUGREPORT); |
| 3789 | pindexNew->m_chain_tx_count = 0; |
| 3790 | } |
| 3791 | pindexNew->nFile = pos.nFile; |
| 3792 | pindexNew->nDataPos = pos.nPos; |
| 3793 | pindexNew->nUndoPos = 0; |
| 3794 | pindexNew->nStatus |= BLOCK_HAVE_DATA; |
| 3795 | if (DeploymentActiveAt(*pindexNew, *this, Consensus::DEPLOYMENT_SEGWIT)) { |
| 3796 | pindexNew->nStatus |= BLOCK_OPT_WITNESS; |
| 3797 | } |
| 3798 | pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS); |
| 3799 | m_blockman.m_dirty_blockindex.insert(pindexNew); |
| 3800 | |
| 3801 | if (pindexNew->pprev == nullptr || pindexNew->pprev->HaveNumChainTxs()) { |
| 3802 | // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS. |
| 3803 | std::deque<CBlockIndex*> queue; |
| 3804 | queue.push_back(pindexNew); |
| 3805 | |
| 3806 | // Recursively process any descendant blocks that now may be eligible to be connected. |
| 3807 | while (!queue.empty()) { |
| 3808 | CBlockIndex *pindex = queue.front(); |
| 3809 | queue.pop_front(); |
| 3810 | // Before setting m_chain_tx_count, assert that it is 0 or already set to |
| 3811 | // the correct value. This assert will fail after receiving the |
| 3812 | // assumeutxo snapshot block if assumeutxo snapshot metadata has an |
| 3813 | // incorrect hardcoded AssumeutxoData::m_chain_tx_count value. |
| 3814 | if (!Assume(pindex->m_chain_tx_count == 0 || pindex->m_chain_tx_count == prev_tx_sum(*pindex))) { |
| 3815 | LogWarning("Internal bug detected: block %d has unexpected m_chain_tx_count %i that should be %i (%s %s). Please report this issue here: %s\n", |
| 3816 | pindex->nHeight, pindex->m_chain_tx_count, prev_tx_sum(*pindex), CLIENT_NAME, FormatFullVersion(), CLIENT_BUGREPORT); |
| 3817 | } |
| 3818 | pindex->m_chain_tx_count = prev_tx_sum(*pindex); |
| 3819 | pindex->nSequenceId = nBlockSequenceId++; |
| 3820 | for (const auto& c : m_chainstates) { |
| 3821 | c->TryAddBlockIndexCandidate(pindex); |
| 3822 | } |
| 3823 | std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = m_blockman.m_blocks_unlinked.equal_range(pindex); |
| 3824 | while (range.first != range.second) { |
| 3825 | std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first; |
| 3826 | queue.push_back(it->second); |
| 3827 | range.first++; |
| 3828 | m_blockman.m_blocks_unlinked.erase(it); |
| 3829 | } |
| 3830 | } |
| 3831 | } else { |
| 3832 | if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) { |
no test coverage detected