| 283 | } |
| 284 | |
| 285 | void BaseIndex::ChainStateFlushed(const CBlockLocator& locator) |
| 286 | { |
| 287 | if (!m_synced) { |
| 288 | return; |
| 289 | } |
| 290 | |
| 291 | const uint256& locator_tip_hash = locator.vHave.front(); |
| 292 | const CBlockIndex* locator_tip_index; |
| 293 | { |
| 294 | LOCK(cs_main); |
| 295 | locator_tip_index = m_chainstate->m_blockman.LookupBlockIndex(locator_tip_hash); |
| 296 | } |
| 297 | |
| 298 | if (!locator_tip_index) { |
| 299 | FatalError("%s: First block (hash=%s) in locator was not found", |
| 300 | __func__, locator_tip_hash.ToString()); |
| 301 | return; |
| 302 | } |
| 303 | |
| 304 | // This checks that ChainStateFlushed callbacks are received after BlockConnected. The check may fail |
| 305 | // immediately after the sync thread catches up and sets m_synced. Consider the case where |
| 306 | // there is a reorg and the blocks on the stale branch are in the ValidationInterface queue |
| 307 | // backlog even after the sync thread has caught up to the new chain tip. In this unlikely |
| 308 | // event, log a warning and let the queue clear. |
| 309 | const CBlockIndex* best_block_index = m_best_block_index.load(); |
| 310 | if (best_block_index->GetAncestor(locator_tip_index->nHeight) != locator_tip_index) { |
| 311 | LogPrintf("%s: WARNING: Locator contains block (hash=%s) not on known best " /* Continued */ |
| 312 | "chain (tip=%s); not writing index locator\n", |
| 313 | __func__, locator_tip_hash.ToString(), |
| 314 | best_block_index->GetBlockHash().ToString()); |
| 315 | return; |
| 316 | } |
| 317 | |
| 318 | // No need to handle errors in Commit. If it fails, the error will be already be logged. The |
| 319 | // best way to recover is to continue, as index cannot be corrupted by a missed commit to disk |
| 320 | // for an advanced index state. |
| 321 | Commit(); |
| 322 | } |
| 323 | |
| 324 | bool BaseIndex::BlockUntilSyncedToCurrentChain() const |
| 325 | { |
no test coverage detected