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.
This commit is contained in:
parent
c3aa0c1194
commit
7d991b55db
2 changed files with 11 additions and 9 deletions
|
@ -12,8 +12,7 @@
|
||||||
|
|
||||||
/** Undo information for a CTxIn
|
/** Undo information for a CTxIn
|
||||||
*
|
*
|
||||||
* Contains the prevout's CTxOut being spent, and if this was the
|
* Contains the prevout's CTxOut being spent, and its metadata as well
|
||||||
* last output of the affected transaction, its metadata as well
|
|
||||||
* (coinbase or not, height). Earlier versions also stored the transaction
|
* (coinbase or not, height). Earlier versions also stored the transaction
|
||||||
* version.
|
* version.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1082,11 +1082,9 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txund
|
||||||
// mark an outpoint spent, and construct undo information
|
// mark an outpoint spent, and construct undo information
|
||||||
txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos]));
|
txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos]));
|
||||||
coins->Spend(nPos);
|
coins->Spend(nPos);
|
||||||
if (coins->vout.size() == 0) {
|
CTxInUndo& undo = txundo.vprevout.back();
|
||||||
CTxInUndo& undo = txundo.vprevout.back();
|
undo.nHeight = coins->nHeight;
|
||||||
undo.nHeight = coins->nHeight;
|
undo.fCoinBase = coins->fCoinBase;
|
||||||
undo.fCoinBase = coins->fCoinBase;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add outputs
|
// add outputs
|
||||||
|
@ -1266,11 +1264,16 @@ int ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint&
|
||||||
|
|
||||||
CCoinsModifier coins = view.ModifyCoins(out.hash);
|
CCoinsModifier coins = view.ModifyCoins(out.hash);
|
||||||
if (undo.nHeight != 0) {
|
if (undo.nHeight != 0) {
|
||||||
// undo data contains height: this is the last output of the prevout tx being spent
|
if (!coins->IsPruned()) {
|
||||||
if (!coins->IsPruned()) fClean = false; // overwriting existing transaction
|
if (coins->fCoinBase != undo.fCoinBase || (uint32_t)coins->nHeight != undo.nHeight) fClean = false; // metadata mismatch
|
||||||
|
}
|
||||||
|
// restore height/coinbase tx metadata from undo data
|
||||||
coins->fCoinBase = undo.fCoinBase;
|
coins->fCoinBase = undo.fCoinBase;
|
||||||
coins->nHeight = undo.nHeight;
|
coins->nHeight = undo.nHeight;
|
||||||
} else {
|
} else {
|
||||||
|
// Undo data does not contain height/coinbase. This should never happen
|
||||||
|
// for newly created undo entries. Previously, this data was only saved
|
||||||
|
// for the last spend of a transaction's outputs, so check IsPruned().
|
||||||
if (coins->IsPruned()) fClean = false; // adding output to missing transaction
|
if (coins->IsPruned()) fClean = false; // adding output to missing transaction
|
||||||
}
|
}
|
||||||
if (coins->IsAvailable(out.n)) fClean = false; // overwriting existing output
|
if (coins->IsAvailable(out.n)) fClean = false; // overwriting existing output
|
||||||
|
|
Loading…
Reference in a new issue