Skip to content

Commit 431a548

Browse files
committed
Merge #10297: Simplify DisconnectBlock arguments/return value
db994b2 Simplify DisconnectBlock arguments/return value (Pieter Wuille) Tree-SHA512: 62ce1a85bde2a5baffb9173ed28f2d8008200ecf8b09332122f1516fe68b33b9d7223cc1c2fffe804e38f767874c6353b76bd483e8ad7d48c4a5e80d6b683039
2 parents 75171f0 + db994b2 commit 431a548

File tree

1 file changed

+33
-26
lines changed

1 file changed

+33
-26
lines changed

src/validation.cpp

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1523,28 +1523,36 @@ bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint
15231523
return fClean;
15241524
}
15251525

1526+
enum DisconnectResult
1527+
{
1528+
DISCONNECT_OK, // All good.
1529+
DISCONNECT_UNCLEAN, // Rolled back, but UTXO set was inconsistent with block.
1530+
DISCONNECT_FAILED // Something else went wrong.
1531+
};
1532+
15261533
/** Undo the effects of this block (with given index) on the UTXO set represented by coins.
1527-
* In case pfClean is provided, operation will try to be tolerant about errors, and *pfClean
1528-
* will be true if no problems were found. Otherwise, the return value will be false in case
1529-
* of problems. Note that in any case, coins may be modified. */
1530-
static bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean = NULL)
1534+
* When UNCLEAN or FAILED is returned, view is left in an indeterminate state. */
1535+
static DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view)
15311536
{
15321537
assert(pindex->GetBlockHash() == view.GetBestBlock());
15331538

1534-
if (pfClean)
1535-
*pfClean = false;
1536-
15371539
bool fClean = true;
15381540

15391541
CBlockUndo blockUndo;
15401542
CDiskBlockPos pos = pindex->GetUndoPos();
1541-
if (pos.IsNull())
1542-
return error("DisconnectBlock(): no undo data available");
1543-
if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash()))
1544-
return error("DisconnectBlock(): failure reading undo data");
1543+
if (pos.IsNull()) {
1544+
error("DisconnectBlock(): no undo data available");
1545+
return DISCONNECT_FAILED;
1546+
}
1547+
if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash())) {
1548+
error("DisconnectBlock(): failure reading undo data");
1549+
return DISCONNECT_FAILED;
1550+
}
15451551

1546-
if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
1547-
return error("DisconnectBlock(): block and undo data inconsistent");
1552+
if (blockUndo.vtxundo.size() + 1 != block.vtx.size()) {
1553+
error("DisconnectBlock(): block and undo data inconsistent");
1554+
return DISCONNECT_FAILED;
1555+
}
15481556

15491557
// undo transactions in reverse order
15501558
for (int i = block.vtx.size() - 1; i >= 0; i--) {
@@ -1573,8 +1581,10 @@ static bool DisconnectBlock(const CBlock& block, CValidationState& state, const
15731581
// restore inputs
15741582
if (i > 0) { // not coinbases
15751583
const CTxUndo &txundo = blockUndo.vtxundo[i-1];
1576-
if (txundo.vprevout.size() != tx.vin.size())
1577-
return error("DisconnectBlock(): transaction and undo data inconsistent");
1584+
if (txundo.vprevout.size() != tx.vin.size()) {
1585+
error("DisconnectBlock(): transaction and undo data inconsistent");
1586+
return DISCONNECT_FAILED;
1587+
}
15781588
for (unsigned int j = tx.vin.size(); j-- > 0;) {
15791589
const COutPoint &out = tx.vin[j].prevout;
15801590
const CTxInUndo &undo = txundo.vprevout[j];
@@ -1587,12 +1597,7 @@ static bool DisconnectBlock(const CBlock& block, CValidationState& state, const
15871597
// move best block pointer to prevout block
15881598
view.SetBestBlock(pindex->pprev->GetBlockHash());
15891599

1590-
if (pfClean) {
1591-
*pfClean = fClean;
1592-
return true;
1593-
}
1594-
1595-
return fClean;
1600+
return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN;
15961601
}
15971602

15981603
void static FlushBlockFile(bool fFinalize = false)
@@ -2128,7 +2133,7 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara
21282133
int64_t nStart = GetTimeMicros();
21292134
{
21302135
CCoinsViewCache view(pcoinsTip);
2131-
if (!DisconnectBlock(block, state, pindexDelete, view))
2136+
if (DisconnectBlock(block, pindexDelete, view) != DISCONNECT_OK)
21322137
return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
21332138
bool flushed = view.Flush();
21342139
assert(flushed);
@@ -3656,15 +3661,17 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
36563661
}
36573662
// check level 3: check for inconsistencies during memory-only disconnect of tip blocks
36583663
if (nCheckLevel >= 3 && pindex == pindexState && (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <= nCoinCacheUsage) {
3659-
bool fClean = true;
3660-
if (!DisconnectBlock(block, state, pindex, coins, &fClean))
3664+
DisconnectResult res = DisconnectBlock(block, pindex, coins);
3665+
if (res == DISCONNECT_FAILED) {
36613666
return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
3667+
}
36623668
pindexState = pindex->pprev;
3663-
if (!fClean) {
3669+
if (res == DISCONNECT_UNCLEAN) {
36643670
nGoodTransactions = 0;
36653671
pindexFailure = pindex;
3666-
} else
3672+
} else {
36673673
nGoodTransactions += block.vtx.size();
3674+
}
36683675
}
36693676
if (ShutdownRequested())
36703677
return true;

0 commit comments

Comments
 (0)