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.
This commit is contained in:
Miguel Freitas 2014-01-10 17:36:23 -02:00
parent 9f9bb58635
commit 9d5d203a0c
3 changed files with 22 additions and 5 deletions

View File

@ -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);

View File

@ -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
};

View File

@ -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
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)
// 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;