Skip to content

Commit 6d2ea62

Browse files
committed
Split logic to undo txin's off DisconnectBlock
coming from btc@eb1c2cd37f75cf4d0e85970932b9774b2d073225
1 parent a3a4ab5 commit 6d2ea62

File tree

1 file changed

+38
-24
lines changed

1 file changed

+38
-24
lines changed

src/main.cpp

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,6 +1990,39 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin
19901990

19911991
} // anon namespace
19921992

1993+
/**
1994+
* Apply the undo operation of a CTxInUndo to the given chain state.
1995+
* @param undo The undo object.
1996+
* @param view The coins view to which to apply the changes.
1997+
* @param out The out point that corresponds to the tx input.
1998+
* @return True on success.
1999+
*/
2000+
static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& out)
2001+
{
2002+
bool fClean = true;
2003+
2004+
CCoinsModifier coins = view.ModifyCoins(out.hash);
2005+
if (undo.nHeight != 0) {
2006+
// undo data contains height: this is the last output of the prevout tx being spent
2007+
if (!coins->IsPruned())
2008+
fClean = fClean && error("%s: undo data overwriting existing transaction", __func__);
2009+
coins->Clear();
2010+
coins->fCoinBase = undo.fCoinBase;
2011+
coins->nHeight = undo.nHeight;
2012+
coins->nVersion = undo.nVersion;
2013+
} else {
2014+
if (coins->IsPruned())
2015+
fClean = fClean && error("%s: undo data adding output to missing transaction", __func__);
2016+
}
2017+
if (coins->IsAvailable(out.n))
2018+
fClean = fClean && error("%s: undo data overwriting existing output", __func__);
2019+
if (coins->vout.size() < out.n+1)
2020+
coins->vout.resize(out.n+1);
2021+
coins->vout[out.n] = undo.txout;
2022+
2023+
return fClean;
2024+
}
2025+
19932026
bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
19942027
{
19952028
AssertLockHeld(cs_main);
@@ -2031,11 +2064,8 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
20312064

20322065

20332066
// Check that all outputs are available and match the outputs in the block itself
2034-
// exactly. Note that transactions with only provably unspendable outputs won't
2035-
// have outputs available even in the block itself, so we handle that case
2036-
// specially with outsEmpty.
2067+
// exactly.
20372068
{
2038-
CCoins outsEmpty;
20392069
CCoinsModifier outs = view.ModifyCoins(hash);
20402070
outs->ClearUnspendable();
20412071

@@ -2063,24 +2093,8 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
20632093
for (unsigned int j = tx.vin.size(); j-- > 0;) {
20642094
const COutPoint& out = tx.vin[j].prevout;
20652095
const CTxInUndo& undo = txundo.vprevout[j];
2066-
CCoinsModifier coins = view.ModifyCoins(out.hash);
2067-
if (undo.nHeight != 0) {
2068-
// undo data contains height: this is the last output of the prevout tx being spent
2069-
if (!coins->IsPruned())
2070-
fClean = fClean && error("DisconnectBlock() : undo data overwriting existing transaction");
2071-
coins->Clear();
2072-
coins->fCoinBase = undo.fCoinBase;
2073-
coins->nHeight = undo.nHeight;
2074-
coins->nVersion = undo.nVersion;
2075-
} else {
2076-
if (coins->IsPruned())
2077-
fClean = fClean && error("DisconnectBlock() : undo data adding output to missing transaction");
2078-
}
2079-
if (coins->IsAvailable(out.n))
2080-
fClean = fClean && error("DisconnectBlock() : undo data overwriting existing output");
2081-
if (coins->vout.size() < out.n + 1)
2082-
coins->vout.resize(out.n + 1);
2083-
coins->vout[out.n] = undo.txout;
2096+
if (!ApplyTxInUndo(undo, view, out))
2097+
fClean = false;
20842098
}
20852099

20862100
if (view.HaveInputs(tx))
@@ -2103,9 +2117,9 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
21032117
if (pfClean) {
21042118
*pfClean = fClean;
21052119
return true;
2106-
} else {
2107-
return fClean;
21082120
}
2121+
2122+
return fClean;
21092123
}
21102124

21112125
void static FlushBlockFile(bool fFinalize = false)

0 commit comments

Comments
 (0)