aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Maxwell <greg@xiph.org>2013-09-09 02:11:11 -0700
committerGavin Andresen <gavinandresen@gmail.com>2013-09-10 10:03:06 +1000
commitf0a1d87b00e666a7028c2b517d786bc7511eaf5d (patch)
treea58e3b2cc3f6f62590eae3a53fd0eed626ebb395
parent839c7d1fa8bf939e313d78d2fae65bcf0174875c (diff)
downloadbitcoin-f0a1d87b00e666a7028c2b517d786bc7511eaf5d.tar.xz
Longer term workaround for chainstate corruption from negative versions.
This also makes negative transaction versions non-standard. This avoids an issue triggered in block 256818 where transactions with negative version numbers were incorrectly serialized into the UTXO set. On restart nodes detect the inconsistency and refuse to start so long as a block with these transactions is inside the self-consistency check window, logging "coin database inconsistencies found". The software recommends reindexing, but reindexing does not correct the problem. This should be fixed by changing the chainstate serialization, but working around it seems harmless for now because the version is not used by any network rule currently. A patch free workaround is to start with -checklevel=2 which skips the consistency checks, but the IsStandard change is important for miners in order to protect unpatched nodes.
-rw-r--r--src/main.cpp7
1 files changed, 6 insertions, 1 deletions
diff --git a/src/main.cpp b/src/main.cpp
index cb0ecdc671..a7501a1b68 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -368,7 +368,7 @@ bool CTxOut::IsDust() const
bool CTransaction::IsStandard() const
{
- if (nVersion > CTransaction::CURRENT_VERSION)
+ if (nVersion > CTransaction::CURRENT_VERSION || nVersion < 1)
return false;
if (!IsFinal())
@@ -1499,6 +1499,11 @@ bool CBlock::DisconnectBlock(CValidationState &state, CBlockIndex *pindex, CCoin
CCoins &outs = view.GetCoins(hash);
CCoins outsBlock = CCoins(tx, pindex->nHeight);
+ // The CCoins serialization does not serialize negative numbers.
+ // No network rules currently depend on the version here, so an inconsistency is harmless
+ // but it must be corrected before txout nversion ever influences a network rule.
+ if (outsBlock.nVersion < 0)
+ outs.nVersion = outsBlock.nVersion;
if (outs != outsBlock)
fClean = fClean && error("DisconnectBlock() : added transaction mismatch? database corrupted");