mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-24 18:23:26 -03:00
optimization: Bulk serialization writes in SaveBlockUndo
and SaveBlock
Similarly to the serialization reads, buffered writes will enable batched xor calculations - especially since currently we need to copy the write inputs Span to do the obfuscation on it, batching enables doing the xor on the internal buffer instead. Before: | ns/op | op/s | err% | total | benchmark |--------------------:|--------------------:|--------:|----------:|:---------- | 5,244,636.51 | 190.67 | 0.3% | 11.04 | `SaveBlockToDiskBench` After: | ns/op | op/s | err% | total | benchmark |--------------------:|--------------------:|--------:|----------:|:---------- | 1,787,371.46 | 559.48 | 1.6% | 11.16 | `SaveBlockToDiskBench` Co-authored-by: Cory Fields <cory-nospam-@coryfields.com>
This commit is contained in:
parent
34eafa54a6
commit
1f736fbdb4
1 changed files with 36 additions and 16 deletions
|
@ -951,31 +951,38 @@ bool BlockManager::SaveBlockUndo(const CBlockUndo& blockundo, BlockValidationSta
|
|||
const BlockfileType type = BlockfileTypeForHeight(block.nHeight);
|
||||
auto& cursor = *Assert(WITH_LOCK(cs_LastBlockFile, return m_blockfile_cursors[type]));
|
||||
|
||||
// Write undo information to disk
|
||||
if (block.GetUndoPos().IsNull()) {
|
||||
FlatFilePos pos;
|
||||
const uint32_t blockundo_size{static_cast<uint32_t>(GetSerializeSize(blockundo))};
|
||||
if (!FindUndoPos(state, block.nFile, pos, blockundo_size + UNDO_DATA_DISK_OVERHEAD)) {
|
||||
if (!FindUndoPos(state, block.nFile, pos, UNDO_DATA_DISK_OVERHEAD + blockundo_size)) {
|
||||
LogError("%s: FindUndoPos failed\n", __func__);
|
||||
return false;
|
||||
}
|
||||
// Open history file to append
|
||||
AutoFile fileout{OpenUndoFile(pos)};
|
||||
AutoFile fileout{m_undo_file_seq.Open(pos, false), {}}; // We'll obfuscate ourselves
|
||||
if (fileout.IsNull()) {
|
||||
LogError("%s: OpenUndoFile failed\n", __func__);
|
||||
return FatalError(m_opts.notifications, state, _("Failed to write undo data."));
|
||||
}
|
||||
|
||||
// Write index header
|
||||
fileout << GetParams().MessageStart() << blockundo_size;
|
||||
{
|
||||
DataStream header;
|
||||
header.reserve(BLOCK_SERIALIZATION_HEADER_SIZE);
|
||||
header << GetParams().MessageStart() << blockundo_size;
|
||||
util::Xor(header, m_xor_key, pos.nPos);
|
||||
fileout.write(header);
|
||||
}
|
||||
pos.nPos += BLOCK_SERIALIZATION_HEADER_SIZE;
|
||||
fileout << blockundo;
|
||||
{
|
||||
HashWriter hasher;
|
||||
hasher << block.pprev->GetBlockHash();
|
||||
hasher << blockundo;
|
||||
|
||||
// calculate & write checksum
|
||||
HashWriter hasher{};
|
||||
hasher << block.pprev->GetBlockHash();
|
||||
hasher << blockundo;
|
||||
fileout << hasher.GetHash();
|
||||
DataStream undo_data;
|
||||
undo_data.reserve(blockundo_size + sizeof(uint256));
|
||||
undo_data << blockundo << hasher.GetHash();
|
||||
util::Xor(undo_data, m_xor_key, pos.nPos);
|
||||
fileout.write(undo_data);
|
||||
}
|
||||
|
||||
// rev files are written in block height order, whereas blk files are written as blocks come in (often out of order)
|
||||
// we want to flush the rev (undo) file once we've written the last block, which is indicated by the last height
|
||||
|
@ -1105,21 +1112,34 @@ bool BlockManager::ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatF
|
|||
FlatFilePos BlockManager::SaveBlock(const CBlock& block, int nHeight)
|
||||
{
|
||||
const uint32_t block_size{static_cast<uint32_t>(GetSerializeSize(TX_WITH_WITNESS(block)))};
|
||||
FlatFilePos pos{FindNextBlockPos(block_size + BLOCK_SERIALIZATION_HEADER_SIZE, nHeight, block.GetBlockTime())};
|
||||
FlatFilePos pos{FindNextBlockPos(BLOCK_SERIALIZATION_HEADER_SIZE + block_size, nHeight, block.GetBlockTime())};
|
||||
if (pos.IsNull()) {
|
||||
LogError("%s: FindNextBlockPos failed\n", __func__);
|
||||
return FlatFilePos();
|
||||
}
|
||||
AutoFile fileout{OpenBlockFile(pos)};
|
||||
AutoFile fileout{m_block_file_seq.Open(pos, false), {}}; // We'll obfuscate ourselves
|
||||
if (fileout.IsNull()) {
|
||||
LogError("%s: OpenBlockFile failed\n", __func__);
|
||||
m_opts.notifications.fatalError(_("Failed to write block."));
|
||||
return FlatFilePos();
|
||||
}
|
||||
|
||||
fileout << GetParams().MessageStart() << block_size;
|
||||
{
|
||||
DataStream header;
|
||||
header.reserve(BLOCK_SERIALIZATION_HEADER_SIZE);
|
||||
header << GetParams().MessageStart() << block_size;
|
||||
util::Xor(header, m_xor_key, pos.nPos);
|
||||
fileout.write(header);
|
||||
}
|
||||
pos.nPos += BLOCK_SERIALIZATION_HEADER_SIZE;
|
||||
fileout << TX_WITH_WITNESS(block);
|
||||
{
|
||||
DataStream block_data;
|
||||
block_data.reserve(block_size);
|
||||
block_data << TX_WITH_WITNESS(block);
|
||||
util::Xor(block_data, m_xor_key, pos.nPos);
|
||||
fileout.write(block_data);
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue