Browse Source

fix txindex inconsistency if twisterd crashes.

txindex (user,-1) may point to a key in a block not yet linked to the chain.
miguelfreitas
Miguel Freitas 11 years ago
parent
commit
4c99e80449
  1. 12
      src/main.cpp
  2. 2
      src/main.h

12
src/main.cpp

@ -709,7 +709,7 @@ bool GetTransaction(const std::string &username, CTransaction &txOut, uint256 &h
return false; 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; CTransaction oldTx;
uint256 hashBlock; uint256 hashBlock;
@ -740,6 +740,14 @@ bool verifyDuplicateOrReplacementTx(CTransaction &tx, bool checkDuplicate, bool
return true; 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; 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. * 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. * 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! // not the same, not replacement => error!
return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction")); return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction"));
} }

2
src/main.h

@ -184,7 +184,7 @@ std::string GetWarnings(std::string strFor);
/** Retrieve a transaction (from memory pool, or from disk, if possible) */ /** Retrieve a transaction (from memory pool, or from disk, if possible) */
bool GetTransaction(const std::string &username, CTransaction &tx, uint256 &hashBlock, int maxHeight = -1); bool GetTransaction(const std::string &username, CTransaction &tx, uint256 &hashBlock, int maxHeight = -1);
/** Verify duplicate or replacement transactions */ /** 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 */ /** Connect/disconnect blocks until pindexNew is the new tip of the active block chain */
bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew); bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew);
/** Find the best known block, and make it the tip of the block chain */ /** Find the best known block, and make it the tip of the block chain */

Loading…
Cancel
Save