Skip to content

Commit f5c7995

Browse files
committed
When people ask us for headers we do not have (over REST or RPC), do something reasonable.
1 parent 4f0da3c commit f5c7995

File tree

4 files changed

+62
-11
lines changed

4 files changed

+62
-11
lines changed

src/node/blockstorage.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,17 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus
412412
return true;
413413
}
414414

415+
bool ReadBlockHeaderFromDisk(CBlockHeader& header, const CBlockIndex* pindex, const Consensus::Params& consensusParams)
416+
{
417+
// Not very efficient: read a block and throw away all but the header.
418+
CBlock tmp;
419+
if (!ReadBlockFromDisk(tmp, pindex, consensusParams)) {
420+
return false;
421+
}
422+
header = tmp.GetBlockHeader();
423+
return true;
424+
}
425+
415426
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start)
416427
{
417428
FlatFilePos hpos = pos;

src/node/blockstorage.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ extern bool fTrimHeaders;
4949
/** Minimum number of full untrimmed headers to keep, for blocks we have. */
5050
extern uint64_t nMustKeepFullHeaders;
5151
/** Target number of headers to download beyond the blocks we have. */
52-
// XXX: this currently only operates when in header trim mode, but it's really independent of that.
52+
// NOTE: this currently only operates when in header trim mode, but it's really independent of that.
5353
extern uint64_t nHeaderDownloadBuffer;
5454

5555
//! 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
7878
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams);
7979
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start);
8080
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CBlockIndex* pindex, const CMessageHeader::MessageStartChars& message_start);
81+
// ELEMENTS:
82+
bool ReadBlockHeaderFromDisk(class CBlockHeader& header, const CBlockIndex* pindex, const Consensus::Params& consensusParams);
8183

8284
bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex);
8385
bool WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValidationState& state, CBlockIndex* pindex, const CChainParams& chainparams);

src/rest.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,14 @@ static bool rest_headers(const std::any& context,
221221
case RetFormat::BINARY: {
222222
CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION);
223223
for (const CBlockIndex *pindex : headers) {
224-
ssHeader << pindex->GetBlockHeader();
224+
if (pindex->trimmed()) {
225+
CBlockHeader tmp;
226+
ReadBlockHeaderFromDisk(tmp, pindex, Params().GetConsensus());
227+
ssHeader << tmp;
228+
229+
} else {
230+
ssHeader << pindex->GetBlockHeader();
231+
}
225232
}
226233

227234
std::string binaryHeader = ssHeader.str();
@@ -233,8 +240,14 @@ static bool rest_headers(const std::any& context,
233240
case RetFormat::HEX: {
234241
CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION);
235242
for (const CBlockIndex *pindex : headers) {
236-
ssHeader << pindex->GetBlockHeader();
237-
}
243+
if (pindex->trimmed()) {
244+
CBlockHeader tmp;
245+
ReadBlockHeaderFromDisk(tmp, pindex, Params().GetConsensus());
246+
ssHeader << tmp;
247+
248+
} else {
249+
ssHeader << pindex->GetBlockHeader();
250+
} }
238251

239252
std::string strHex = HexStr(ssHeader) + "\n";
240253
req->WriteHeader("Content-Type", "text/plain");

src/rpc/blockchain.cpp

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -249,12 +249,25 @@ UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex
249249
result.pushKV("chainwork", blockindex->nChainWork.GetHex());
250250
} else {
251251
if (blockindex->dynafed_params().IsNull()) {
252-
result.pushKV("signblock_witness_asm", ScriptToAsmStr(blockindex->get_proof().solution));
253-
result.pushKV("signblock_witness_hex", HexStr(blockindex->get_proof().solution));
254-
result.pushKV("signblock_challenge", HexStr(blockindex->get_proof().challenge));
252+
if (blockindex->trimmed()) {
253+
result.pushKV("signblock_witness_asm", "<trimmed>");
254+
result.pushKV("signblock_witness_hex", "<trimmed>");
255+
result.pushKV("signblock_challenge", "<trimmed>");
256+
result.pushKV("warning", "Fields missing due to -trim_headers flag.");
257+
} else {
258+
result.pushKV("signblock_witness_asm", ScriptToAsmStr(blockindex->get_proof().solution));
259+
result.pushKV("signblock_witness_hex", HexStr(blockindex->get_proof().solution));
260+
result.pushKV("signblock_challenge", HexStr(blockindex->get_proof().challenge));
261+
}
255262
} else {
256-
result.pushKV("signblock_witness_hex", EncodeHexScriptWitness(blockindex->signblock_witness()));
257-
result.pushKV("dynamic_parameters", dynaParamsToJSON(blockindex->dynafed_params()));
263+
if (blockindex->trimmed()) {
264+
result.pushKV("signblock_witness_hex", "<trimmed>");
265+
result.pushKV("dynamic_parameters", "<trimmed>");
266+
result.pushKV("warning", "Fields missing due to -trim_headers flag.");
267+
} else {
268+
result.pushKV("signblock_witness_hex", EncodeHexScriptWitness(blockindex->signblock_witness()));
269+
result.pushKV("dynamic_parameters", dynaParamsToJSON(blockindex->dynafed_params()));
270+
}
258271
}
259272
}
260273
result.pushKV("nTx", (uint64_t)blockindex->nTx);
@@ -267,7 +280,13 @@ UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex
267280

268281
UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, bool txDetails)
269282
{
270-
UniValue result = blockheaderToJSON(tip, blockindex);
283+
UniValue result;
284+
if (blockindex->trimmed()) {
285+
CBlockIndex tmp = CBlockIndex(block.GetBlockHeader()); // XXX: lifetimes?
286+
result = blockheaderToJSON(tip, &tmp);
287+
} else {
288+
result = blockheaderToJSON(tip, blockindex);
289+
}
271290

272291
result.pushKV("strippedsize", (int)::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS));
273292
result.pushKV("size", (int)::GetSerializeSize(block, PROTOCOL_VERSION));
@@ -969,7 +988,13 @@ static RPCHelpMan getblockheader()
969988
if (!fVerbose)
970989
{
971990
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
972-
ssBlock << pblockindex->GetBlockHeader();
991+
if (pblockindex->trimmed()) {
992+
CBlockHeader tmp;
993+
ReadBlockHeaderFromDisk(tmp, pblockindex, Params().GetConsensus());
994+
ssBlock << tmp;
995+
} else {
996+
ssBlock << pblockindex->GetBlockHeader();
997+
}
973998
std::string strHex = HexStr(ssBlock);
974999
return strHex;
9751000
}

0 commit comments

Comments
 (0)