From 4c99e804497721d252b765f04534a42d5e461773 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Tue, 5 Nov 2013 14:02:37 -0200 Subject: [PATCH] fix txindex inconsistency if twisterd crashes. txindex (user,-1) may point to a key in a block not yet linked to the chain. --- src/main.cpp | 12 ++++++++++-- src/main.h | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 65cfdae3..c269a62c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -709,7 +709,7 @@ bool GetTransaction(const std::string &username, CTransaction &txOut, uint256 &h return false; } -bool verifyDuplicateOrReplacementTx(CTransaction &tx, bool checkDuplicate, bool checkReplacement, int maxHeight) +bool verifyDuplicateOrReplacementTx(CTransaction &tx, bool checkDuplicate, bool checkReplacement, int maxHeight, bool removeOrphan) { CTransaction oldTx; uint256 hashBlock; @@ -740,6 +740,14 @@ bool verifyDuplicateOrReplacementTx(CTransaction &tx, bool checkDuplicate, bool return true; } } + } else if (removeOrphan) { + // check if (user,-1) exists in txindex and remove it + // return true to count as duplicate/replacement + uint256 txid = SerializeHash(make_pair(tx.GetUsername(),-1)); + if( pblocktree->HaveTxIndex(txid) ) { + pblocktree->EraseTxIndex(txid); + return true; + } } return false; } @@ -1154,7 +1162,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C * reconnect blocks which transactions are already written to the tx index. * 2) possibly a key replacement. check if new key is signed by the old one. */ - if( !verifyDuplicateOrReplacementTx(tx, true, true, block.nHeight) ) { + if( !verifyDuplicateOrReplacementTx(tx, true, true, block.nHeight, true) ) { // not the same, not replacement => error! return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction")); } diff --git a/src/main.h b/src/main.h index 1c18bbe3..03ffb0cf 100644 --- a/src/main.h +++ b/src/main.h @@ -184,7 +184,7 @@ std::string GetWarnings(std::string strFor); /** Retrieve a transaction (from memory pool, or from disk, if possible) */ bool GetTransaction(const std::string &username, CTransaction &tx, uint256 &hashBlock, int maxHeight = -1); /** Verify duplicate or replacement transactions */ -bool verifyDuplicateOrReplacementTx(CTransaction &tx, bool checkDuplicate, bool checkReplacement, int maxHeight = -1); +bool verifyDuplicateOrReplacementTx(CTransaction &tx, bool checkDuplicate, bool checkReplacement, int maxHeight = -1, bool removeOrphan = false); /** Connect/disconnect blocks until pindexNew is the new tip of the active block chain */ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew); /** Find the best known block, and make it the tip of the block chain */