| 188 | } |
| 189 | |
| 190 | void BaseIndex::ChainStateFlushed(const CBlockLocator& locator) |
| 191 | { |
| 192 | if (!m_synced) { |
| 193 | return; |
| 194 | } |
| 195 | |
| 196 | const uint256& locator_tip_hash = locator.vHave.front(); |
| 197 | const CBlockIndex* locator_tip_index; |
| 198 | { |
| 199 | LOCK(cs_main); |
| 200 | locator_tip_index = LookupBlockIndex(locator_tip_hash); |
| 201 | } |
| 202 | |
| 203 | if (!locator_tip_index) { |
| 204 | FatalError("%s: First block (hash=%s) in locator was not found", |
| 205 | __func__, locator_tip_hash.ToString()); |
| 206 | return; |
| 207 | } |
| 208 | |
| 209 | // This checks that ChainStateFlushed callbacks are received after BlockConnected. The check may fail |
| 210 | // immediately after the sync thread catches up and sets m_synced. Consider the case where |
| 211 | // there is a reorg and the blocks on the stale branch are in the ValidationInterface queue |
| 212 | // backlog even after the sync thread has caught up to the new chain tip. In this unlikely |
| 213 | // event, log a warning and let the queue clear. |
| 214 | const CBlockIndex* best_block_index = m_best_block_index.load(); |
| 215 | if (best_block_index->GetAncestor(locator_tip_index->nHeight) != locator_tip_index) { |
| 216 | LogPrintf("%s: WARNING: Locator contains block (hash=%s) not on known best " /* Continued */ |
| 217 | "chain (tip=%s); not writing index locator\n", |
| 218 | __func__, locator_tip_hash.ToString(), |
| 219 | best_block_index->GetBlockHash().ToString()); |
| 220 | return; |
| 221 | } |
| 222 | |
| 223 | if (!GetDB().WriteBestBlock(locator)) { |
| 224 | error("%s: Failed to write locator to disk", __func__); |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | bool BaseIndex::BlockUntilSyncedToCurrentChain() |
| 229 | { |
no test coverage detected