| 150 | } |
| 151 | |
| 152 | void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex, |
| 153 | const std::vector<CTransactionRef>& txn_conflicted) |
| 154 | { |
| 155 | if (!m_synced) { |
| 156 | return; |
| 157 | } |
| 158 | |
| 159 | const CBlockIndex* best_block_index = m_best_block_index.load(); |
| 160 | if (!best_block_index) { |
| 161 | if (pindex->nHeight != 0) { |
| 162 | FatalError("%s: First block connected is not the genesis block (height=%d)", |
| 163 | __func__, pindex->nHeight); |
| 164 | return; |
| 165 | } |
| 166 | } else { |
| 167 | // Ensure block connects to an ancestor of the current best block. This should be the case |
| 168 | // most of the time, but may not be immediately after the sync thread catches up and sets |
| 169 | // m_synced. Consider the case where there is a reorg and the blocks on the stale branch are |
| 170 | // in the ValidationInterface queue backlog even after the sync thread has caught up to the |
| 171 | // new chain tip. In this unlikely event, log a warning and let the queue clear. |
| 172 | if (best_block_index->GetAncestor(pindex->nHeight - 1) != pindex->pprev) { |
| 173 | LogPrintf("%s: WARNING: Block %s does not connect to an ancestor of " /* Continued */ |
| 174 | "known best chain (tip=%s); not updating index\n", |
| 175 | __func__, pindex->GetBlockHash().ToString(), |
| 176 | best_block_index->GetBlockHash().ToString()); |
| 177 | return; |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | if (WriteBlock(*block, pindex)) { |
| 182 | m_best_block_index = pindex; |
| 183 | } else { |
| 184 | FatalError("%s: Failed to write block %s to index", |
| 185 | __func__, pindex->GetBlockHash().ToString()); |
| 186 | return; |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | void BaseIndex::ChainStateFlushed(const CBlockLocator& locator) |
| 191 | { |
nothing calls this directly
no test coverage detected