| 525 | } |
| 526 | |
| 527 | bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex) |
| 528 | { |
| 529 | const FlatFilePos pos{WITH_LOCK(::cs_main, return pindex->GetUndoPos())}; |
| 530 | |
| 531 | if (pos.IsNull()) { |
| 532 | return error("%s: no undo data available", __func__); |
| 533 | } |
| 534 | |
| 535 | // Open history file to read |
| 536 | CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION); |
| 537 | if (filein.IsNull()) { |
| 538 | return error("%s: OpenUndoFile failed", __func__); |
| 539 | } |
| 540 | |
| 541 | // Read block |
| 542 | uint256 hashChecksum; |
| 543 | CHashVerifier<CAutoFile> verifier(&filein); // We need a CHashVerifier as reserializing may lose data |
| 544 | try { |
| 545 | verifier << pindex->pprev->GetBlockHash(); |
| 546 | verifier >> blockundo; |
| 547 | filein >> hashChecksum; |
| 548 | } catch (const std::exception& e) { |
| 549 | return error("%s: Deserialize or I/O error - %s", __func__, e.what()); |
| 550 | } |
| 551 | |
| 552 | // Verify checksum |
| 553 | if (hashChecksum != verifier.GetHash()) { |
| 554 | return error("%s: Checksum mismatch", __func__); |
| 555 | } |
| 556 | |
| 557 | return true; |
| 558 | } |
| 559 | |
| 560 | void BlockManager::FlushUndoFile(int block_file, bool finalize) |
| 561 | { |