MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / WriteBlockUndo

Method WriteBlockUndo

src/node/blockstorage.cpp:981–1048  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

979}
980
981bool BlockManager::WriteBlockUndo(const CBlockUndo& blockundo, BlockValidationState& state, CBlockIndex& block)
982{
983 AssertLockHeld(::cs_main);
984 const BlockfileType type = BlockfileTypeForHeight(block.nHeight);
985 auto& cursor = *Assert(m_blockfile_cursors[type]);
986
987 // Write undo information to disk
988 if (block.GetUndoPos().IsNull()) {
989 FlatFilePos pos;
990 const auto blockundo_size{static_cast<uint32_t>(GetSerializeSize(blockundo))};
991 if (!FindUndoPos(state, block.nFile, pos, blockundo_size + UNDO_DATA_DISK_OVERHEAD)) {
992 LogError("FindUndoPos failed for %s while writing block undo", pos.ToString());
993 return false;
994 }
995
996 // Open history file to append
997 AutoFile file{OpenUndoFile(pos)};
998 if (file.IsNull()) {
999 LogError("OpenUndoFile failed for %s while writing block undo", pos.ToString());
1000 return FatalError(m_opts.notifications, state, _("Failed to write undo data."));
1001 }
1002 {
1003 BufferedWriter fileout{file};
1004
1005 // Write index header
1006 fileout << GetParams().MessageStart() << blockundo_size;
1007 pos.nPos += STORAGE_HEADER_BYTES;
1008 {
1009 // Calculate checksum
1010 HashWriter hasher{};
1011 hasher << block.pprev->GetBlockHash() << blockundo;
1012 // Write undo data & checksum
1013 fileout << blockundo << hasher.GetHash();
1014 }
1015 // BufferedWriter will flush pending data to file when fileout goes out of scope.
1016 }
1017
1018 // Make sure that the file is closed before we call `FlushUndoFile`.
1019 if (file.fclose() != 0) {
1020 LogError("Failed to close block undo file %s: %s", pos.ToString(), SysErrorString(errno));
1021 return FatalError(m_opts.notifications, state, _("Failed to close block undo file."));
1022 }
1023
1024 // rev files are written in block height order, whereas blk files are written as blocks come in (often out of order)
1025 // we want to flush the rev (undo) file once we've written the last block, which is indicated by the last height
1026 // in the block file info as below; note that this does not catch the case where the undo writes are keeping up
1027 // with the block writes (usually when a synced up node is getting newly mined blocks) -- this case is caught in
1028 // the FindNextBlockPos function
1029 if (pos.nFile < cursor.file_num && static_cast<uint32_t>(block.nHeight) == m_blockfile_info[pos.nFile].nHeightLast) {
1030 // Do not propagate the return code, a failed flush here should not
1031 // be an indication for a failed write. If it were propagated here,
1032 // the caller would assume the undo data not to be written, when in
1033 // fact it is. Note though, that a failed flush might leave the data
1034 // file untrimmed.
1035 if (!FlushUndoFile(pos.nFile, true)) {
1036 LogWarning("Failed to flush undo file %05i\n", pos.nFile);
1037 }
1038 } else if (pos.nFile == cursor.file_num && block.nHeight > cursor.undo_height) {

Callers 1

ConnectBlockMethod · 0.80

Calls 10

GetSerializeSizeFunction · 0.85
FatalErrorFunction · 0.85
_Function · 0.85
SysErrorStringFunction · 0.85
fcloseMethod · 0.80
IsNullMethod · 0.45
ToStringMethod · 0.45
GetBlockHashMethod · 0.45
GetHashMethod · 0.45
insertMethod · 0.45

Tested by

no test coverage detected