mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 12:32:48 +01:00
refactoring PS, cleanup, more log output in debug mode (#1121)
* refactoring PS, cleanup, more log output in debug mode (part of #1120) * fix dsq rate limit calculations on new dsq
This commit is contained in:
parent
4894345a58
commit
ee60f6e76a
275
src/darksend.cpp
275
src/darksend.cpp
@ -36,19 +36,15 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
||||
|
||||
if(strCommand == NetMsgType::DSACCEPT) {
|
||||
|
||||
PoolMessage nMessageID = MSG_NOERR;
|
||||
|
||||
if(pfrom->nVersion < MIN_PRIVATESEND_PEER_PROTO_VERSION) {
|
||||
nMessageID = ERR_VERSION;
|
||||
LogPrintf("DSACCEPT -- incompatible version! nVersion: %d\n", pfrom->nVersion);
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID);
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_VERSION);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!fMasterNode) {
|
||||
nMessageID = ERR_NOT_A_MN;
|
||||
LogPrintf("DSACCEPT -- not a Masternode!\n");
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID);
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_NOT_A_MN);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -56,22 +52,23 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
||||
CTransaction txCollateral;
|
||||
vRecv >> nDenom >> txCollateral;
|
||||
|
||||
LogPrint("privatesend", "DSACCEPT -- nDenom %d (%s) txCollateral %s", nDenom, GetDenominationsToString(nDenom), txCollateral.ToString());
|
||||
|
||||
CMasternode* pmn = mnodeman.Find(activeMasternode.vin);
|
||||
if(pmn == NULL) {
|
||||
nMessageID = ERR_MN_LIST;
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID);
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_MN_LIST);
|
||||
return;
|
||||
}
|
||||
|
||||
if(nSessionUsers == 0 && pmn->nLastDsq != 0 &&
|
||||
if(vecSessionCollaterals.size() == 0 && pmn->nLastDsq != 0 &&
|
||||
pmn->nLastDsq + mnodeman.CountEnabled(MIN_PRIVATESEND_PEER_PROTO_VERSION)/5 > mnodeman.nDsqCount)
|
||||
{
|
||||
LogPrintf("DSACCEPT -- last dsq too recent, must wait: addr=%s\n", pfrom->addr.ToString());
|
||||
nMessageID = ERR_RECENT;
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID);
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_RECENT);
|
||||
return;
|
||||
}
|
||||
|
||||
PoolMessage nMessageID = MSG_NOERR;
|
||||
if(IsDenomCompatibleWithSession(nDenom, txCollateral, nMessageID)) {
|
||||
LogPrintf("DSACCEPT -- is compatible, please submit!\n");
|
||||
PushStatus(pfrom, STATUS_ACCEPTED, nMessageID);
|
||||
@ -94,32 +91,39 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
||||
CDarksendQueue dsq;
|
||||
vRecv >> dsq;
|
||||
|
||||
CService addr;
|
||||
if(!dsq.GetAddress(addr) || !dsq.CheckSignature() || dsq.IsExpired()) return;
|
||||
LogPrint("privatesend", "DSQUEUE -- %s new\n", dsq.ToString());
|
||||
|
||||
if(dsq.IsExpired()) return;
|
||||
|
||||
CMasternode* pmn = mnodeman.Find(dsq.vin);
|
||||
if(pmn == NULL) return;
|
||||
|
||||
if(!dsq.CheckSignature(pmn->pubKeyMasternode)) {
|
||||
// we probably have outdated info
|
||||
mnodeman.AskForMN(pfrom, dsq.vin);
|
||||
return;
|
||||
}
|
||||
|
||||
// if the queue is ready, submit if we can
|
||||
if(dsq.fReady) {
|
||||
if(!pSubmittedToMasternode) return;
|
||||
if((CNetAddr)pSubmittedToMasternode->addr != (CNetAddr)addr) {
|
||||
LogPrintf("DSQUEUE -- message doesn't match current Masternode: pSubmittedToMasternode=%s, addr=%s\n", pSubmittedToMasternode->addr.ToString(), addr.ToString());
|
||||
if((CNetAddr)pSubmittedToMasternode->addr != (CNetAddr)pmn->addr) {
|
||||
LogPrintf("DSQUEUE -- message doesn't match current Masternode: pSubmittedToMasternode=%s, addr=%s\n", pSubmittedToMasternode->addr.ToString(), pmn->addr.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
if(nState == POOL_STATE_QUEUE) {
|
||||
LogPrint("privatesend", "DSQUEUE -- PrivateSend queue (%s) is ready on masternode %s\n", dsq.ToString(), addr.ToString());
|
||||
LogPrint("privatesend", "DSQUEUE -- PrivateSend queue (%s) is ready on masternode %s\n", dsq.ToString(), pmn->addr.ToString());
|
||||
SubmitDenominate();
|
||||
}
|
||||
} else {
|
||||
BOOST_FOREACH(CDarksendQueue q, vecDarksendQueue)
|
||||
if(q.vin == dsq.vin) return;
|
||||
|
||||
LogPrint("privatesend", "DSQUEUE -- nLastDsq: %d threshold: %d nDsqCount: %d\n", pmn->nLastDsq, pmn->nLastDsq + mnodeman.size()/5, mnodeman.nDsqCount);
|
||||
int nThreshold = pmn->nLastDsq + mnodeman.CountEnabled(MIN_PRIVATESEND_PEER_PROTO_VERSION)/5;
|
||||
LogPrint("privatesend", "DSQUEUE -- nLastDsq: %d threshold: %d nDsqCount: %d\n", pmn->nLastDsq, nThreshold, mnodeman.nDsqCount);
|
||||
//don't allow a few nodes to dominate the queuing process
|
||||
if(pmn->nLastDsq != 0 &&
|
||||
pmn->nLastDsq + mnodeman.CountEnabled(MIN_PRIVATESEND_PEER_PROTO_VERSION)/5 > mnodeman.nDsqCount) {
|
||||
if(pmn->nLastDsq != 0 && nThreshold > mnodeman.nDsqCount) {
|
||||
LogPrint("privatesend", "DSQUEUE -- Masternode %s is sending too many dsq messages\n", pmn->addr.ToString());
|
||||
return;
|
||||
}
|
||||
@ -127,26 +131,23 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
||||
pmn->nLastDsq = mnodeman.nDsqCount;
|
||||
pmn->fAllowMixingTx = true;
|
||||
|
||||
LogPrint("privatesend", "DSQUEUE -- new PrivateSend queue (%s) from masternode %s\n", dsq.ToString(), addr.ToString());
|
||||
LogPrint("privatesend", "DSQUEUE -- new PrivateSend queue (%s) from masternode %s\n", dsq.ToString(), pmn->addr.ToString());
|
||||
vecDarksendQueue.push_back(dsq);
|
||||
dsq.Relay();
|
||||
dsq.nTime = GetTime();
|
||||
}
|
||||
|
||||
} else if(strCommand == NetMsgType::DSVIN) {
|
||||
PoolMessage nMessageID = MSG_NOERR;
|
||||
|
||||
if(pfrom->nVersion < MIN_PRIVATESEND_PEER_PROTO_VERSION) {
|
||||
LogPrintf("DSVIN -- incompatible version! nVersion: %d\n", pfrom->nVersion);
|
||||
nMessageID = ERR_VERSION;
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID);
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_VERSION);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!fMasterNode) {
|
||||
LogPrintf("DSVIN -- not a Masternode!\n");
|
||||
nMessageID = ERR_NOT_A_MN;
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID);
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_NOT_A_MN);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -154,18 +155,18 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
||||
vRecv >> entry;
|
||||
|
||||
//do we have enough users in the current session?
|
||||
if(nSessionUsers < GetMaxPoolTransactions()) {
|
||||
if(!IsSessionReady()) {
|
||||
LogPrintf("DSVIN -- session not complete!\n");
|
||||
nMessageID = ERR_SESSION;
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID);
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_SESSION);
|
||||
return;
|
||||
}
|
||||
|
||||
LogPrint("privatesend", "DSVIN -- txCollateral %s", entry.txCollateral.ToString());
|
||||
|
||||
//do we have the same denominations as the current session?
|
||||
if(!IsOutputsCompatibleWithSessionDenom(entry.vecTxDSOut)) {
|
||||
LogPrintf("DSVIN -- not compatible with existing transactions!\n");
|
||||
nMessageID = ERR_EXISTING_TX;
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID);
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_EXISTING_TX);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -173,7 +174,6 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
||||
{
|
||||
CAmount nValueIn = 0;
|
||||
CAmount nValueOut = 0;
|
||||
bool fMissingTx = false;
|
||||
|
||||
CMutableTransaction tx;
|
||||
|
||||
@ -183,14 +183,12 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
||||
|
||||
if(txout.scriptPubKey.size() != 25) {
|
||||
LogPrintf("DSVIN -- non-standard pubkey detected! scriptPubKey=%s\n", ScriptToAsmStr(txout.scriptPubKey));
|
||||
nMessageID = ERR_NON_STANDARD_PUBKEY;
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID);
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_NON_STANDARD_PUBKEY);
|
||||
return;
|
||||
}
|
||||
if(!txout.scriptPubKey.IsNormalPaymentScript()) {
|
||||
LogPrintf("DSVIN -- invalid script! scriptPubKey=%s\n", ScriptToAsmStr(txout.scriptPubKey));
|
||||
nMessageID = ERR_INVALID_SCRIPT;
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID);
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_INVALID_SCRIPT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -206,21 +204,15 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
||||
if(txPrev.vout.size() > txin.prevout.n)
|
||||
nValueIn += txPrev.vout[txin.prevout.n].nValue;
|
||||
} else {
|
||||
fMissingTx = true;
|
||||
LogPrintf("DSVIN -- missing input! tx=%s", tx.ToString());
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_MISSING_TX);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(nValueIn > PRIVATESEND_POOL_MAX) {
|
||||
LogPrintf("DSVIN -- more than PrivateSend pool max! nValueIn: %lld, tx=%s", nValueIn, tx.ToString());
|
||||
nMessageID = ERR_MAXIMUM;
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID);
|
||||
return;
|
||||
}
|
||||
|
||||
if(fMissingTx) {
|
||||
LogPrintf("DSVIN -- missing input! tx=%s", tx.ToString());
|
||||
nMessageID = ERR_MISSING_TX;
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID);
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_MAXIMUM);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -228,8 +220,7 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
||||
// TODO: Or do not allow fees at all?
|
||||
if(nValueIn - nValueOut > vecPrivateSendDenominations.back()) {
|
||||
LogPrintf("DSVIN -- fees are too high! fees: %lld, tx=%s", nValueIn - nValueOut, tx.ToString());
|
||||
nMessageID = ERR_FEES;
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID);
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_FEES);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -239,13 +230,14 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
||||
mempool.PrioritiseTransaction(tx.GetHash(), tx.GetHash().ToString(), 1000, 0.1*COIN);
|
||||
if(!AcceptToMemoryPool(mempool, validationState, CTransaction(tx), false, NULL, false, true, true)) {
|
||||
LogPrintf("DSVIN -- transaction not valid! tx=%s", tx.ToString());
|
||||
nMessageID = ERR_INVALID_TX;
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID);
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_INVALID_TX);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PoolMessage nMessageID = MSG_NOERR;
|
||||
|
||||
if(AddEntry(entry, nMessageID)) {
|
||||
PushStatus(pfrom, STATUS_ACCEPTED, nMessageID);
|
||||
CheckPool();
|
||||
@ -255,6 +247,7 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
||||
}
|
||||
|
||||
} else if(strCommand == NetMsgType::DSSTATUSUPDATE) {
|
||||
|
||||
if(pfrom->nVersion < MIN_PRIVATESEND_PEER_PROTO_VERSION) {
|
||||
LogPrintf("DSSTATUSUPDATE -- incompatible version! nVersion: %d\n", pfrom->nVersion);
|
||||
return;
|
||||
@ -310,6 +303,8 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
||||
std::vector<CTxIn> vecTxIn;
|
||||
vRecv >> vecTxIn;
|
||||
|
||||
LogPrint("privatesend", "DSSIGNFINALTX -- vecTxIn.size() %s\n", vecTxIn.size());
|
||||
|
||||
int nTxInIndex = 0;
|
||||
int nTxInsCount = (int)vecTxIn.size();
|
||||
|
||||
@ -347,6 +342,8 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
||||
return;
|
||||
}
|
||||
|
||||
LogPrint("privatesend", "DSFINALTX -- txNew %s", txNew.ToString());
|
||||
|
||||
//check to see if input is spent already? (and probably not confirmed)
|
||||
SignFinalTransaction(txNew, pfrom);
|
||||
|
||||
@ -369,7 +366,7 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
||||
vRecv >> nMsgSessionID >> fMsgError >> nMsgMessageID;
|
||||
|
||||
if(nMsgMessageID < MSG_POOL_MIN || nMsgMessageID > MSG_POOL_MAX) {
|
||||
LogPrint("privatesend", "DSSTATUSUPDATE -- nMsgMessageID is out of bounds: %d\n", nMsgMessageID);
|
||||
LogPrint("privatesend", "DSCOMPLETE -- nMsgMessageID is out of bounds: %d\n", nMsgMessageID);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -378,6 +375,8 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
||||
return;
|
||||
}
|
||||
|
||||
LogPrint("privatesend", "DSCOMPLETE -- nMsgSessionID %d nMsgMessageID %d (%s)\n", nMsgSessionID, nMsgMessageID, GetMessageByID(PoolMessage(nMsgMessageID)));
|
||||
|
||||
CompletedTransaction(fMsgError, PoolMessage(nMsgMessageID));
|
||||
}
|
||||
}
|
||||
@ -417,7 +416,7 @@ void CDarksendPool::SetNull()
|
||||
{
|
||||
// MN side
|
||||
nSessionUsers = 0;
|
||||
vecSessionCollateral.clear();
|
||||
vecSessionCollaterals.clear();
|
||||
|
||||
// Client side
|
||||
nEntriesCount = 0;
|
||||
@ -462,6 +461,11 @@ std::string CDarksendPool::GetStatus()
|
||||
switch(nState) {
|
||||
case POOL_STATE_IDLE:
|
||||
return _("PrivateSend is idle.");
|
||||
case POOL_STATE_QUEUE:
|
||||
if( nStatusMessageProgress % 70 <= 30) strSuffix = ".";
|
||||
else if(nStatusMessageProgress % 70 <= 50) strSuffix = "..";
|
||||
else if(nStatusMessageProgress % 70 <= 70) strSuffix = "...";
|
||||
return strprintf(_("Submitted to masternode, waiting in queue %s"), strSuffix);;
|
||||
case POOL_STATE_ACCEPTING_ENTRIES:
|
||||
if(nEntriesCount == 0) {
|
||||
nStatusMessageProgress = 0;
|
||||
@ -493,11 +497,6 @@ std::string CDarksendPool::GetStatus()
|
||||
return _("PrivateSend request incomplete:") + " " + strLastMessage + " " + _("Will retry...");
|
||||
case POOL_STATE_SUCCESS:
|
||||
return _("PrivateSend request complete:") + " " + strLastMessage;
|
||||
case POOL_STATE_QUEUE:
|
||||
if( nStatusMessageProgress % 70 <= 30) strSuffix = ".";
|
||||
else if(nStatusMessageProgress % 70 <= 50) strSuffix = "..";
|
||||
else if(nStatusMessageProgress % 70 <= 70) strSuffix = "...";
|
||||
return strprintf(_("Submitted to masternode, waiting in queue %s"), strSuffix);;
|
||||
default:
|
||||
return strprintf(_("Unknown state: id = %u"), nState);
|
||||
}
|
||||
@ -511,7 +510,7 @@ void CDarksendPool::CheckPool()
|
||||
if(fMasterNode) {
|
||||
LogPrint("privatesend", "CDarksendPool::CheckPool -- entries count %lu\n", GetEntriesCount());
|
||||
|
||||
// If entries is full, then move on to the next phase
|
||||
// If entries are full, then move on to the next phase
|
||||
if(nState == POOL_STATE_ACCEPTING_ENTRIES && GetEntriesCount() >= GetMaxPoolTransactions()) {
|
||||
LogPrint("privatesend", "CDarksendPool::CheckPool -- TRYING TRANSACTION\n");
|
||||
SetState(POOL_STATE_FINALIZE_TRANSACTION);
|
||||
@ -520,38 +519,14 @@ void CDarksendPool::CheckPool()
|
||||
|
||||
// create the finalized transaction for distribution to the clients
|
||||
if(nState == POOL_STATE_FINALIZE_TRANSACTION) {
|
||||
LogPrint("privatesend", "CDarksendPool::CheckPool -- FINALIZE TRANSACTIONS\n");
|
||||
SetState(POOL_STATE_SIGNING);
|
||||
|
||||
if(!fMasterNode) return;
|
||||
|
||||
CMutableTransaction txNew;
|
||||
|
||||
// make our new transaction
|
||||
for(int i = 0; i < GetEntriesCount(); i++) {
|
||||
BOOST_FOREACH(const CTxDSOut& txdsout, vecEntries[i].vecTxDSOut)
|
||||
txNew.vout.push_back(txdsout);
|
||||
|
||||
BOOST_FOREACH(const CTxDSIn& txdsin, vecEntries[i].vecTxDSIn)
|
||||
txNew.vin.push_back(txdsin);
|
||||
}
|
||||
|
||||
// BIP69 https://github.com/kristovatlas/bips/blob/master/bip-0069.mediawiki
|
||||
sort(txNew.vin.begin(), txNew.vin.end());
|
||||
sort(txNew.vout.begin(), txNew.vout.end());
|
||||
|
||||
finalMutableTransaction = txNew;
|
||||
LogPrint("privatesend", "CDarksendPool::CheckPool -- finalMutableTransaction=%s", txNew.ToString());
|
||||
|
||||
// request signatures from clients
|
||||
RelayFinalTransaction(finalMutableTransaction);
|
||||
CreateFinalTransaction();
|
||||
}
|
||||
|
||||
// If we have all of the signatures, try to compile the transaction
|
||||
if(fMasterNode && nState == POOL_STATE_SIGNING && IsSignaturesComplete()) {
|
||||
LogPrint("privatesend", "CDarksendPool::CheckPool -- SIGNING\n");
|
||||
SetState(POOL_STATE_TRANSMISSION);
|
||||
CheckFinalTransaction();
|
||||
CommitFinalTransaction();
|
||||
}
|
||||
|
||||
// reset if we're here for 10 seconds
|
||||
@ -565,22 +540,50 @@ void CDarksendPool::CheckPool()
|
||||
}
|
||||
}
|
||||
|
||||
void CDarksendPool::CheckFinalTransaction()
|
||||
void CDarksendPool::CreateFinalTransaction()
|
||||
{
|
||||
LogPrint("privatesend", "CDarksendPool::CreateFinalTransaction -- FINALIZE TRANSACTIONS\n");
|
||||
|
||||
CMutableTransaction txNew;
|
||||
|
||||
// make our new transaction
|
||||
for(int i = 0; i < GetEntriesCount(); i++) {
|
||||
BOOST_FOREACH(const CTxDSOut& txdsout, vecEntries[i].vecTxDSOut)
|
||||
txNew.vout.push_back(txdsout);
|
||||
|
||||
BOOST_FOREACH(const CTxDSIn& txdsin, vecEntries[i].vecTxDSIn)
|
||||
txNew.vin.push_back(txdsin);
|
||||
}
|
||||
|
||||
// BIP69 https://github.com/kristovatlas/bips/blob/master/bip-0069.mediawiki
|
||||
sort(txNew.vin.begin(), txNew.vin.end());
|
||||
sort(txNew.vout.begin(), txNew.vout.end());
|
||||
|
||||
finalMutableTransaction = txNew;
|
||||
LogPrint("privatesend", "CDarksendPool::CreateFinalTransaction -- finalMutableTransaction=%s", txNew.ToString());
|
||||
|
||||
// request signatures from clients
|
||||
RelayFinalTransaction(finalMutableTransaction);
|
||||
SetState(POOL_STATE_SIGNING);
|
||||
}
|
||||
|
||||
void CDarksendPool::CommitFinalTransaction()
|
||||
{
|
||||
if(!fMasterNode) return; // check and relay final tx only on masternode
|
||||
|
||||
CTransaction finalTransaction = CTransaction(finalMutableTransaction);
|
||||
uint256 hashTx = finalTransaction.GetHash();
|
||||
|
||||
LogPrint("privatesend", "CDarksendPool::CheckFinalTransaction -- finalTransaction=%s", finalTransaction.ToString());
|
||||
LogPrint("privatesend", "CDarksendPool::CommitFinalTransaction -- finalTransaction=%s", finalTransaction.ToString());
|
||||
|
||||
{
|
||||
// See if the transaction is valid
|
||||
TRY_LOCK(cs_main, lockMain);
|
||||
CValidationState validationState;
|
||||
mempool.PrioritiseTransaction(finalTransaction.GetHash(), finalTransaction.GetHash().ToString(), 1000, 0.1*COIN);
|
||||
mempool.PrioritiseTransaction(hashTx, hashTx.ToString(), 1000, 0.1*COIN);
|
||||
if(!lockMain || !AcceptToMemoryPool(mempool, validationState, finalTransaction, false, NULL, false, true, true))
|
||||
{
|
||||
LogPrintf("CDarksendPool::CheckFinalTransaction -- AcceptToMemoryPool() error: Transaction not valid\n");
|
||||
LogPrintf("CDarksendPool::CommitFinalTransaction -- AcceptToMemoryPool() error: Transaction not valid\n");
|
||||
SetNull();
|
||||
|
||||
// not much we can do in this case
|
||||
@ -590,18 +593,18 @@ void CDarksendPool::CheckFinalTransaction()
|
||||
}
|
||||
}
|
||||
|
||||
LogPrintf("CDarksendPool::CheckFinalTransaction -- CREATING DSTX\n");
|
||||
LogPrintf("CDarksendPool::CommitFinalTransaction -- CREATING DSTX\n");
|
||||
|
||||
// create and sign masternode dstx transaction
|
||||
if(!mapDarksendBroadcastTxes.count(finalTransaction.GetHash())) {
|
||||
if(!mapDarksendBroadcastTxes.count(hashTx)) {
|
||||
CDarksendBroadcastTx dstx(finalTransaction, activeMasternode.vin, GetAdjustedTime());
|
||||
dstx.Sign();
|
||||
mapDarksendBroadcastTxes.insert(std::make_pair(finalTransaction.GetHash(), dstx));
|
||||
mapDarksendBroadcastTxes.insert(std::make_pair(hashTx, dstx));
|
||||
}
|
||||
|
||||
LogPrintf("CDarksendPool::CheckFinalTransaction -- TRANSMITTING DSTX\n");
|
||||
LogPrintf("CDarksendPool::CommitFinalTransaction -- TRANSMITTING DSTX\n");
|
||||
|
||||
CInv inv(MSG_DSTX, finalTransaction.GetHash());
|
||||
CInv inv(MSG_DSTX, hashTx);
|
||||
RelayInv(inv);
|
||||
|
||||
// Tell the clients it was successful
|
||||
@ -611,7 +614,7 @@ void CDarksendPool::CheckFinalTransaction()
|
||||
ChargeRandomFees();
|
||||
|
||||
// Reset
|
||||
LogPrint("privatesend", "CDarksendPool::CheckFinalTransaction -- COMPLETED -- RESETTING\n");
|
||||
LogPrint("privatesend", "CDarksendPool::CommitFinalTransaction -- COMPLETED -- RESETTING\n");
|
||||
SetNull();
|
||||
RelayStatus(STATUS_SET_STATE);
|
||||
}
|
||||
@ -638,7 +641,7 @@ void CDarksendPool::ChargeFees()
|
||||
if(r > 33) return;
|
||||
|
||||
if(nState == POOL_STATE_ACCEPTING_ENTRIES) {
|
||||
BOOST_FOREACH(const CTransaction& txCollateral, vecSessionCollateral) {
|
||||
BOOST_FOREACH(const CTransaction& txCollateral, vecSessionCollaterals) {
|
||||
bool fFound = false;
|
||||
BOOST_FOREACH(const CDarkSendEntry& entry, vecEntries)
|
||||
if(entry.txCollateral == txCollateral)
|
||||
@ -678,7 +681,7 @@ void CDarksendPool::ChargeFees()
|
||||
if(nOffences > 1) nTarget = 50;
|
||||
|
||||
if(nState == POOL_STATE_ACCEPTING_ENTRIES) {
|
||||
BOOST_FOREACH(const CTransaction& txCollateral, vecSessionCollateral) {
|
||||
BOOST_FOREACH(const CTransaction& txCollateral, vecSessionCollaterals) {
|
||||
bool fFound = false;
|
||||
BOOST_FOREACH(const CDarkSendEntry& entry, vecEntries)
|
||||
if(entry.txCollateral == txCollateral)
|
||||
@ -740,7 +743,7 @@ void CDarksendPool::ChargeRandomFees()
|
||||
{
|
||||
if(!fMasterNode) return;
|
||||
|
||||
BOOST_FOREACH(const CTransaction& txCollateral, vecSessionCollateral) {
|
||||
BOOST_FOREACH(const CTransaction& txCollateral, vecSessionCollaterals) {
|
||||
int r = insecure_rand()%100;
|
||||
|
||||
if(r > 10) return;
|
||||
@ -852,7 +855,7 @@ void CDarksendPool::CheckForCompleteQueue()
|
||||
{
|
||||
if(!fEnablePrivateSend && !fMasterNode) return;
|
||||
|
||||
if(nState == POOL_STATE_QUEUE && nSessionUsers == GetMaxPoolTransactions()) {
|
||||
if(nState == POOL_STATE_QUEUE && IsSessionReady()) {
|
||||
SetState(POOL_STATE_ACCEPTING_ENTRIES);
|
||||
|
||||
CDarksendQueue dsq(nSessionDenom, activeMasternode.vin, GetTime(), true);
|
||||
@ -908,7 +911,7 @@ bool CDarksendPool::IsInputScriptSigValid(const CTxIn& txin)
|
||||
// check to make sure the collateral provided by the client is valid
|
||||
bool CDarksendPool::IsCollateralValid(const CTransaction& txCollateral)
|
||||
{
|
||||
if(txCollateral.vout.size() < 1) return false;
|
||||
if(txCollateral.vout.empty()) return false;
|
||||
if(txCollateral.nLockTime != 0) return false;
|
||||
|
||||
CAmount nValueIn = 0;
|
||||
@ -1084,10 +1087,6 @@ bool CDarksendPool::SendDenominate(const std::vector<CTxIn>& vecTxIn, const std:
|
||||
BOOST_FOREACH(CTxIn txin, vecTxIn)
|
||||
vecOutPointLocked.push_back(txin.prevout);
|
||||
|
||||
//BOOST_FOREACH(CTxOut o, vecTxOut)
|
||||
// LogPrintf(" vecTxOut - %s\n", o.ToString());
|
||||
|
||||
|
||||
// we should already be connected to a Masternode
|
||||
if(!fSessionFoundMasternode) {
|
||||
LogPrintf("CDarksendPool::SendDenominate -- No Masternode has been selected yet.\n");
|
||||
@ -1196,10 +1195,10 @@ bool CDarksendPool::UpdatePoolStateOnClient(PoolState nStateNew, int nEntriesCou
|
||||
//
|
||||
bool CDarksendPool::SignFinalTransaction(const CTransaction& finalTransactionNew, CNode* pnode)
|
||||
{
|
||||
if(fMasterNode) return false;
|
||||
if(fMasterNode || pnode == NULL) return false;
|
||||
|
||||
finalMutableTransaction = finalTransactionNew;
|
||||
LogPrintf("CDarksendPool::SignFinalTransaction -- %s", finalMutableTransaction.ToString());
|
||||
LogPrintf("CDarksendPool::SignFinalTransaction -- finalMutableTransaction=%s", finalMutableTransaction.ToString());
|
||||
|
||||
std::vector<CTxIn> sigs;
|
||||
|
||||
@ -1258,7 +1257,6 @@ bool CDarksendPool::SignFinalTransaction(const CTransaction& finalTransactionNew
|
||||
sigs.push_back(finalMutableTransaction.vin[nMyInputIndex]);
|
||||
LogPrint("privatesend", "CDarksendPool::SignFinalTransaction -- nMyInputIndex: %d, sigs.size(): %d, scriptSig=%s\n", nMyInputIndex, (int)sigs.size(), ScriptToAsmStr(finalMutableTransaction.vin[nMyInputIndex].scriptSig));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
LogPrint("privatesend", "CDarksendPool::SignFinalTransaction -- finalMutableTransaction=%s", finalMutableTransaction.ToString());
|
||||
@ -1523,8 +1521,10 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
|
||||
}
|
||||
}
|
||||
|
||||
int nMnCountEnabled = mnodeman.CountEnabled(MIN_PRIVATESEND_PEER_PROTO_VERSION);
|
||||
|
||||
// If we've used 90% of the Masternode list then drop the oldest first ~30%
|
||||
int nThreshold_high = (int)(mnodeman.CountEnabled(MIN_PRIVATESEND_PEER_PROTO_VERSION) * 0.9);
|
||||
int nThreshold_high = nMnCountEnabled * 0.9;
|
||||
int nThreshold_low = nThreshold_high * 0.7;
|
||||
LogPrint("privatesend", "Checking vecMasternodesUsed: size: %d, threshold: %d\n", (int)vecMasternodesUsed.size(), nThreshold_high);
|
||||
|
||||
@ -1542,12 +1542,13 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
|
||||
if(dsq.nTime == 0) continue;
|
||||
if(dsq.IsExpired()) continue;
|
||||
|
||||
CService addr;
|
||||
if(!dsq.GetAddress(addr)) continue;
|
||||
CMasternode* pmn = mnodeman.Find(dsq.vin);
|
||||
if(pmn == NULL) {
|
||||
LogPrintf("CDarksendPool::DoAutomaticDenominating -- dsq masternode is not in masternode list, masternode=%s\n", dsq.vin.prevout.ToStringShort());
|
||||
continue;
|
||||
}
|
||||
|
||||
int nProtocolVersion;
|
||||
if(!dsq.GetProtocolVersion(nProtocolVersion)) continue;
|
||||
if(nProtocolVersion < MIN_PRIVATESEND_PEER_PROTO_VERSION) continue;
|
||||
if(pmn->nProtocolVersion < MIN_PRIVATESEND_PEER_PROTO_VERSION) continue;
|
||||
|
||||
// incompatible denom
|
||||
if(dsq.nDenom >= (1 << vecPrivateSendDenominations.size())) continue;
|
||||
@ -1572,17 +1573,12 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
|
||||
continue;
|
||||
}
|
||||
|
||||
CMasternode* pmn = mnodeman.Find(dsq.vin);
|
||||
if(pmn == NULL) {
|
||||
LogPrintf("CDarksendPool::DoAutomaticDenominating -- dsq masternode is not in masternode list, masternode=%s\n", dsq.vin.prevout.ToStringShort());
|
||||
continue;
|
||||
}
|
||||
vecMasternodesUsed.push_back(dsq.vin);
|
||||
|
||||
LogPrintf("CDarksendPool::DoAutomaticDenominating -- attempt to connect to masternode from queue, addr=%s\n", pmn->addr.ToString());
|
||||
nLastTimeChanged = GetTimeMillis();
|
||||
// connect to Masternode and submit the queue request
|
||||
CNode* pnode = ConnectNode((CAddress)addr, NULL, true);
|
||||
CNode* pnode = ConnectNode((CAddress)pmn->addr, NULL, true);
|
||||
if(pnode) {
|
||||
pSubmittedToMasternode = pmn;
|
||||
nSessionDenom = dsq.nDenom;
|
||||
@ -1618,12 +1614,11 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
|
||||
}
|
||||
vecMasternodesUsed.push_back(pmn->vin);
|
||||
|
||||
int nFifthCompatible = mnodeman.CountEnabled(MIN_PRIVATESEND_PEER_PROTO_VERSION)/5;
|
||||
if(pmn->nLastDsq != 0 && pmn->nLastDsq + nFifthCompatible > mnodeman.nDsqCount) {
|
||||
if(pmn->nLastDsq != 0 && pmn->nLastDsq + nMnCountEnabled/5 > mnodeman.nDsqCount) {
|
||||
LogPrintf("CDarksendPool::DoAutomaticDenominating -- Too early to mix on this masternode!"
|
||||
" masternode=%s addr=%s nLastDsq=%d CountEnabled/5=%d nDsqCount=%d\n",
|
||||
pmn->vin.prevout.ToStringShort(), pmn->addr.ToString(), pmn->nLastDsq,
|
||||
nFifthCompatible, mnodeman.nDsqCount);
|
||||
nMnCountEnabled/5, mnodeman.nDsqCount);
|
||||
nTries++;
|
||||
continue;
|
||||
}
|
||||
@ -2070,7 +2065,7 @@ bool CDarksendPool::IsDenomCompatibleWithSession(int nDenom, CTransaction txColl
|
||||
}
|
||||
|
||||
SetState(POOL_STATE_QUEUE);
|
||||
vecSessionCollateral.push_back(txCollateral);
|
||||
vecSessionCollaterals.push_back(txCollateral);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2091,7 +2086,7 @@ bool CDarksendPool::IsDenomCompatibleWithSession(int nDenom, CTransaction txColl
|
||||
nMessageIDRet = MSG_NOERR;
|
||||
nSessionUsers++;
|
||||
nLastTimeChanged = GetTimeMillis();
|
||||
vecSessionCollateral.push_back(txCollateral);
|
||||
vecSessionCollaterals.push_back(txCollateral);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -2330,18 +2325,15 @@ bool CDarksendQueue::Sign()
|
||||
return false;
|
||||
}
|
||||
|
||||
return CheckSignature();
|
||||
return CheckSignature(activeMasternode.pubKeyMasternode);
|
||||
}
|
||||
|
||||
bool CDarksendQueue::CheckSignature()
|
||||
bool CDarksendQueue::CheckSignature(const CPubKey& pubKeyMasternode)
|
||||
{
|
||||
CMasternode* pmn = mnodeman.Find(vin);
|
||||
if(pmn == NULL) return false;
|
||||
|
||||
std::string strMessage = vin.ToString() + boost::lexical_cast<std::string>(nDenom) + boost::lexical_cast<std::string>(nTime) + boost::lexical_cast<std::string>(fReady);
|
||||
std::string strError = "";
|
||||
|
||||
if(!darkSendSigner.VerifyMessage(pmn->pubKeyMasternode, vchSig, strMessage, strError)) {
|
||||
if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
|
||||
LogPrintf("CDarksendQueue::CheckSignature -- Got bad Masternode queue signature: %s; error: %s\n", ToString(), strError);
|
||||
return false;
|
||||
}
|
||||
@ -2349,24 +2341,6 @@ bool CDarksendQueue::CheckSignature()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDarksendQueue::GetAddress(CService &addrRet)
|
||||
{
|
||||
CMasternode* pmn = mnodeman.Find(vin);
|
||||
if(pmn == NULL) return false;
|
||||
|
||||
addrRet = pmn->addr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDarksendQueue::GetProtocolVersion(int &nProtocolVersionRet)
|
||||
{
|
||||
CMasternode* pmn = mnodeman.Find(vin);
|
||||
if(pmn == NULL) return false;
|
||||
|
||||
nProtocolVersionRet = pmn->nProtocolVersion;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDarksendQueue::Relay()
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
@ -2388,18 +2362,15 @@ bool CDarksendBroadcastTx::Sign()
|
||||
return false;
|
||||
}
|
||||
|
||||
return CheckSignature();
|
||||
return CheckSignature(activeMasternode.pubKeyMasternode);
|
||||
}
|
||||
|
||||
bool CDarksendBroadcastTx::CheckSignature()
|
||||
bool CDarksendBroadcastTx::CheckSignature(const CPubKey& pubKeyMasternode)
|
||||
{
|
||||
CMasternode* pmn = mnodeman.Find(vin);
|
||||
if(pmn == NULL) return false;
|
||||
|
||||
std::string strMessage = tx.GetHash().ToString() + boost::lexical_cast<std::string>(sigTime);
|
||||
std::string strError = "";
|
||||
|
||||
if(!darkSendSigner.VerifyMessage(pmn->pubKeyMasternode, vchSig, strMessage, strError)) {
|
||||
if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
|
||||
LogPrintf("CDarksendBroadcastTx::CheckSignature -- Got bad dstx signature, error: %s\n", strError);
|
||||
return false;
|
||||
}
|
||||
|
@ -172,9 +172,6 @@ public:
|
||||
READWRITE(vchSig);
|
||||
}
|
||||
|
||||
bool GetAddress(CService &addrRet);
|
||||
bool GetProtocolVersion(int &nProtocolVersionRet);
|
||||
|
||||
/** Sign this mixing transaction
|
||||
* \return true if all conditions are met:
|
||||
* 1) we have an active Masternode,
|
||||
@ -184,7 +181,7 @@ public:
|
||||
*/
|
||||
bool Sign();
|
||||
/// Check if we have a valid Masternode address
|
||||
bool CheckSignature();
|
||||
bool CheckSignature(const CPubKey& pubKeyMasternode);
|
||||
|
||||
bool Relay();
|
||||
|
||||
@ -233,7 +230,7 @@ public:
|
||||
}
|
||||
|
||||
bool Sign();
|
||||
bool CheckSignature();
|
||||
bool CheckSignature(const CPubKey& pubKeyMasternode);
|
||||
};
|
||||
|
||||
/** Helper object for signing and checking signatures
|
||||
@ -317,7 +314,7 @@ private:
|
||||
std::vector<COutPoint> vecOutPointLocked;
|
||||
// Mixing uses collateral transactions to trust parties entering the pool
|
||||
// to behave honestly. If they don't it takes their money.
|
||||
std::vector<CTransaction> vecSessionCollateral;
|
||||
std::vector<CTransaction> vecSessionCollaterals;
|
||||
std::vector<CDarkSendEntry> vecEntries; // Masternode/clients entries
|
||||
|
||||
PoolState nState; // should be one of the POOL_STATE_XXX values
|
||||
@ -331,7 +328,7 @@ private:
|
||||
int nSessionUsers; //N Users have said they'll join
|
||||
bool fSessionFoundMasternode; //If we've found a compatible Masternode
|
||||
|
||||
unsigned int nEntriesCount;
|
||||
int nEntriesCount;
|
||||
bool fLastEntryAccepted;
|
||||
|
||||
std::string strLastMessage;
|
||||
@ -355,7 +352,8 @@ private:
|
||||
/// Check for process
|
||||
void CheckPool();
|
||||
|
||||
void CheckFinalTransaction();
|
||||
void CreateFinalTransaction();
|
||||
void CommitFinalTransaction();
|
||||
|
||||
void CompletedTransaction(bool fError, PoolMessage nMessageID);
|
||||
|
||||
|
@ -5726,7 +5726,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||
// we have no idea about (e.g we were offline)? How to handle them?
|
||||
}
|
||||
|
||||
if(!dstx.CheckSignature()) {
|
||||
if(!dstx.CheckSignature(pmn->pubKeyMasternode)) {
|
||||
LogPrint("privatesend", "DSTX -- CheckSignature() failed for %s\n", hashTx.ToString());
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user