From 2992907d91f6aaa2fed5f4380860c4337161a06f Mon Sep 17 00:00:00 2001 From: Evan Duffield Date: Mon, 2 Feb 2015 10:33:52 -0700 Subject: [PATCH] Better DOS protection, fixed min confirmations --- src/instantx.cpp | 40 ++++++++++++++++++++++++++++++++-------- src/instantx.h | 2 ++ src/masternode.cpp | 2 ++ src/qt/walletmodel.cpp | 3 ++- src/wallet.cpp | 2 +- 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/instantx.cpp b/src/instantx.cpp index e3fbb53023..80d9fc347e 100644 --- a/src/instantx.cpp +++ b/src/instantx.cpp @@ -22,7 +22,7 @@ std::map mapTxLockReq; std::map mapTxLockReqRejected; std::map mapTxLockVote; std::map mapTxLocks; -std::map mapUnknownVotes; //track votes with no tx for DOS +std::map mapUnknownVotes; //track votes with no tx for DOS int nCompleteTXLocks; //txlock - Locks transaction @@ -117,18 +117,24 @@ void ProcessMessageInstantX(CNode* pfrom, std::string& strCommand, CDataStream& if(ProcessConsensusVote(ctx)){ //Spam/Dos protection + /* + Masternodes will sometimes propagate votes before the transaction is known to the client. + This tracks those messages and allows it at the same rate of the rest of the network, if + a peer violates it, it will simply be ignored + */ if(!mapTxLockReq.count(ctx.txHash) && !mapTxLockReqRejected.count(ctx.txHash)){ if(!mapUnknownVotes.count(ctx.vinMasternode.prevout.hash)){ //TODO: Make an algorithm to calculate the average time per IX/MNCOUNT mapUnknownVotes[ctx.vinMasternode.prevout.hash] = GetTime()+(60*10); } - if(mapUnknownVotes[ctx.vinMasternode.prevout.hash] > GetTime()){ - LogPrintf("ProcessMessageInstantX::txlreq - masternode is spamming transaction votes: %s %s : rejected %s\n", - ctx.vinMasternode.ToString().c_str(), - ctx.txHash.ToString().c_str() - ); - return; + if(mapUnknownVotes[ctx.vinMasternode.prevout.hash] > GetTime() && + mapUnknownVotes[ctx.vinMasternode.prevout.hash] - GetAverageVoteTime() > 60*10){ + LogPrintf("ProcessMessageInstantX::txlreq - masternode is spamming transaction votes: %s %s : rejected %s\n", + ctx.vinMasternode.ToString().c_str(), + ctx.txHash.ToString().c_str() + ); + return; } else { mapUnknownVotes[ctx.vinMasternode.prevout.hash] = GetTime()+(60*10); } @@ -216,8 +222,10 @@ bool ProcessConsensusVote(CConsensusVote& ctx) (*i).second.AddSignature(ctx); if((*i).second.CountSignatures() >= INSTANTX_SIGNATURES_REQUIRED){ LogPrintf("InstantX::ProcessConsensusVote - Transaction Lock Is Complete %s !\n", (*i).second.GetHash().ToString().c_str()); - if(pwalletMain->UpdatedTransaction((*i).second.txHash)) + + if(pwalletMain->UpdatedTransaction((*i).second.txHash)){ nCompleteTXLocks++; + } } return true; } @@ -226,6 +234,22 @@ bool ProcessConsensusVote(CConsensusVote& ctx) return false; } + +int64_t GetAverageVoteTime() +{ + std::map::iterator it = mapUnknownVotes.begin(); + int64_t total = 0; + int64_t count = 0; + + while(it != mapUnknownVotes.end()) { + total+= it->second; + count++; + it++; + } + + return total / count; +} + void CleanTransactionLocksList() { if(chainActive.Tip() == NULL) return; diff --git a/src/instantx.h b/src/instantx.h index a48ac6f625..674c21ac40 100644 --- a/src/instantx.h +++ b/src/instantx.h @@ -40,6 +40,8 @@ bool ProcessConsensusVote(CConsensusVote& ctx); // keep transaction locks in memory for an hour void CleanTransactionLocksList(); +int64_t GetAverageVoteTime(); + class CConsensusVote { public: diff --git a/src/masternode.cpp b/src/masternode.cpp index 4dce8e9250..9172c71a74 100644 --- a/src/masternode.cpp +++ b/src/masternode.cpp @@ -68,6 +68,8 @@ void ProcessMessageMasternode(CNode* pfrom, std::string& strCommand, CDataStream } bool isLocal = addr.IsRFC1918() || addr.IsLocal(); + if(RegTest()) isLocal = false; + std::string vchPubKey(pubkey.begin(), pubkey.end()); std::string vchPubKey2(pubkey2.begin(), pubkey2.end()); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 6b23030ae3..40cbb906c2 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -123,8 +123,9 @@ void WalletModel::pollBalanceChanged() cachedDarksendRounds = nDarksendRounds; checkBalanceChanged(); - if(transactionTableModel) + if(transactionTableModel){ transactionTableModel->updateConfirmations(); + } } } diff --git a/src/wallet.cpp b/src/wallet.cpp index efa74abf81..b66e75f73c 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1250,7 +1250,7 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const continue; int nDepth = pcoin->GetDepthInMainChain(false); - if (nDepth < minimum_confirmations) + if (nDepth <= minimum_confirmations) continue; for (unsigned int i = 0; i < pcoin->vout.size(); i++) {