From fe8e6dfc048817fdcbbd20f8ae508074a70228fe Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Wed, 9 Oct 2019 13:23:19 -0400 Subject: [PATCH 1/2] Break out finalizecomaptblock errors to be more helpful --- src/rpc/mining.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 143bfcef85..7a9971cbc7 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -1382,8 +1382,14 @@ UniValue finalizecompactblock(const JSONRPCRequest& request) const std::vector> dummy; std::shared_ptr pblock = std::make_shared(); - if (partialBlock.InitData(cmpctblock, dummy) != READ_STATUS_OK || partialBlock.FillBlock(*pblock, found, false /* pow_check*/) != READ_STATUS_OK) { + if (partialBlock.InitData(cmpctblock, dummy) != READ_STATUS_OK) { + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "compact_hex appears malformed."); + } + auto result = partialBlock.FillBlock(*pblock, found, false /* pow_check*/); + if (result == READ_STATUS_FAILED) { throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Failed to complete block though all transactions were apparently found. Could be random short ID collision; requires full block instead."); + } else if (result != READ_STATUS_OK) { + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Failed to complete block though all transactions were apparently found."); } CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); From d70cb068c4539968175469421fbbbb743caf361b Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Wed, 9 Oct 2019 16:36:16 -0400 Subject: [PATCH 2/2] Have compact block FillBlock give more verbose log printing when encountering failures. --- src/blockencodings.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index 4c95d730e6..1503afe78d 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -189,8 +189,10 @@ ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector< size_t tx_missing_offset = 0; for (size_t i = 0; i < txn_available.size(); i++) { if (!txn_available[i]) { - if (vtx_missing.size() <= tx_missing_offset) + if (vtx_missing.size() <= tx_missing_offset) { + LogPrint(BCLog::CMPCTBLOCK, "Transactions missing arg mismatches offset in loop: %zu %zu\n", vtx_missing.size(), tx_missing_offset); return READ_STATUS_INVALID; + } block.vtx[i] = vtx_missing[tx_missing_offset++]; } else block.vtx[i] = std::move(txn_available[i]); @@ -200,8 +202,10 @@ ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector< header.SetNull(); txn_available.clear(); - if (vtx_missing.size() != tx_missing_offset) + if (vtx_missing.size() != tx_missing_offset) { + LogPrint(BCLog::CMPCTBLOCK, "Transactions missing arg mismatches offset: %zu %zu\n", vtx_missing.size(), tx_missing_offset); return READ_STATUS_INVALID; + } CValidationState state; if (!CheckBlock(block, state, Params().GetConsensus(), check_pow)) { @@ -209,8 +213,12 @@ ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector< // but that is expensive, and CheckBlock caches a block's // "checked-status" (in the CBlock?). CBlock should be able to // check its own merkle root and cache that check. - if (state.CorruptionPossible()) + if (state.CorruptionPossible()) { + LogPrint(BCLog::CMPCTBLOCK, "Corrupted compact block? Possible shortid collision: %s\n", state.GetRejectReason()); return READ_STATUS_FAILED; // Possible Short ID collision + } + + LogPrint(BCLog::CMPCTBLOCK, "CheckBlock fail: %s\n", state.GetRejectReason()); return READ_STATUS_CHECKBLOCK_FAILED; }