Better DOS protection, fixed min confirmations

This commit is contained in:
Evan Duffield 2015-02-02 10:33:52 -07:00
parent 6c4a6f6583
commit 2992907d91
5 changed files with 39 additions and 10 deletions

View File

@ -22,7 +22,7 @@ std::map<uint256, CTransaction> mapTxLockReq;
std::map<uint256, CTransaction> mapTxLockReqRejected;
std::map<uint256, int> mapTxLockVote;
std::map<uint256, CTransactionLock> mapTxLocks;
std::map<uint256, int> mapUnknownVotes; //track votes with no tx for DOS
std::map<uint256, int64_t> 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<uint256, int64_t>::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;

View File

@ -40,6 +40,8 @@ bool ProcessConsensusVote(CConsensusVote& ctx);
// keep transaction locks in memory for an hour
void CleanTransactionLocksList();
int64_t GetAverageVoteTime();
class CConsensusVote
{
public:

View File

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

View File

@ -123,8 +123,9 @@ void WalletModel::pollBalanceChanged()
cachedDarksendRounds = nDarksendRounds;
checkBalanceChanged();
if(transactionTableModel)
if(transactionTableModel){
transactionTableModel->updateConfirmations();
}
}
}

View File

@ -1250,7 +1250,7 @@ void CWallet::AvailableCoins(vector<COutput>& 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++) {