From f5c79950a1d32082341ee0cd8982de42903403fa Mon Sep 17 00:00:00 2001 From: Glenn Willen Date: Wed, 9 Nov 2022 22:40:20 -0800 Subject: [PATCH] When people ask us for headers we do not have (over REST or RPC), do something reasonable. --- src/node/blockstorage.cpp | 11 +++++++++++ src/node/blockstorage.h | 4 +++- src/rest.cpp | 19 ++++++++++++++++--- src/rpc/blockchain.cpp | 39 ++++++++++++++++++++++++++++++++------- 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp index b014785a67..5a2744d553 100644 --- a/src/node/blockstorage.cpp +++ b/src/node/blockstorage.cpp @@ -412,6 +412,17 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus return true; } +bool ReadBlockHeaderFromDisk(CBlockHeader& header, const CBlockIndex* pindex, const Consensus::Params& consensusParams) +{ + // Not very efficient: read a block and throw away all but the header. + CBlock tmp; + if (!ReadBlockFromDisk(tmp, pindex, consensusParams)) { + return false; + } + header = tmp.GetBlockHeader(); + return true; +} + bool ReadRawBlockFromDisk(std::vector& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start) { FlatFilePos hpos = pos; diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h index 07c13052b3..df582b06d1 100644 --- a/src/node/blockstorage.h +++ b/src/node/blockstorage.h @@ -49,7 +49,7 @@ extern bool fTrimHeaders; /** Minimum number of full untrimmed headers to keep, for blocks we have. */ extern uint64_t nMustKeepFullHeaders; /** Target number of headers to download beyond the blocks we have. */ -// XXX: this currently only operates when in header trim mode, but it's really independent of that. +// NOTE: this currently only operates when in header trim mode, but it's really independent of that. extern uint64_t nHeaderDownloadBuffer; //! Check whether the block associated with this index entry is pruned or not. @@ -78,6 +78,8 @@ bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::P bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams); bool ReadRawBlockFromDisk(std::vector& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start); bool ReadRawBlockFromDisk(std::vector& block, const CBlockIndex* pindex, const CMessageHeader::MessageStartChars& message_start); +// ELEMENTS: +bool ReadBlockHeaderFromDisk(class CBlockHeader& header, const CBlockIndex* pindex, const Consensus::Params& consensusParams); bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex); bool WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValidationState& state, CBlockIndex* pindex, const CChainParams& chainparams); diff --git a/src/rest.cpp b/src/rest.cpp index 7453e966db..65888f95a0 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -221,7 +221,14 @@ static bool rest_headers(const std::any& context, case RetFormat::BINARY: { CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION); for (const CBlockIndex *pindex : headers) { - ssHeader << pindex->GetBlockHeader(); + if (pindex->trimmed()) { + CBlockHeader tmp; + ReadBlockHeaderFromDisk(tmp, pindex, Params().GetConsensus()); + ssHeader << tmp; + + } else { + ssHeader << pindex->GetBlockHeader(); + } } std::string binaryHeader = ssHeader.str(); @@ -233,8 +240,14 @@ static bool rest_headers(const std::any& context, case RetFormat::HEX: { CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION); for (const CBlockIndex *pindex : headers) { - ssHeader << pindex->GetBlockHeader(); - } + if (pindex->trimmed()) { + CBlockHeader tmp; + ReadBlockHeaderFromDisk(tmp, pindex, Params().GetConsensus()); + ssHeader << tmp; + + } else { + ssHeader << pindex->GetBlockHeader(); + } } std::string strHex = HexStr(ssHeader) + "\n"; req->WriteHeader("Content-Type", "text/plain"); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 6db3520170..d99af28807 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -249,12 +249,25 @@ UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex result.pushKV("chainwork", blockindex->nChainWork.GetHex()); } else { if (blockindex->dynafed_params().IsNull()) { - result.pushKV("signblock_witness_asm", ScriptToAsmStr(blockindex->get_proof().solution)); - result.pushKV("signblock_witness_hex", HexStr(blockindex->get_proof().solution)); - result.pushKV("signblock_challenge", HexStr(blockindex->get_proof().challenge)); + if (blockindex->trimmed()) { + result.pushKV("signblock_witness_asm", ""); + result.pushKV("signblock_witness_hex", ""); + result.pushKV("signblock_challenge", ""); + result.pushKV("warning", "Fields missing due to -trim_headers flag."); + } else { + result.pushKV("signblock_witness_asm", ScriptToAsmStr(blockindex->get_proof().solution)); + result.pushKV("signblock_witness_hex", HexStr(blockindex->get_proof().solution)); + result.pushKV("signblock_challenge", HexStr(blockindex->get_proof().challenge)); + } } else { - result.pushKV("signblock_witness_hex", EncodeHexScriptWitness(blockindex->signblock_witness())); - result.pushKV("dynamic_parameters", dynaParamsToJSON(blockindex->dynafed_params())); + if (blockindex->trimmed()) { + result.pushKV("signblock_witness_hex", ""); + result.pushKV("dynamic_parameters", ""); + result.pushKV("warning", "Fields missing due to -trim_headers flag."); + } else { + result.pushKV("signblock_witness_hex", EncodeHexScriptWitness(blockindex->signblock_witness())); + result.pushKV("dynamic_parameters", dynaParamsToJSON(blockindex->dynafed_params())); + } } } result.pushKV("nTx", (uint64_t)blockindex->nTx); @@ -267,7 +280,13 @@ UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, bool txDetails) { - UniValue result = blockheaderToJSON(tip, blockindex); + UniValue result; + if (blockindex->trimmed()) { + CBlockIndex tmp = CBlockIndex(block.GetBlockHeader()); // XXX: lifetimes? + result = blockheaderToJSON(tip, &tmp); + } else { + result = blockheaderToJSON(tip, blockindex); + } result.pushKV("strippedsize", (int)::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)); result.pushKV("size", (int)::GetSerializeSize(block, PROTOCOL_VERSION)); @@ -969,7 +988,13 @@ static RPCHelpMan getblockheader() if (!fVerbose) { CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); - ssBlock << pblockindex->GetBlockHeader(); + if (pblockindex->trimmed()) { + CBlockHeader tmp; + ReadBlockHeaderFromDisk(tmp, pblockindex, Params().GetConsensus()); + ssBlock << tmp; + } else { + ssBlock << pblockindex->GetBlockHeader(); + } std::string strHex = HexStr(ssBlock); return strHex; }