diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2017-04-25 11:29:19 -0700 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2017-05-26 13:33:39 -0700 |
commit | 7d991b55dbf0b0f6e21c0680ee3ebd09df09012f (patch) | |
tree | 78cebf3cfb52326c900393014c7f8b8a3f68210e /src | |
parent | c3aa0c11947dfd82702df276d39bb7f748dd83a1 (diff) |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/undo.h | 3 | ||||
-rw-r--r-- | src/validation.cpp | 17 |
2 files changed, 11 insertions, 9 deletions
diff --git a/src/undo.h b/src/undo.h index d21b82e2ec..37a1c89f45 100644 --- a/src/undo.h +++ b/src/undo.h @@ -12,8 +12,7 @@ /** Undo information for a CTxIn * - * Contains the prevout's CTxOut being spent, and if this was the - * last output of the affected transaction, its metadata as well + * Contains the prevout's CTxOut being spent, and its metadata as well * (coinbase or not, height). Earlier versions also stored the transaction * version. */ diff --git a/src/validation.cpp b/src/validation.cpp index be0c9b564e..fccef17196 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1082,11 +1082,9 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txund // mark an outpoint spent, and construct undo information txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos])); coins->Spend(nPos); - if (coins->vout.size() == 0) { - CTxInUndo& undo = txundo.vprevout.back(); - undo.nHeight = coins->nHeight; - undo.fCoinBase = coins->fCoinBase; - } + CTxInUndo& undo = txundo.vprevout.back(); + undo.nHeight = coins->nHeight; + undo.fCoinBase = coins->fCoinBase; } } // add outputs @@ -1266,11 +1264,16 @@ int ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& CCoinsModifier coins = view.ModifyCoins(out.hash); if (undo.nHeight != 0) { - // undo data contains height: this is the last output of the prevout tx being spent - if (!coins->IsPruned()) fClean = false; // overwriting existing transaction + if (!coins->IsPruned()) { + 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->nHeight = undo.nHeight; } 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->IsAvailable(out.n)) fClean = false; // overwriting existing output |