aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2017-04-25 11:29:19 -0700
committerPieter Wuille <pieter.wuille@gmail.com>2017-05-26 13:33:39 -0700
commit7d991b55dbf0b0f6e21c0680ee3ebd09df09012f (patch)
tree78cebf3cfb52326c900393014c7f8b8a3f68210e
parentc3aa0c11947dfd82702df276d39bb7f748dd83a1 (diff)
downloadbitcoin-7d991b55dbf0b0f6e21c0680ee3ebd09df09012f.tar.xz
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.
-rw-r--r--src/undo.h3
-rw-r--r--src/validation.cpp17
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