diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2018-05-02 14:10:27 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2018-05-15 08:11:56 +0200 |
commit | 0bf431870e45d8e20c4671e51a782ebf97b75fac (patch) | |
tree | 44e2e163ef3cffeb6af12a93293a964328b7a9dc /src/validation.cpp | |
parent | 598db389c33e5e90783ef1223df2eeab095ed622 (diff) | |
download | bitcoin-0bf431870e45d8e20c4671e51a782ebf97b75fac.tar.xz |
net: Serve blocks directly from disk when possible
In `ProcessGetBlockData`, send the block data directly from disk if
type MSG_WITNESS_BLOCK is requested. This is a valid shortcut as the
on-disk format matches the network format.
This is expected to increase performance because a deserialization and
subsequent serialization roundtrip is avoided.
Diffstat (limited to 'src/validation.cpp')
-rw-r--r-- | src/validation.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/validation.cpp b/src/validation.cpp index 1b9e982753..69a201d988 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1125,6 +1125,52 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus return true; } +bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& message_start) +{ + CDiskBlockPos hpos = pos; + hpos.nPos -= 8; // Seek back 8 bytes for meta header + CAutoFile filein(OpenBlockFile(hpos, true), SER_DISK, CLIENT_VERSION); + if (filein.IsNull()) { + return error("%s: OpenBlockFile failed for %s", __func__, pos.ToString()); + } + + try { + CMessageHeader::MessageStartChars blk_start; + unsigned int blk_size; + + filein >> blk_start >> blk_size; + + if (memcmp(blk_start, message_start, CMessageHeader::MESSAGE_START_SIZE)) { + return error("%s: Block magic mismatch for %s: %s versus expected %s", __func__, pos.ToString(), + HexStr(blk_start, blk_start + CMessageHeader::MESSAGE_START_SIZE), + HexStr(message_start, message_start + CMessageHeader::MESSAGE_START_SIZE)); + } + + if (blk_size > MAX_SIZE) { + return error("%s: Block data is larger than maximum deserialization size for %s: %s versus %s", __func__, pos.ToString(), + blk_size, MAX_SIZE); + } + + block.resize(blk_size); // Zeroing of memory is intentional here + filein.read((char*)block.data(), blk_size); + } catch(const std::exception& e) { + return error("%s: Read from block file failed: %s for %s", __func__, e.what(), pos.ToString()); + } + + return true; +} + +bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CBlockIndex* pindex, const CMessageHeader::MessageStartChars& message_start) +{ + CDiskBlockPos block_pos; + { + LOCK(cs_main); + block_pos = pindex->GetBlockPos(); + } + + return ReadRawBlockFromDisk(block, block_pos, message_start); +} + CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams) { int halvings = nHeight / consensusParams.nSubsidyHalvingInterval; |