Skip to content

Commit 7d991b5

Browse files
committed
Store/allow tx metadata in all undo records
Previously, transaction metadata (height, coinbase or not, and before the previous commit also nVersion) was only stored for undo records that correspond to the last output of a transaction being spent. This only saves 2 bytes per undo record. Change this to storing this information for every undo record, and stop complaining for having it in non-last output spends. This means that undo dat written with this patch won't be readable by older versions anymore.
1 parent c3aa0c1 commit 7d991b5

File tree

2 files changed

+11
-9
lines changed

2 files changed

+11
-9
lines changed

src/undo.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212

1313
/** Undo information for a CTxIn
1414
*
15-
* Contains the prevout's CTxOut being spent, and if this was the
16-
* last output of the affected transaction, its metadata as well
15+
* Contains the prevout's CTxOut being spent, and its metadata as well
1716
* (coinbase or not, height). Earlier versions also stored the transaction
1817
* version.
1918
*/

src/validation.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,11 +1082,9 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txund
10821082
// mark an outpoint spent, and construct undo information
10831083
txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos]));
10841084
coins->Spend(nPos);
1085-
if (coins->vout.size() == 0) {
1086-
CTxInUndo& undo = txundo.vprevout.back();
1087-
undo.nHeight = coins->nHeight;
1088-
undo.fCoinBase = coins->fCoinBase;
1089-
}
1085+
CTxInUndo& undo = txundo.vprevout.back();
1086+
undo.nHeight = coins->nHeight;
1087+
undo.fCoinBase = coins->fCoinBase;
10901088
}
10911089
}
10921090
// add outputs
@@ -1266,11 +1264,16 @@ int ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint&
12661264

12671265
CCoinsModifier coins = view.ModifyCoins(out.hash);
12681266
if (undo.nHeight != 0) {
1269-
// undo data contains height: this is the last output of the prevout tx being spent
1270-
if (!coins->IsPruned()) fClean = false; // overwriting existing transaction
1267+
if (!coins->IsPruned()) {
1268+
if (coins->fCoinBase != undo.fCoinBase || (uint32_t)coins->nHeight != undo.nHeight) fClean = false; // metadata mismatch
1269+
}
1270+
// restore height/coinbase tx metadata from undo data
12711271
coins->fCoinBase = undo.fCoinBase;
12721272
coins->nHeight = undo.nHeight;
12731273
} else {
1274+
// Undo data does not contain height/coinbase. This should never happen
1275+
// for newly created undo entries. Previously, this data was only saved
1276+
// for the last spend of a transaction's outputs, so check IsPruned().
12741277
if (coins->IsPruned()) fClean = false; // adding output to missing transaction
12751278
}
12761279
if (coins->IsAvailable(out.n)) fClean = false; // overwriting existing output

0 commit comments

Comments
 (0)