Merge pull request #1134 from UdjinM6/PSFixes
Yet another PrivateSend refactoring/optimization - core part
This commit is contained in:
commit
5128085240
299
src/darksend.cpp
299
src/darksend.cpp
@ -76,7 +76,10 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
|||||||
}
|
}
|
||||||
|
|
||||||
PoolMessage nMessageID = MSG_NOERR;
|
PoolMessage nMessageID = MSG_NOERR;
|
||||||
if(IsDenomCompatibleWithSession(nDenom, txCollateral, nMessageID)) {
|
|
||||||
|
bool fResult = nSessionID == 0 ? CreateNewSession(nDenom, txCollateral, nMessageID)
|
||||||
|
: AddUserToExistingSession(nDenom, txCollateral, nMessageID);
|
||||||
|
if(fResult) {
|
||||||
LogPrintf("DSACCEPT -- is compatible, please submit!\n");
|
LogPrintf("DSACCEPT -- is compatible, please submit!\n");
|
||||||
PushStatus(pfrom, STATUS_ACCEPTED, nMessageID);
|
PushStatus(pfrom, STATUS_ACCEPTED, nMessageID);
|
||||||
return;
|
return;
|
||||||
@ -263,9 +266,10 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
|||||||
if(AddEntry(entry, nMessageID)) {
|
if(AddEntry(entry, nMessageID)) {
|
||||||
PushStatus(pfrom, STATUS_ACCEPTED, nMessageID);
|
PushStatus(pfrom, STATUS_ACCEPTED, nMessageID);
|
||||||
CheckPool();
|
CheckPool();
|
||||||
RelayStatus(STATUS_SET_STATE);
|
RelayStatus(STATUS_ACCEPTED);
|
||||||
} else {
|
} else {
|
||||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID);
|
PushStatus(pfrom, STATUS_REJECTED, nMessageID);
|
||||||
|
SetNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(strCommand == NetMsgType::DSSTATUSUPDATE) {
|
} else if(strCommand == NetMsgType::DSSTATUSUPDATE) {
|
||||||
@ -301,25 +305,23 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nMsgStatusUpdate < STATUS_SET_STATE || nMsgStatusUpdate > STATUS_ACCEPTED) {
|
if(nMsgStatusUpdate < STATUS_REJECTED || nMsgStatusUpdate > STATUS_ACCEPTED) {
|
||||||
LogPrint("privatesend", "DSSTATUSUPDATE -- nMsgStatusUpdate is out of bounds: %d\n", nMsgStatusUpdate);
|
LogPrint("privatesend", "DSSTATUSUPDATE -- nMsgStatusUpdate is out of bounds: %d\n", nMsgStatusUpdate);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nMsgMessageID < MSG_POOL_MIN || nMsgMessageID > MSG_POOL_MAX) {
|
if(nMsgMessageID < MSG_POOL_MIN || nMsgMessageID > MSG_POOL_MAX) {
|
||||||
LogPrint("privatesend", "DSSTATUSUPDATE -- nMsgMessageID is out of bounds: %d\n", nMsgMessageID);
|
LogPrint("privatesend", "DSSTATUSUPDATE -- nMsgMessageID is out of bounds: %d\n", nMsgMessageID);
|
||||||
|
if(pfrom->nVersion < 70203) nMsgMessageID = MSG_NOERR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrint("privatesend", "DSSTATUSUPDATE -- GetMessageByID: %s\n", GetMessageByID(PoolMessage(nMsgMessageID)));
|
LogPrint("privatesend", "DSSTATUSUPDATE -- GetMessageByID: %s\n", GetMessageByID(PoolMessage(nMsgMessageID)));
|
||||||
|
|
||||||
if(nMsgStatusUpdate == STATUS_SET_STATE && nSessionID != nMsgSessionID) {
|
if(!CheckPoolStateUpdate(PoolState(nMsgState), nMsgEntriesCount, PoolStatusUpdate(nMsgStatusUpdate), PoolMessage(nMsgMessageID), nMsgSessionID)) {
|
||||||
LogPrint("privatesend", "DSSTATUSUPDATE -- message doesn't match current PrivateSend session: nSessionID: %d nMsgSessionID: %d\n", nSessionID, nMsgSessionID);
|
LogPrint("privatesend", "DSSTATUSUPDATE -- CheckPoolStateUpdate failed\n");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdatePoolStateOnClient(PoolState(nMsgState), nMsgEntriesCount, PoolStatusUpdate(nMsgStatusUpdate), PoolMessage(nMsgMessageID), nMsgSessionID);
|
|
||||||
|
|
||||||
} else if(strCommand == NetMsgType::DSSIGNFINALTX) {
|
} else if(strCommand == NetMsgType::DSSIGNFINALTX) {
|
||||||
|
|
||||||
if(pfrom->nVersion < MIN_PRIVATESEND_PEER_PROTO_VERSION) {
|
if(pfrom->nVersion < MIN_PRIVATESEND_PEER_PROTO_VERSION) {
|
||||||
@ -344,13 +346,13 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS
|
|||||||
nTxInIndex++;
|
nTxInIndex++;
|
||||||
if(!AddScriptSig(txin)) {
|
if(!AddScriptSig(txin)) {
|
||||||
LogPrint("privatesend", "DSSIGNFINALTX -- AddScriptSig() failed at %d/%d, session: %d\n", nTxInIndex, nTxInsCount, nSessionID);
|
LogPrint("privatesend", "DSSIGNFINALTX -- AddScriptSig() failed at %d/%d, session: %d\n", nTxInIndex, nTxInsCount, nSessionID);
|
||||||
|
RelayStatus(STATUS_REJECTED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogPrint("privatesend", "DSSIGNFINALTX -- AddScriptSig() %d/%d success\n", nTxInIndex, nTxInsCount);
|
LogPrint("privatesend", "DSSIGNFINALTX -- AddScriptSig() %d/%d success\n", nTxInIndex, nTxInsCount);
|
||||||
}
|
}
|
||||||
// all is good
|
// all is good
|
||||||
CheckPool();
|
CheckPool();
|
||||||
RelayStatus(STATUS_SET_STATE);
|
|
||||||
|
|
||||||
} else if(strCommand == NetMsgType::DSFINALTX) {
|
} else if(strCommand == NetMsgType::DSFINALTX) {
|
||||||
|
|
||||||
@ -456,13 +458,12 @@ void CDarksendPool::ResetPool()
|
|||||||
void CDarksendPool::SetNull()
|
void CDarksendPool::SetNull()
|
||||||
{
|
{
|
||||||
// MN side
|
// MN side
|
||||||
nSessionUsers = 0;
|
|
||||||
vecSessionCollaterals.clear();
|
vecSessionCollaterals.clear();
|
||||||
|
|
||||||
// Client side
|
// Client side
|
||||||
nEntriesCount = 0;
|
nEntriesCount = 0;
|
||||||
fLastEntryAccepted = false;
|
fLastEntryAccepted = false;
|
||||||
fSessionFoundMasternode = false;
|
pSubmittedToMasternode = NULL;
|
||||||
|
|
||||||
// Both sides
|
// Both sides
|
||||||
nState = POOL_STATE_IDLE;
|
nState = POOL_STATE_IDLE;
|
||||||
@ -471,7 +472,7 @@ void CDarksendPool::SetNull()
|
|||||||
vecEntries.clear();
|
vecEntries.clear();
|
||||||
finalMutableTransaction.vin.clear();
|
finalMutableTransaction.vin.clear();
|
||||||
finalMutableTransaction.vout.clear();
|
finalMutableTransaction.vout.clear();
|
||||||
nLastTimeChanged = GetTimeMillis();
|
nTimeLastSuccessfulStep = GetTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -530,10 +531,6 @@ std::string CDarksendPool::GetStatus()
|
|||||||
else if(nStatusMessageProgress % 70 <= 60) strSuffix = "..";
|
else if(nStatusMessageProgress % 70 <= 60) strSuffix = "..";
|
||||||
else if(nStatusMessageProgress % 70 <= 70) strSuffix = "...";
|
else if(nStatusMessageProgress % 70 <= 70) strSuffix = "...";
|
||||||
return strprintf(_("Found enough users, signing ( waiting %s )"), strSuffix);
|
return strprintf(_("Found enough users, signing ( waiting %s )"), strSuffix);
|
||||||
case POOL_STATE_TRANSMISSION:
|
|
||||||
return _("Transmitting final transaction.");
|
|
||||||
case POOL_STATE_FINALIZE_TRANSACTION:
|
|
||||||
return _("Finalizing transaction.");
|
|
||||||
case POOL_STATE_ERROR:
|
case POOL_STATE_ERROR:
|
||||||
return _("PrivateSend request incomplete:") + " " + strLastMessage + " " + _("Will retry...");
|
return _("PrivateSend request incomplete:") + " " + strLastMessage + " " + _("Will retry...");
|
||||||
case POOL_STATE_SUCCESS:
|
case POOL_STATE_SUCCESS:
|
||||||
@ -551,33 +548,26 @@ void CDarksendPool::CheckPool()
|
|||||||
if(fMasterNode) {
|
if(fMasterNode) {
|
||||||
LogPrint("privatesend", "CDarksendPool::CheckPool -- entries count %lu\n", GetEntriesCount());
|
LogPrint("privatesend", "CDarksendPool::CheckPool -- entries count %lu\n", GetEntriesCount());
|
||||||
|
|
||||||
// If entries are full, then move on to the next phase
|
// If entries are full, create finalized transaction
|
||||||
if(nState == POOL_STATE_ACCEPTING_ENTRIES && GetEntriesCount() >= GetMaxPoolTransactions()) {
|
if(nState == POOL_STATE_ACCEPTING_ENTRIES && GetEntriesCount() >= GetMaxPoolTransactions()) {
|
||||||
LogPrint("privatesend", "CDarksendPool::CheckPool -- TRYING TRANSACTION\n");
|
LogPrint("privatesend", "CDarksendPool::CheckPool -- FINALIZE TRANSACTIONS\n");
|
||||||
SetState(POOL_STATE_FINALIZE_TRANSACTION);
|
CreateFinalTransaction();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// create the finalized transaction for distribution to the clients
|
// If we have all of the signatures, try to compile the transaction
|
||||||
if(nState == POOL_STATE_FINALIZE_TRANSACTION) {
|
if(nState == POOL_STATE_SIGNING && IsSignaturesComplete()) {
|
||||||
CreateFinalTransaction();
|
LogPrint("privatesend", "CDarksendPool::CheckPool -- SIGNING\n");
|
||||||
}
|
CommitFinalTransaction();
|
||||||
|
return;
|
||||||
// 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);
|
|
||||||
CommitFinalTransaction();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset if we're here for 10 seconds
|
// reset if we're here for 10 seconds
|
||||||
if((nState == POOL_STATE_ERROR || nState == POOL_STATE_SUCCESS) && GetTimeMillis() - nLastTimeChanged >= 10000) {
|
if((nState == POOL_STATE_ERROR || nState == POOL_STATE_SUCCESS) && GetTimeMillis() - nTimeLastSuccessfulStep >= 10000) {
|
||||||
LogPrint("privatesend", "CDarksendPool::CheckPool -- timeout, RESETTING\n");
|
LogPrint("privatesend", "CDarksendPool::CheckPool -- timeout, RESETTING\n");
|
||||||
UnlockCoins();
|
UnlockCoins();
|
||||||
SetNull();
|
SetNull();
|
||||||
if(fMasterNode) {
|
|
||||||
RelayStatus(STATUS_SET_STATE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,9 +616,7 @@ void CDarksendPool::CommitFinalTransaction()
|
|||||||
{
|
{
|
||||||
LogPrintf("CDarksendPool::CommitFinalTransaction -- AcceptToMemoryPool() error: Transaction not valid\n");
|
LogPrintf("CDarksendPool::CommitFinalTransaction -- AcceptToMemoryPool() error: Transaction not valid\n");
|
||||||
SetNull();
|
SetNull();
|
||||||
|
// not much we can do in this case, just notify clients
|
||||||
// not much we can do in this case
|
|
||||||
SetState(POOL_STATE_ACCEPTING_ENTRIES);
|
|
||||||
RelayCompletedTransaction(ERR_INVALID_TX);
|
RelayCompletedTransaction(ERR_INVALID_TX);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -657,7 +645,6 @@ void CDarksendPool::CommitFinalTransaction()
|
|||||||
// Reset
|
// Reset
|
||||||
LogPrint("privatesend", "CDarksendPool::CommitFinalTransaction -- COMPLETED -- RESETTING\n");
|
LogPrint("privatesend", "CDarksendPool::CommitFinalTransaction -- COMPLETED -- RESETTING\n");
|
||||||
SetNull();
|
SetNull();
|
||||||
RelayStatus(STATUS_SET_STATE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -787,10 +774,6 @@ void CDarksendPool::CheckTimeout()
|
|||||||
// catching hanging sessions
|
// catching hanging sessions
|
||||||
if(!fMasterNode) {
|
if(!fMasterNode) {
|
||||||
switch(nState) {
|
switch(nState) {
|
||||||
case POOL_STATE_TRANSMISSION:
|
|
||||||
LogPrint("privatesend", "CDarksendPool::CheckTimeout -- Session complete -- Running CheckPool\n");
|
|
||||||
CheckPool();
|
|
||||||
break;
|
|
||||||
case POOL_STATE_ERROR:
|
case POOL_STATE_ERROR:
|
||||||
LogPrint("privatesend", "CDarksendPool::CheckTimeout -- Pool error -- Running CheckPool\n");
|
LogPrint("privatesend", "CDarksendPool::CheckTimeout -- Pool error -- Running CheckPool\n");
|
||||||
CheckPool();
|
CheckPool();
|
||||||
@ -804,50 +787,18 @@ void CDarksendPool::CheckTimeout()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int nLagTime = 0;
|
int nLagTime = fMasterNode ? 0 : 10000; // if we're the client, give the server a few extra seconds before resetting.
|
||||||
if(!fMasterNode) nLagTime = 10000; //if we're the client, give the server a few extra seconds before resetting.
|
int nTimeout = (nState == POOL_STATE_SIGNING) ? PRIVATESEND_SIGNING_TIMEOUT : PRIVATESEND_QUEUE_TIMEOUT;
|
||||||
|
bool fTimeout = GetTimeMillis() - nTimeLastSuccessfulStep >= nTimeout*1000 + nLagTime;
|
||||||
|
|
||||||
if(nState == POOL_STATE_ACCEPTING_ENTRIES || nState == POOL_STATE_QUEUE) {
|
if(nState != POOL_STATE_IDLE && fTimeout) {
|
||||||
int c = 0;
|
LogPrint("privatesend", "CDarksendPool::CheckTimeout -- %s timed out (%ds) -- restting\n",
|
||||||
|
(nState == POOL_STATE_SIGNING) ? "Signing" : "Session", nTimeout);
|
||||||
// check for a timeout and reset if needed
|
|
||||||
std::vector<CDarkSendEntry>::iterator it2 = vecEntries.begin();
|
|
||||||
while(it2 != vecEntries.end()) {
|
|
||||||
if((*it2).IsExpired()) {
|
|
||||||
LogPrint("privatesend", "CDarksendPool::CheckTimeout -- Removing expired entry: %d\n", c);
|
|
||||||
it2 = vecEntries.erase(it2);
|
|
||||||
if(GetEntriesCount() == 0) {
|
|
||||||
UnlockCoins();
|
|
||||||
SetNull();
|
|
||||||
}
|
|
||||||
if(fMasterNode) {
|
|
||||||
RelayStatus(STATUS_SET_STATE);
|
|
||||||
}
|
|
||||||
} else ++it2;
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(GetTimeMillis() - nLastTimeChanged >= PRIVATESEND_QUEUE_TIMEOUT*1000 + nLagTime) {
|
|
||||||
UnlockCoins();
|
|
||||||
SetNull();
|
|
||||||
}
|
|
||||||
} else if (GetTimeMillis() - nLastTimeChanged >= PRIVATESEND_QUEUE_TIMEOUT*1000 + nLagTime) {
|
|
||||||
LogPrint("privatesend", "CDarksendPool::CheckTimeout -- Session timed out (%ds) -- resetting\n", PRIVATESEND_QUEUE_TIMEOUT);
|
|
||||||
UnlockCoins();
|
|
||||||
SetNull();
|
|
||||||
|
|
||||||
SetState(POOL_STATE_ERROR);
|
|
||||||
strLastMessage = _("Session timed out.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(nState == POOL_STATE_SIGNING && GetTimeMillis() - nLastTimeChanged >= PRIVATESEND_SIGNING_TIMEOUT*1000 + nLagTime) {
|
|
||||||
LogPrint("privatesend", "CDarksendPool::CheckTimeout -- Session timed out (%ds) -- restting\n", PRIVATESEND_SIGNING_TIMEOUT);
|
|
||||||
ChargeFees();
|
ChargeFees();
|
||||||
UnlockCoins();
|
UnlockCoins();
|
||||||
SetNull();
|
SetNull();
|
||||||
|
|
||||||
SetState(POOL_STATE_ERROR);
|
SetState(POOL_STATE_ERROR);
|
||||||
strLastMessage = _("Signing timed out.");
|
strLastMessage = _("Session timed out.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -980,7 +931,6 @@ bool CDarksendPool::AddEntry(const CDarkSendEntry& entryNew, PoolMessage& nMessa
|
|||||||
if(txin.prevout.IsNull()) {
|
if(txin.prevout.IsNull()) {
|
||||||
LogPrint("privatesend", "CDarksendPool::AddEntry -- input not valid!\n");
|
LogPrint("privatesend", "CDarksendPool::AddEntry -- input not valid!\n");
|
||||||
nMessageIDRet = ERR_INVALID_INPUT;
|
nMessageIDRet = ERR_INVALID_INPUT;
|
||||||
nSessionUsers--;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -988,14 +938,12 @@ bool CDarksendPool::AddEntry(const CDarkSendEntry& entryNew, PoolMessage& nMessa
|
|||||||
if(!IsCollateralValid(entryNew.txCollateral)) {
|
if(!IsCollateralValid(entryNew.txCollateral)) {
|
||||||
LogPrint("privatesend", "CDarksendPool::AddEntry -- collateral not valid!\n");
|
LogPrint("privatesend", "CDarksendPool::AddEntry -- collateral not valid!\n");
|
||||||
nMessageIDRet = ERR_INVALID_COLLATERAL;
|
nMessageIDRet = ERR_INVALID_COLLATERAL;
|
||||||
nSessionUsers--;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetEntriesCount() >= GetMaxPoolTransactions()) {
|
if(GetEntriesCount() >= GetMaxPoolTransactions()) {
|
||||||
LogPrint("privatesend", "CDarksendPool::AddEntry -- entries is full!\n");
|
LogPrint("privatesend", "CDarksendPool::AddEntry -- entries is full!\n");
|
||||||
nMessageIDRet = ERR_ENTRIES_FULL;
|
nMessageIDRet = ERR_ENTRIES_FULL;
|
||||||
nSessionUsers--;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1006,7 +954,6 @@ bool CDarksendPool::AddEntry(const CDarkSendEntry& entryNew, PoolMessage& nMessa
|
|||||||
if(txdsin.prevout == txin.prevout) {
|
if(txdsin.prevout == txin.prevout) {
|
||||||
LogPrint("privatesend", "CDarksendPool::AddEntry -- found in txin\n");
|
LogPrint("privatesend", "CDarksendPool::AddEntry -- found in txin\n");
|
||||||
nMessageIDRet = ERR_ALREADY_HAVE;
|
nMessageIDRet = ERR_ALREADY_HAVE;
|
||||||
nSessionUsers--;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1017,6 +964,7 @@ bool CDarksendPool::AddEntry(const CDarkSendEntry& entryNew, PoolMessage& nMessa
|
|||||||
|
|
||||||
LogPrint("privatesend", "CDarksendPool::AddEntry -- adding entry\n");
|
LogPrint("privatesend", "CDarksendPool::AddEntry -- adding entry\n");
|
||||||
nMessageIDRet = MSG_ENTRIES_ADDED;
|
nMessageIDRet = MSG_ENTRIES_ADDED;
|
||||||
|
nTimeLastSuccessfulStep = GetTimeMillis();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1093,7 +1041,7 @@ bool CDarksendPool::SendDenominate(const std::vector<CTxIn>& vecTxIn, const std:
|
|||||||
vecOutPointLocked.push_back(txin.prevout);
|
vecOutPointLocked.push_back(txin.prevout);
|
||||||
|
|
||||||
// we should already be connected to a Masternode
|
// we should already be connected to a Masternode
|
||||||
if(!fSessionFoundMasternode) {
|
if(!nSessionID) {
|
||||||
LogPrintf("CDarksendPool::SendDenominate -- No Masternode has been selected yet.\n");
|
LogPrintf("CDarksendPool::SendDenominate -- No Masternode has been selected yet.\n");
|
||||||
UnlockCoins();
|
UnlockCoins();
|
||||||
SetNull();
|
SetNull();
|
||||||
@ -1143,54 +1091,51 @@ bool CDarksendPool::SendDenominate(const std::vector<CTxIn>& vecTxIn, const std:
|
|||||||
// store our entry for later use
|
// store our entry for later use
|
||||||
CDarkSendEntry entry(vecTxIn, vecTxOut, txMyCollateral);
|
CDarkSendEntry entry(vecTxIn, vecTxOut, txMyCollateral);
|
||||||
vecEntries.push_back(entry);
|
vecEntries.push_back(entry);
|
||||||
|
|
||||||
RelayIn(entry);
|
RelayIn(entry);
|
||||||
CheckPool();
|
nTimeLastSuccessfulStep = GetTimeMillis();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Incoming message from Masternode updating the progress of mixing
|
// Incoming message from Masternode updating the progress of mixing
|
||||||
bool CDarksendPool::UpdatePoolStateOnClient(PoolState nStateNew, int nEntriesCountNew, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID, int nSessionIDNew)
|
bool CDarksendPool::CheckPoolStateUpdate(PoolState nStateNew, int nEntriesCountNew, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID, int nSessionIDNew)
|
||||||
{
|
{
|
||||||
if(fMasterNode) return false;
|
if(fMasterNode) return false;
|
||||||
if(nState == POOL_STATE_ERROR || nState == POOL_STATE_SUCCESS) return false;
|
|
||||||
|
|
||||||
SetState(nStateNew);
|
// do not update state when mixing client state is one of these
|
||||||
nEntriesCount = nEntriesCountNew;
|
if(nState == POOL_STATE_IDLE || nState == POOL_STATE_ERROR || nState == POOL_STATE_SUCCESS) return false;
|
||||||
|
|
||||||
strAutoDenomResult = _("Masternode:") + " " + GetMessageByID(nMessageID);
|
strAutoDenomResult = _("Masternode:") + " " + GetMessageByID(nMessageID);
|
||||||
|
|
||||||
if(nStatusUpdate != STATUS_SET_STATE) {
|
// if rejected at any state
|
||||||
fLastEntryAccepted = nStatusUpdate;
|
if(nStatusUpdate == STATUS_REJECTED) {
|
||||||
if(nStatusUpdate == STATUS_REJECTED) {
|
LogPrintf("CDarksendPool::CheckPoolStateUpdate -- entry is rejected by Masternode\n");
|
||||||
SetState(POOL_STATE_ERROR);
|
UnlockCoins();
|
||||||
strLastMessage = GetMessageByID(nMessageID);
|
SetNull();
|
||||||
}
|
SetState(POOL_STATE_ERROR);
|
||||||
|
strLastMessage = GetMessageByID(nMessageID);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if(nStatusUpdate == STATUS_ACCEPTED && nSessionIDNew != 0) {
|
if(nStatusUpdate == STATUS_ACCEPTED && nState == nStateNew) {
|
||||||
|
if(nStateNew == POOL_STATE_QUEUE && nSessionID == 0 && nSessionIDNew != 0) {
|
||||||
|
// new session id should be set only in POOL_STATE_QUEUE state
|
||||||
nSessionID = nSessionIDNew;
|
nSessionID = nSessionIDNew;
|
||||||
LogPrintf("CDarksendPool::UpdatePoolStateOnClient -- set nSessionID to %d\n", nSessionID);
|
nTimeLastSuccessfulStep = GetTimeMillis();
|
||||||
fSessionFoundMasternode = true;
|
LogPrintf("CDarksendPool::CheckPoolStateUpdate -- set nSessionID to %d\n", nSessionID);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(nStateNew == POOL_STATE_ACCEPTING_ENTRIES && nEntriesCount != nEntriesCountNew) {
|
||||||
|
nEntriesCount = nEntriesCountNew;
|
||||||
|
nTimeLastSuccessfulStep = GetTimeMillis();
|
||||||
|
fLastEntryAccepted = true;
|
||||||
|
LogPrintf("CDarksendPool::CheckPoolStateUpdate -- new entry accepted!\n");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nStateNew == POOL_STATE_ACCEPTING_ENTRIES) {
|
// only situations above are allowed, fail in any other case
|
||||||
if(nStatusUpdate == STATUS_ACCEPTED) {
|
return false;
|
||||||
LogPrintf("CDarksendPool::UpdatePoolStateOnClient -- entry accepted!\n");
|
|
||||||
fSessionFoundMasternode = true;
|
|
||||||
//wait for other users. Masternode will report when ready
|
|
||||||
SetState(POOL_STATE_QUEUE);
|
|
||||||
} else if(nStatusUpdate == STATUS_REJECTED && nSessionID == 0 && !fSessionFoundMasternode) {
|
|
||||||
LogPrintf("CDarksendPool::UpdatePoolStateOnClient -- entry not accepted by Masternode\n");
|
|
||||||
UnlockCoins();
|
|
||||||
SetState(POOL_STATE_ACCEPTING_ENTRIES);
|
|
||||||
DoAutomaticDenominating(); //try another Masternode
|
|
||||||
}
|
|
||||||
if(fSessionFoundMasternode) return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -1274,8 +1219,10 @@ bool CDarksendPool::SignFinalTransaction(const CTransaction& finalTransactionNew
|
|||||||
}
|
}
|
||||||
|
|
||||||
// push all of our signatures to the Masternode
|
// push all of our signatures to the Masternode
|
||||||
if(!sigs.empty() && pnode != NULL)
|
LogPrintf("CDarksendPool::SignFinalTransaction -- pushing sigs to the masternode, finalMutableTransaction=%s", finalMutableTransaction.ToString());
|
||||||
pnode->PushMessage(NetMsgType::DSSIGNFINALTX, sigs);
|
pnode->PushMessage(NetMsgType::DSSIGNFINALTX, sigs);
|
||||||
|
SetState(POOL_STATE_SIGNING);
|
||||||
|
nTimeLastSuccessfulStep = GetTimeMillis();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1488,7 +1435,7 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
|
|||||||
if(!pwalletMain->HasCollateralInputs())
|
if(!pwalletMain->HasCollateralInputs())
|
||||||
return !pwalletMain->HasCollateralInputs(false) && MakeCollateralAmounts();
|
return !pwalletMain->HasCollateralInputs(false) && MakeCollateralAmounts();
|
||||||
|
|
||||||
if(fSessionFoundMasternode) {
|
if(nSessionID) {
|
||||||
strAutoDenomResult = _("Mixing in progress...");
|
strAutoDenomResult = _("Mixing in progress...");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1498,8 +1445,6 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
|
|||||||
UnlockCoins();
|
UnlockCoins();
|
||||||
SetNull();
|
SetNull();
|
||||||
|
|
||||||
SetState(POOL_STATE_ACCEPTING_ENTRIES);
|
|
||||||
|
|
||||||
if(!fPrivateSendMultiSession && pwalletMain->GetDenominatedBalance(true) > 0) { //get denominated unconfirmed inputs
|
if(!fPrivateSendMultiSession && pwalletMain->GetDenominatedBalance(true) > 0) { //get denominated unconfirmed inputs
|
||||||
LogPrintf("CDarksendPool::DoAutomaticDenominating -- Found unconfirmed denominated outputs, will wait till they confirm to continue.\n");
|
LogPrintf("CDarksendPool::DoAutomaticDenominating -- Found unconfirmed denominated outputs, will wait till they confirm to continue.\n");
|
||||||
strAutoDenomResult = _("Found unconfirmed denominated outputs, will wait till they confirm to continue.");
|
strAutoDenomResult = _("Found unconfirmed denominated outputs, will wait till they confirm to continue.");
|
||||||
@ -1544,6 +1489,7 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
|
|||||||
// only try each queue once
|
// only try each queue once
|
||||||
if(dsq.fTried) continue;
|
if(dsq.fTried) continue;
|
||||||
dsq.fTried = true;
|
dsq.fTried = true;
|
||||||
|
|
||||||
if(dsq.IsExpired()) continue;
|
if(dsq.IsExpired()) continue;
|
||||||
|
|
||||||
CMasternode* pmn = mnodeman.Find(dsq.vin);
|
CMasternode* pmn = mnodeman.Find(dsq.vin);
|
||||||
@ -1574,7 +1520,6 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
|
|||||||
vecMasternodesUsed.push_back(dsq.vin);
|
vecMasternodesUsed.push_back(dsq.vin);
|
||||||
|
|
||||||
LogPrintf("CDarksendPool::DoAutomaticDenominating -- attempt to connect to masternode from queue, addr=%s\n", pmn->addr.ToString());
|
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
|
// connect to Masternode and submit the queue request
|
||||||
CNode* pnode = ConnectNode((CAddress)pmn->addr, NULL, true);
|
CNode* pnode = ConnectNode((CAddress)pmn->addr, NULL, true);
|
||||||
if(pnode) {
|
if(pnode) {
|
||||||
@ -1585,6 +1530,8 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
|
|||||||
LogPrintf("CDarksendPool::DoAutomaticDenominating -- connected (from queue), sending DSACCEPT: nSessionDenom: %d (%s), addr=%s\n",
|
LogPrintf("CDarksendPool::DoAutomaticDenominating -- connected (from queue), sending DSACCEPT: nSessionDenom: %d (%s), addr=%s\n",
|
||||||
nSessionDenom, GetDenominationsToString(nSessionDenom), pnode->addr.ToString());
|
nSessionDenom, GetDenominationsToString(nSessionDenom), pnode->addr.ToString());
|
||||||
strAutoDenomResult = _("Mixing in progress...");
|
strAutoDenomResult = _("Mixing in progress...");
|
||||||
|
SetState(POOL_STATE_QUEUE);
|
||||||
|
nTimeLastSuccessfulStep = GetTimeMillis();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
LogPrintf("CDarksendPool::DoAutomaticDenominating -- can't connect, addr=%s\n", pmn->addr.ToString());
|
LogPrintf("CDarksendPool::DoAutomaticDenominating -- can't connect, addr=%s\n", pmn->addr.ToString());
|
||||||
@ -1619,7 +1566,6 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
nLastTimeChanged = GetTimeMillis();
|
|
||||||
LogPrintf("CDarksendPool::DoAutomaticDenominating -- attempt %d connection to Masternode %s\n", nTries, pmn->addr.ToString());
|
LogPrintf("CDarksendPool::DoAutomaticDenominating -- attempt %d connection to Masternode %s\n", nTries, pmn->addr.ToString());
|
||||||
CNode* pnode = ConnectNode((CAddress)pmn->addr, NULL, true);
|
CNode* pnode = ConnectNode((CAddress)pmn->addr, NULL, true);
|
||||||
if(pnode) {
|
if(pnode) {
|
||||||
@ -1637,6 +1583,8 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
|
|||||||
LogPrintf("CDarksendPool::DoAutomaticDenominating -- connected, sending DSACCEPT, nSessionDenom: %d (%s)\n",
|
LogPrintf("CDarksendPool::DoAutomaticDenominating -- connected, sending DSACCEPT, nSessionDenom: %d (%s)\n",
|
||||||
nSessionDenom, GetDenominationsToString(nSessionDenom));
|
nSessionDenom, GetDenominationsToString(nSessionDenom));
|
||||||
strAutoDenomResult = _("Mixing in progress...");
|
strAutoDenomResult = _("Mixing in progress...");
|
||||||
|
SetState(POOL_STATE_QUEUE);
|
||||||
|
nTimeLastSuccessfulStep = GetTimeMillis();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
LogPrintf("CDarksendPool::DoAutomaticDenominating -- can't connect, addr=%s\n", pmn->addr.ToString());
|
LogPrintf("CDarksendPool::DoAutomaticDenominating -- can't connect, addr=%s\n", pmn->addr.ToString());
|
||||||
@ -2027,63 +1975,98 @@ bool CDarksendPool::IsOutputsCompatibleWithSessionDenom(const std::vector<CTxDSO
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDarksendPool::IsDenomCompatibleWithSession(int nDenom, CTransaction txCollateral, PoolMessage& nMessageIDRet)
|
bool CDarksendPool::IsAcceptableDenomAndCollateral(int nDenom, CTransaction txCollateral, PoolMessage& nMessageIDRet)
|
||||||
{
|
{
|
||||||
if(nDenom == 0) {
|
if(!fMasterNode) return false;
|
||||||
|
|
||||||
|
// is denom even smth legit?
|
||||||
|
std::vector<int> vecBits;
|
||||||
|
if(!GetDenominationsBits(nDenom, vecBits)) {
|
||||||
|
LogPrint("privatesend", "CDarksendPool::IsAcceptableDenomAndCollateral -- denom not valid!\n");
|
||||||
nMessageIDRet = ERR_DENOM;
|
nMessageIDRet = ERR_DENOM;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrintf("CDarksendPool::IsDenomCompatibleWithSession -- nSessionDenom: %d (%s) nSessionUsers: %d\n",
|
// check collateral
|
||||||
nSessionDenom, GetDenominationsToString(nSessionDenom), nSessionUsers);
|
|
||||||
|
|
||||||
if(!fUnitTest && !IsCollateralValid(txCollateral)) {
|
if(!fUnitTest && !IsCollateralValid(txCollateral)) {
|
||||||
LogPrint("privatesend", "CDarksendPool::IsDenomCompatibleWithSession -- collateral not valid!\n");
|
LogPrint("privatesend", "CDarksendPool::IsAcceptableDenomAndCollateral -- collateral not valid!\n");
|
||||||
nMessageIDRet = ERR_INVALID_COLLATERAL;
|
nMessageIDRet = ERR_INVALID_COLLATERAL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nSessionUsers < 0) nSessionUsers = 0;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if(nSessionUsers == 0) {
|
bool CDarksendPool::CreateNewSession(int nDenom, CTransaction txCollateral, PoolMessage& nMessageIDRet)
|
||||||
nMessageIDRet = MSG_NOERR;
|
{
|
||||||
nSessionID = GetInsecureRand(999999)+1;
|
if(!fMasterNode || nSessionID != 0) return false;
|
||||||
nSessionDenom = nDenom;
|
|
||||||
nSessionUsers++;
|
|
||||||
nLastTimeChanged = GetTimeMillis();
|
|
||||||
|
|
||||||
if(!fUnitTest) {
|
// new session can only be started in idle mode
|
||||||
//broadcast that I'm accepting entries, only if it's the first entry through
|
if(nState != POOL_STATE_IDLE) {
|
||||||
CDarksendQueue dsq(nDenom, activeMasternode.vin, GetTime(), false);
|
nMessageIDRet = ERR_MODE;
|
||||||
LogPrint("privatesend", "CDarksendPool::IsDenomCompatibleWithSession -- signing and relaying new queue: %s\n", dsq.ToString());
|
LogPrintf("CDarksendPool::CreateNewSession -- incompatible mode: nState=%d\n", nState);
|
||||||
dsq.Sign();
|
return false;
|
||||||
dsq.Relay();
|
|
||||||
}
|
|
||||||
|
|
||||||
SetState(POOL_STATE_QUEUE);
|
|
||||||
vecSessionCollaterals.push_back(txCollateral);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if((nState != POOL_STATE_ACCEPTING_ENTRIES && nState != POOL_STATE_QUEUE) || nSessionUsers >= GetMaxPoolTransactions()) {
|
if(!IsAcceptableDenomAndCollateral(nDenom, txCollateral, nMessageIDRet)) {
|
||||||
if((nState != POOL_STATE_ACCEPTING_ENTRIES && nState != POOL_STATE_QUEUE)) nMessageIDRet = ERR_MODE;
|
return false;
|
||||||
if(nSessionUsers >= GetMaxPoolTransactions()) nMessageIDRet = ERR_QUEUE_FULL;
|
}
|
||||||
LogPrintf("CDarksendPool::IsDenomCompatibleWithSession -- incompatible mode, return false: nState status %d, nSessionUsers status %d\n", nState != POOL_STATE_ACCEPTING_ENTRIES, nSessionUsers >= GetMaxPoolTransactions());
|
|
||||||
|
// start new session
|
||||||
|
nMessageIDRet = MSG_NOERR;
|
||||||
|
nSessionID = GetInsecureRand(999999)+1;
|
||||||
|
nSessionDenom = nDenom;
|
||||||
|
|
||||||
|
SetState(POOL_STATE_QUEUE);
|
||||||
|
nTimeLastSuccessfulStep = GetTimeMillis();
|
||||||
|
|
||||||
|
if(!fUnitTest) {
|
||||||
|
//broadcast that I'm accepting entries, only if it's the first entry through
|
||||||
|
CDarksendQueue dsq(nDenom, activeMasternode.vin, GetTime(), false);
|
||||||
|
LogPrint("privatesend", "CDarksendPool::CreateNewSession -- signing and relaying new queue: %s\n", dsq.ToString());
|
||||||
|
dsq.Sign();
|
||||||
|
dsq.Relay();
|
||||||
|
vecDarksendQueue.push_back(dsq);
|
||||||
|
}
|
||||||
|
|
||||||
|
vecSessionCollaterals.push_back(txCollateral);
|
||||||
|
LogPrintf("CDarksendPool::CreateNewSession -- new session created, nSessionID: %d nSessionDenom: %d (%s) vecSessionCollaterals.size(): %d\n",
|
||||||
|
nSessionID, nSessionDenom, GetDenominationsToString(nSessionDenom), vecSessionCollaterals.size());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDarksendPool::AddUserToExistingSession(int nDenom, CTransaction txCollateral, PoolMessage& nMessageIDRet)
|
||||||
|
{
|
||||||
|
if(!fMasterNode || nSessionID == 0 || IsSessionReady()) return false;
|
||||||
|
|
||||||
|
if(!IsAcceptableDenomAndCollateral(nDenom, txCollateral, nMessageIDRet)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we only add new users to an existing session when we are in queue mode
|
||||||
|
if(nState != POOL_STATE_QUEUE) {
|
||||||
|
nMessageIDRet = ERR_MODE;
|
||||||
|
LogPrintf("CDarksendPool::AddUserToExistingSession -- incompatible mode: nState=%d\n", nState);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nDenom != nSessionDenom) {
|
if(nDenom != nSessionDenom) {
|
||||||
|
LogPrintf("CDarksendPool::AddUserToExistingSession -- incompatible denom %d (%s) != nSessionDenom %d (%s)\n",
|
||||||
|
nDenom, GetDenominationsToString(nDenom), nSessionDenom, GetDenominationsToString(nSessionDenom));
|
||||||
nMessageIDRet = ERR_DENOM;
|
nMessageIDRet = ERR_DENOM;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrintf("CDarksendPool::IsDenomCompatibleWithSession -- compatible\n");
|
// count new user as accepted to an existing session
|
||||||
|
|
||||||
nMessageIDRet = MSG_NOERR;
|
nMessageIDRet = MSG_NOERR;
|
||||||
nSessionUsers++;
|
nTimeLastSuccessfulStep = GetTimeMillis();
|
||||||
nLastTimeChanged = GetTimeMillis();
|
|
||||||
vecSessionCollaterals.push_back(txCollateral);
|
vecSessionCollaterals.push_back(txCollateral);
|
||||||
|
|
||||||
|
LogPrintf("CDarksendPool::AddUserToExistingSession -- new user accepted, nSessionID: %d nSessionDenom: %d (%s) vecSessionCollaterals.size(): %d\n",
|
||||||
|
nSessionID, nSessionDenom, GetDenominationsToString(nSessionDenom), vecSessionCollaterals.size());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2423,12 +2406,6 @@ void CDarksendPool::SetState(PoolState nStateNew)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LogPrintf("CDarksendPool::SetState -- nState: %d, nStateNew: %d\n", nState, nStateNew);
|
LogPrintf("CDarksendPool::SetState -- nState: %d, nStateNew: %d\n", nState, nStateNew);
|
||||||
if(nState != nStateNew) {
|
|
||||||
nLastTimeChanged = GetTimeMillis();
|
|
||||||
if(fMasterNode) {
|
|
||||||
RelayStatus(STATUS_SET_STATE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nState = nStateNew;
|
nState = nStateNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ static const int PRIVATESEND_QUEUE_TIMEOUT = 30;
|
|||||||
static const int PRIVATESEND_SIGNING_TIMEOUT = 15;
|
static const int PRIVATESEND_SIGNING_TIMEOUT = 15;
|
||||||
|
|
||||||
//! minimum peer version accepted by mixing pool
|
//! minimum peer version accepted by mixing pool
|
||||||
static const int MIN_PRIVATESEND_PEER_PROTO_VERSION = 70202;
|
static const int MIN_PRIVATESEND_PEER_PROTO_VERSION = 70203;
|
||||||
|
|
||||||
static const CAmount PRIVATESEND_COLLATERAL = 0.001 * COIN;
|
static const CAmount PRIVATESEND_COLLATERAL = 0.001 * COIN;
|
||||||
static const CAmount PRIVATESEND_POOL_MAX = 999.999 * COIN;
|
static const CAmount PRIVATESEND_POOL_MAX = 999.999 * COIN;
|
||||||
@ -95,21 +95,15 @@ public:
|
|||||||
std::vector<CTxDSIn> vecTxDSIn;
|
std::vector<CTxDSIn> vecTxDSIn;
|
||||||
std::vector<CTxDSOut> vecTxDSOut;
|
std::vector<CTxDSOut> vecTxDSOut;
|
||||||
CTransaction txCollateral;
|
CTransaction txCollateral;
|
||||||
CAmount nAmount; // depreciated since 12.1, it's used for backwards compatibility only and can be removed with future protocol bump
|
|
||||||
int64_t nTimeAdded; // time in UTC milliseconds
|
|
||||||
|
|
||||||
CDarkSendEntry() :
|
CDarkSendEntry() :
|
||||||
vecTxDSIn(std::vector<CTxDSIn>()),
|
vecTxDSIn(std::vector<CTxDSIn>()),
|
||||||
vecTxDSOut(std::vector<CTxDSOut>()),
|
vecTxDSOut(std::vector<CTxDSOut>()),
|
||||||
txCollateral(CTransaction()),
|
txCollateral(CTransaction())
|
||||||
nAmount(0),
|
|
||||||
nTimeAdded(GetTime())
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CDarkSendEntry(const std::vector<CTxIn>& vecTxIn, const std::vector<CTxOut>& vecTxOut, const CTransaction& txCollateral) :
|
CDarkSendEntry(const std::vector<CTxIn>& vecTxIn, const std::vector<CTxOut>& vecTxOut, const CTransaction& txCollateral) :
|
||||||
txCollateral(txCollateral),
|
txCollateral(txCollateral)
|
||||||
nAmount(0),
|
|
||||||
nTimeAdded(GetTime())
|
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(CTxIn txin, vecTxIn)
|
BOOST_FOREACH(CTxIn txin, vecTxIn)
|
||||||
vecTxDSIn.push_back(txin);
|
vecTxDSIn.push_back(txin);
|
||||||
@ -122,14 +116,11 @@ public:
|
|||||||
template <typename Stream, typename Operation>
|
template <typename Stream, typename Operation>
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||||
READWRITE(vecTxDSIn);
|
READWRITE(vecTxDSIn);
|
||||||
READWRITE(nAmount);
|
|
||||||
READWRITE(txCollateral);
|
READWRITE(txCollateral);
|
||||||
READWRITE(vecTxDSOut);
|
READWRITE(vecTxDSOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AddScriptSig(const CTxIn& txin);
|
bool AddScriptSig(const CTxIn& txin);
|
||||||
|
|
||||||
bool IsExpired() { return GetTime() - nTimeAdded > PRIVATESEND_QUEUE_TIMEOUT; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -292,24 +283,20 @@ private:
|
|||||||
|
|
||||||
// pool states
|
// pool states
|
||||||
enum PoolState {
|
enum PoolState {
|
||||||
POOL_STATE_UNKNOWN,
|
|
||||||
POOL_STATE_IDLE,
|
POOL_STATE_IDLE,
|
||||||
POOL_STATE_QUEUE,
|
POOL_STATE_QUEUE,
|
||||||
POOL_STATE_ACCEPTING_ENTRIES,
|
POOL_STATE_ACCEPTING_ENTRIES,
|
||||||
POOL_STATE_FINALIZE_TRANSACTION,
|
|
||||||
POOL_STATE_SIGNING,
|
POOL_STATE_SIGNING,
|
||||||
POOL_STATE_TRANSMISSION,
|
|
||||||
POOL_STATE_ERROR,
|
POOL_STATE_ERROR,
|
||||||
POOL_STATE_SUCCESS,
|
POOL_STATE_SUCCESS,
|
||||||
POOL_STATE_MIN = POOL_STATE_UNKNOWN,
|
POOL_STATE_MIN = POOL_STATE_IDLE,
|
||||||
POOL_STATE_MAX = POOL_STATE_SUCCESS
|
POOL_STATE_MAX = POOL_STATE_SUCCESS
|
||||||
};
|
};
|
||||||
|
|
||||||
// status update message constants
|
// status update message constants
|
||||||
enum PoolStatusUpdate {
|
enum PoolStatusUpdate {
|
||||||
STATUS_SET_STATE = -1,
|
STATUS_REJECTED,
|
||||||
STATUS_REJECTED = 0,
|
STATUS_ACCEPTED
|
||||||
STATUS_ACCEPTED = 1
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mutable CCriticalSection cs_darksend;
|
mutable CCriticalSection cs_darksend;
|
||||||
@ -327,15 +314,13 @@ private:
|
|||||||
std::vector<CDarkSendEntry> vecEntries; // Masternode/clients entries
|
std::vector<CDarkSendEntry> vecEntries; // Masternode/clients entries
|
||||||
|
|
||||||
PoolState nState; // should be one of the POOL_STATE_XXX values
|
PoolState nState; // should be one of the POOL_STATE_XXX values
|
||||||
int64_t nLastTimeChanged; // last time the 'state' changed, in UTC milliseconds
|
int64_t nTimeLastSuccessfulStep; // the time when last successful mixing step was performed, in UTC milliseconds
|
||||||
|
|
||||||
int nCachedLastSuccessBlock;
|
int nCachedLastSuccessBlock;
|
||||||
int nMinBlockSpacing; //required blocks between mixes
|
int nMinBlockSpacing; //required blocks between mixes
|
||||||
const CBlockIndex *pCurrentBlockIndex; // Keep track of current block index
|
const CBlockIndex *pCurrentBlockIndex; // Keep track of current block index
|
||||||
|
|
||||||
int nSessionID;
|
int nSessionID; // 0 if no mixing session is active
|
||||||
int nSessionUsers; //N Users have said they'll join
|
|
||||||
bool fSessionFoundMasternode; //If we've found a compatible Masternode
|
|
||||||
|
|
||||||
int nEntriesCount;
|
int nEntriesCount;
|
||||||
bool fLastEntryAccepted;
|
bool fLastEntryAccepted;
|
||||||
@ -374,10 +359,12 @@ private:
|
|||||||
/// Get the maximum number of transactions for the pool
|
/// Get the maximum number of transactions for the pool
|
||||||
int GetMaxPoolTransactions() { return Params().PoolMaxTransactions(); }
|
int GetMaxPoolTransactions() { return Params().PoolMaxTransactions(); }
|
||||||
|
|
||||||
/// Are these outputs compatible with other client in the pool?
|
/// Is this nDenom and txCollateral acceptable?
|
||||||
bool IsOutputsCompatibleWithSessionDenom(const std::vector<CTxDSOut>& vecTxDSOut);
|
bool IsAcceptableDenomAndCollateral(int nDenom, CTransaction txCollateral, PoolMessage &nMessageIDRet);
|
||||||
/// Is this nDenom compatible with other client in the pool?
|
bool CreateNewSession(int nDenom, CTransaction txCollateral, PoolMessage &nMessageIDRet);
|
||||||
bool IsDenomCompatibleWithSession(int nDenom, CTransaction txCollateral, PoolMessage &nMessageIDRet);
|
bool AddUserToExistingSession(int nDenom, CTransaction txCollateral, PoolMessage &nMessageIDRet);
|
||||||
|
/// Do we have enough users to take entries?
|
||||||
|
bool IsSessionReady() { return (int)vecSessionCollaterals.size() >= GetMaxPoolTransactions(); }
|
||||||
|
|
||||||
/// If the collateral is valid given by a client
|
/// If the collateral is valid given by a client
|
||||||
bool IsCollateralValid(const CTransaction& txCollateral);
|
bool IsCollateralValid(const CTransaction& txCollateral);
|
||||||
@ -385,13 +372,13 @@ private:
|
|||||||
bool IsSignaturesComplete();
|
bool IsSignaturesComplete();
|
||||||
/// Check to make sure a given input matches an input in the pool and its scriptSig is valid
|
/// Check to make sure a given input matches an input in the pool and its scriptSig is valid
|
||||||
bool IsInputScriptSigValid(const CTxIn& txin);
|
bool IsInputScriptSigValid(const CTxIn& txin);
|
||||||
|
/// Are these outputs compatible with other client in the pool?
|
||||||
|
bool IsOutputsCompatibleWithSessionDenom(const std::vector<CTxDSOut>& vecTxDSOut);
|
||||||
|
|
||||||
bool IsDenomSkipped(CAmount nDenomValue) {
|
bool IsDenomSkipped(CAmount nDenomValue) {
|
||||||
return std::find(vecDenominationsSkipped.begin(), vecDenominationsSkipped.end(), nDenomValue) != vecDenominationsSkipped.end();
|
return std::find(vecDenominationsSkipped.begin(), vecDenominationsSkipped.end(), nDenomValue) != vecDenominationsSkipped.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsNull() const { return nState == POOL_STATE_ACCEPTING_ENTRIES && vecEntries.empty(); }
|
|
||||||
|
|
||||||
/// Create denominations
|
/// Create denominations
|
||||||
bool CreateDenominated();
|
bool CreateDenominated();
|
||||||
bool CreateDenominated(const CompactTallyItem& tallyItem);
|
bool CreateDenominated(const CompactTallyItem& tallyItem);
|
||||||
@ -408,7 +395,7 @@ private:
|
|||||||
bool SendDenominate(const std::vector<CTxIn>& vecTxIn, const std::vector<CTxOut>& vecTxOut);
|
bool SendDenominate(const std::vector<CTxIn>& vecTxIn, const std::vector<CTxOut>& vecTxOut);
|
||||||
|
|
||||||
/// Get Masternode updates about the progress of mixing
|
/// Get Masternode updates about the progress of mixing
|
||||||
bool UpdatePoolStateOnClient(PoolState nStateNew, int nEntriesCountNew, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID, int nSessionIDNew=0);
|
bool CheckPoolStateUpdate(PoolState nStateNew, int nEntriesCountNew, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID, int nSessionIDNew=0);
|
||||||
// Set the 'state' value, with some logging and capturing when the state changed
|
// Set the 'state' value, with some logging and capturing when the state changed
|
||||||
void SetState(PoolState nStateNew);
|
void SetState(PoolState nStateNew);
|
||||||
|
|
||||||
@ -421,9 +408,11 @@ private:
|
|||||||
void RelayInAnon(std::vector<CTxIn>& vin, std::vector<CTxOut>& vout);
|
void RelayInAnon(std::vector<CTxIn>& vin, std::vector<CTxOut>& vout);
|
||||||
void RelayIn(const CDarkSendEntry& entry);
|
void RelayIn(const CDarkSendEntry& entry);
|
||||||
void PushStatus(CNode* pnode, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID);
|
void PushStatus(CNode* pnode, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID);
|
||||||
void RelayStatus(PoolStatusUpdate nStatusUpdate = STATUS_SET_STATE, PoolMessage nMessageID = MSG_NOERR);
|
void RelayStatus(PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID = MSG_NOERR);
|
||||||
void RelayCompletedTransaction(PoolMessage nMessageID);
|
void RelayCompletedTransaction(PoolMessage nMessageID);
|
||||||
|
|
||||||
|
void SetNull();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CMasternode* pSubmittedToMasternode;
|
CMasternode* pSubmittedToMasternode;
|
||||||
int nSessionDenom; //Users must submit an denom matching this
|
int nSessionDenom; //Users must submit an denom matching this
|
||||||
@ -466,7 +455,6 @@ public:
|
|||||||
void SetMinBlockSpacing(int nMinBlockSpacingIn) { nMinBlockSpacing = nMinBlockSpacingIn; }
|
void SetMinBlockSpacing(int nMinBlockSpacingIn) { nMinBlockSpacing = nMinBlockSpacingIn; }
|
||||||
|
|
||||||
void ResetPool();
|
void ResetPool();
|
||||||
void SetNull();
|
|
||||||
|
|
||||||
void UnlockCoins();
|
void UnlockCoins();
|
||||||
|
|
||||||
@ -481,8 +469,6 @@ public:
|
|||||||
|
|
||||||
void CheckTimeout();
|
void CheckTimeout();
|
||||||
void CheckForCompleteQueue();
|
void CheckForCompleteQueue();
|
||||||
/// Do we have enough users to take entries?
|
|
||||||
bool IsSessionReady(){ return nSessionUsers >= GetMaxPoolTransactions(); }
|
|
||||||
|
|
||||||
/// Process a new block
|
/// Process a new block
|
||||||
void NewBlock();
|
void NewBlock();
|
||||||
|
Loading…
Reference in New Issue
Block a user