Browse Source

bugfix: weak checking for existing users (the transaction may exist in index only

but the chain it belongs was invalidated) caused fork between users who erased their
block database from yesterday and those who didn't. improve the checking (test
if tx is actually in main chain). add another checkpoint. enforce.
miguelfreitas
Miguel Freitas 11 years ago
parent
commit
9d5d203a0c
  1. 2
      src/bitcoinrpc.cpp
  2. 5
      src/checkpoints.cpp
  3. 20
      src/main.cpp

2
src/bitcoinrpc.cpp

@ -1084,7 +1084,7 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s @@ -1084,7 +1084,7 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s
// Observe safe mode
string strWarning = GetWarnings("rpc");
if (strWarning != "" && !GetBoolArg("-disablesafemode", true) &&
if (strWarning != "" && !GetBoolArg("-disablesafemode", false) &&
!pcmd->okSafeMode)
throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning);

5
src/checkpoints.cpp

@ -40,11 +40,12 @@ namespace Checkpoints @@ -40,11 +40,12 @@ namespace Checkpoints
( 121, uint256("0xcfdd9b4eb621c93163af7b730b3590b7a90c3d5e233569d76a1c0363527c92ae"))
( 13081, uint256("0x5125dc1f6a3b8f1c463baf3e078d8af9f1b35aa4b34fb441e3a7ee391f8727c6"))
( 18000, uint256("0xa3cab01c0e3e9b17b2a63b3cc93d258112f5ad753df1df7bd45e37a5c60814a9"))
( 18050, uint256("0xef0d4c9e318a952dd45fcb1c867996df309a0fb586811479c08cf18a176a8864"))
;
static const CCheckpointData data = {
&mapCheckpoints,
1389317765, // * UNIX timestamp of last checkpoint block
21106, // * total number of transactions between genesis and last checkpoint
1389337278, // * UNIX timestamp of last checkpoint block
21168, // * total number of transactions between genesis and last checkpoint
// (the tx=... number in the SetBestChain debug.log lines)
144.0 // * estimated number of transactions per day after checkpoint
};

20
src/main.cpp

@ -1137,6 +1137,20 @@ void static FlushBlockFile(bool fFinalize = false) @@ -1137,6 +1137,20 @@ void static FlushBlockFile(bool fFinalize = false)
bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize);
bool isUserTransactionInMainChain(std::string username) {
CTransaction tx;
uint256 hashBlock = 0;
if( !GetTransaction(username, tx, hashBlock) || hashBlock == 0)
return false;
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
if (mi != mapBlockIndex.end() && (*mi).second) {
CBlockIndex* pindex = (*mi).second;
return pindex->IsInMainChain();
}
return false;
}
bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck)
{
// Check it again in case a previous version let a bad block in
@ -1159,8 +1173,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C @@ -1159,8 +1173,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
for (unsigned int i = 1; i < block.vtx.size(); i++) {
CTransaction &tx = block.vtx[i];
uint256 txid = SerializeHash(make_pair(block.vtx[i].GetUsername(),-1));
if( pblocktree->HaveTxIndex(txid) ) {
if( isUserTransactionInMainChain(block.vtx[i].GetUsername()) ) {
/* We have index for this username, which is not allowed, except:
* 1) same transaction. this shouldn't happen but it does if twisterd terminates badly.
* explanation: TxIndex seems to get out-of-sync with block chain, so it may try to
@ -2144,6 +2157,9 @@ bool VerifyDB(int nCheckLevel, int nCheckDepth) @@ -2144,6 +2157,9 @@ bool VerifyDB(int nCheckLevel, int nCheckDepth)
// check level 1: verify block validity
if (nCheckLevel >= 1 && !CheckBlock(block, state))
return error("VerifyDB() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
if (!Checkpoints::CheckBlock(pindex->nHeight, pindex->GetBlockHash()))
return error("VerifyDB() : *** rejected by checkpoint lock-in at %d\n", pindex->nHeight);
// check level 2: verify undo validity
if (nCheckLevel >= 2 && pindex) {
CBlockUndo undo;

Loading…
Cancel
Save