diff options
author | Gregory Maxwell <greg@xiph.org> | 2013-09-09 02:11:11 -0700 |
---|---|---|
committer | Gregory Maxwell <greg@xiph.org> | 2013-09-09 02:11:11 -0700 |
commit | f8b7aa862519ab2efd1ce327d2ed4bea1325dc11 (patch) | |
tree | 1a0cd0aab0b06ccf3b0b2b4013b834ed501228f2 | |
parent | 4c723841e25650f045ed55b1e6a619d6d43398d5 (diff) |
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.cpp | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/src/main.cpp b/src/main.cpp index b708879f16..c4e08e15d9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -466,7 +466,7 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) bool IsStandardTx(const CTransaction& tx, string& reason) { - if (tx.nVersion > CTransaction::CURRENT_VERSION) { + if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) { reason = "version"; return false; } @@ -1778,6 +1778,11 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex 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"); |