When people ask us for headers we do not have (over REST or RPC), do something reasonable.

This commit is contained in:
Glenn Willen 2022-11-09 22:40:20 -08:00
parent 4f0da3ce3d
commit f5c79950a1
4 changed files with 62 additions and 11 deletions

View file

@ -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<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start)
{
FlatFilePos hpos = pos;

View file

@ -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<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start);
bool ReadRawBlockFromDisk(std::vector<uint8_t>& 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);

View file

@ -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");

View file

@ -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", "<trimmed>");
result.pushKV("signblock_witness_hex", "<trimmed>");
result.pushKV("signblock_challenge", "<trimmed>");
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", "<trimmed>");
result.pushKV("dynamic_parameters", "<trimmed>");
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;
}