Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 10 additions & 41 deletions src/privatesend-client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ void CPrivateSendClientManager::ProcessMessage(CNode* pfrom, const std::string&
LogPrint("privatesend", "DSQUEUE -- %s new\n", dsq.ToString());

if(dsq.IsExpired()) return;
if(dsq.nInputCount < 0 || dsq.nInputCount > PRIVATESEND_ENTRY_MAX_SIZE) return;

masternode_info_t infoMn;
if(!mnodeman.GetMasternodeInfo(dsq.masternodeOutpoint, infoMn)) return;
Expand Down Expand Up @@ -1035,16 +1034,10 @@ bool CPrivateSendClientSession::JoinExistingQueue(CAmount nBalanceNeedsAnonymize
std::vector<COutput> vCoinsTmp;
CAmount nMinAmount = vecStandardDenoms[vecBits.front()];
CAmount nMaxAmount = nBalanceNeedsAnonymized;
// nInputCount is not covered by legacy signature, require SPORK_6_NEW_SIGS to activate to use new algo
// (to make sure nInputCount wasn't modified by some intermediary node)
bool fNewAlgo = infoMn.nProtocolVersion > 70208 && sporkManager.IsSporkActive(SPORK_6_NEW_SIGS);

if (fNewAlgo && dsq.nInputCount != 0) {
nMinAmount = nMaxAmount = dsq.nInputCount * vecStandardDenoms[vecBits.front()];
}
// Try to match their denominations if possible, select exact number of denominations
if(!pwalletMain->SelectCoinsByDenominations(dsq.nDenom, nMinAmount, nMaxAmount, vecTxDSInTmp, vCoinsTmp, nValueInTmp, 0, privateSendClient.nPrivateSendRounds)) {
LogPrintf("CPrivateSendClientSession::JoinExistingQueue -- Couldn't match %d denominations %d %d (%s)\n", dsq.nInputCount, vecBits.front(), dsq.nDenom, CPrivateSend::GetDenominationsToString(dsq.nDenom));
LogPrintf("CPrivateSendClientSession::JoinExistingQueue -- Couldn't match %d denominations %d (%s)\n", vecBits.front(), dsq.nDenom, CPrivateSend::GetDenominationsToString(dsq.nDenom));
continue;
}

Expand All @@ -1056,15 +1049,14 @@ bool CPrivateSendClientSession::JoinExistingQueue(CAmount nBalanceNeedsAnonymize
}

nSessionDenom = dsq.nDenom;
nSessionInputCount = fNewAlgo ? dsq.nInputCount : 0;
infoMixingMasternode = infoMn;
pendingDsaRequest = CPendingDsaRequest(infoMn.addr, CDarksendAccept(nSessionDenom, nSessionInputCount, txMyCollateral));
pendingDsaRequest = CPendingDsaRequest(infoMn.addr, CDarksendAccept(nSessionDenom, txMyCollateral));
connman.AddPendingMasternode(infoMn.addr);
// TODO: add new state POOL_STATE_CONNECTING and bump MIN_PRIVATESEND_PEER_PROTO_VERSION
SetState(POOL_STATE_QUEUE);
nTimeLastSuccessfulStep = GetTime();
LogPrintf("CPrivateSendClientSession::JoinExistingQueue -- pending connection (from queue): nSessionDenom: %d (%s), nSessionInputCount: %d, addr=%s\n",
nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom), nSessionInputCount, infoMn.addr.ToString());
LogPrintf("CPrivateSendClientSession::JoinExistingQueue -- pending connection (from queue): nSessionDenom: %d (%s), addr=%s\n",
nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom), infoMn.addr.ToString());
strAutoDenomResult = _("Trying to connect...");
return true;
}
Expand Down Expand Up @@ -1132,37 +1124,14 @@ bool CPrivateSendClientSession::StartNewQueue(CAmount nValueMin, CAmount nBalanc
nSessionDenom = CPrivateSend::GetDenominationsByAmounts(vecAmounts);
}

// Count available denominations.
// Should never really fail after this point, since we just selected compatible inputs ourselves.
std::vector<int> vecBits;
if (!CPrivateSend::GetDenominationsBits(nSessionDenom, vecBits)) {
return false;
}

CAmount nValueInTmp = 0;
std::vector<CTxDSIn> vecTxDSInTmp;
std::vector<COutput> vCoinsTmp;
std::vector<CAmount> vecStandardDenoms = CPrivateSend::GetStandardDenominations();

bool fSelected = pwalletMain->SelectCoinsByDenominations(nSessionDenom, vecStandardDenoms[vecBits.front()], vecStandardDenoms[vecBits.front()] * PRIVATESEND_ENTRY_MAX_SIZE, vecTxDSInTmp, vCoinsTmp, nValueInTmp, 0, privateSendClient.nPrivateSendRounds);
if (!fSelected) {
return false;
}

// nInputCount is not covered by legacy signature, require SPORK_6_NEW_SIGS to activate to use new algo
// (to make sure nInputCount wasn't modified by some intermediary node)
bool fNewAlgo = infoMn.nProtocolVersion > 70208 && sporkManager.IsSporkActive(SPORK_6_NEW_SIGS);
nSessionInputCount = fNewAlgo
? std::min(vecTxDSInTmp.size(), size_t(5 + GetRand(PRIVATESEND_ENTRY_MAX_SIZE - 5 + 1)))
: 0;
infoMixingMasternode = infoMn;
connman.AddPendingMasternode(infoMn.addr);
pendingDsaRequest = CPendingDsaRequest(infoMn.addr, CDarksendAccept(nSessionDenom, nSessionInputCount, txMyCollateral));
pendingDsaRequest = CPendingDsaRequest(infoMn.addr, CDarksendAccept(nSessionDenom, txMyCollateral));
// TODO: add new state POOL_STATE_CONNECTING and bump MIN_PRIVATESEND_PEER_PROTO_VERSION
SetState(POOL_STATE_QUEUE);
nTimeLastSuccessfulStep = GetTime();
LogPrintf("CPrivateSendClientSession::StartNewQueue -- pending connection, nSessionDenom: %d (%s), nSessionInputCount: %d, addr=%s\n",
nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom), nSessionInputCount, infoMn.addr.ToString());
LogPrintf("CPrivateSendClientSession::StartNewQueue -- pending connection, nSessionDenom: %d (%s), addr=%s\n",
nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom), infoMn.addr.ToString());
strAutoDenomResult = _("Trying to connect...");
return true;
}
Expand Down Expand Up @@ -1282,7 +1251,7 @@ bool CPrivateSendClientSession::PrepareDenominate(int nMinRounds, int nMaxRounds
return false;
}
std::vector<CAmount> vecStandardDenoms = CPrivateSend::GetStandardDenominations();
bool fSelected = pwalletMain->SelectCoinsByDenominations(nSessionDenom, vecStandardDenoms[vecBits.front()], vecStandardDenoms[vecBits.front()] * PRIVATESEND_ENTRY_MAX_SIZE, vecTxDSIn, vCoins, nValueIn, nMinRounds, nMaxRounds);
bool fSelected = pwalletMain->SelectCoinsByDenominations(nSessionDenom, vecStandardDenoms[vecBits.front()], CPrivateSend::GetMaxPoolAmount(), vecTxDSIn, vCoins, nValueIn, nMinRounds, nMaxRounds);
if (nMinRounds >= 0 && !fSelected) {
strErrorRet = "Can't select current denominated inputs";
return false;
Expand All @@ -1303,7 +1272,7 @@ bool CPrivateSendClientSession::PrepareDenominate(int nMinRounds, int nMaxRounds
// NOTE: No need to randomize order of inputs because they were
// initially shuffled in CWallet::SelectCoinsByDenominations already.
int nStep = 0;
int nStepsMax = nSessionInputCount != 0 ? nSessionInputCount : (5 + GetRandInt(PRIVATESEND_ENTRY_MAX_SIZE - 5 + 1));
int nStepsMax = 5 + GetRandInt(PRIVATESEND_ENTRY_MAX_SIZE - 5 + 1);

while (nStep < nStepsMax) {
for (const auto& nBit : vecBits) {
Expand Down Expand Up @@ -1350,7 +1319,7 @@ bool CPrivateSendClientSession::PrepareDenominate(int nMinRounds, int nMaxRounds
}
}

if (CPrivateSend::GetDenominations(vecTxOutRet) != nSessionDenom || (nSessionInputCount != 0 && vecTxOutRet.size() != (size_t)nSessionInputCount)) {
if (CPrivateSend::GetDenominations(vecTxOutRet) != nSessionDenom) {
{
// unlock used coins on failure
LOCK(pwalletMain->cs_wallet);
Expand Down
39 changes: 4 additions & 35 deletions src/privatesend-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, const std::string& strComm

LogPrint("privatesend", "DSACCEPT -- nDenom %d (%s) txCollateral %s", dsa.nDenom, CPrivateSend::GetDenominationsToString(dsa.nDenom), dsa.txCollateral.ToString());

if(dsa.nInputCount < 0 || dsa.nInputCount > PRIVATESEND_ENTRY_MAX_SIZE) return;

masternode_info_t mnInfo;
if(!mnodeman.GetMasternodeInfo(activeMasternodeInfo.outpoint, mnInfo)) {
PushStatus(pfrom, STATUS_REJECTED, ERR_MN_LIST, connman);
Expand Down Expand Up @@ -100,7 +98,6 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, const std::string& strComm
LogPrint("privatesend", "DSQUEUE -- %s new\n", dsq.ToString());

if(dsq.IsExpired()) return;
if(dsq.nInputCount < 0 || dsq.nInputCount > PRIVATESEND_ENTRY_MAX_SIZE) return;

masternode_info_t mnInfo;
if(!mnodeman.GetMasternodeInfo(dsq.masternodeOutpoint, mnInfo)) return;
Expand Down Expand Up @@ -168,18 +165,6 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, const std::string& strComm
return;
}

if(nSessionInputCount != 0 && entry.vecTxDSIn.size() != nSessionInputCount) {
LogPrintf("DSVIN -- ERROR: incorrect number of inputs! %d/%d\n", entry.vecTxDSIn.size(), nSessionInputCount);
PushStatus(pfrom, STATUS_REJECTED, ERR_INVALID_INPUT_COUNT, connman);
return;
}

if(nSessionInputCount != 0 && entry.vecTxOut.size() != nSessionInputCount) {
LogPrintf("DSVIN -- ERROR: incorrect number of outputs! %d/%d\n", entry.vecTxOut.size(), nSessionInputCount);
PushStatus(pfrom, STATUS_REJECTED, ERR_INVALID_INPUT_COUNT, connman);
return;
}

//do we have the same denominations as the current session?
if(!IsOutputsCompatibleWithSessionDenom(entry.vecTxOut)) {
LogPrintf("DSVIN -- not compatible with existing transactions!\n");
Expand Down Expand Up @@ -525,7 +510,7 @@ void CPrivateSendServer::CheckForCompleteQueue(CConnman& connman)
if(nState == POOL_STATE_QUEUE && IsSessionReady()) {
SetState(POOL_STATE_ACCEPTING_ENTRIES);

CDarksendQueue dsq(nSessionDenom, nSessionInputCount, activeMasternodeInfo.outpoint, GetAdjustedTime(), true);
CDarksendQueue dsq(nSessionDenom, activeMasternodeInfo.outpoint, GetAdjustedTime(), true);
LogPrint("privatesend", "CPrivateSendServer::CheckForCompleteQueue -- queue is ready, signing and relaying (%s)\n", dsq.ToString());
dsq.Sign();
dsq.Relay(connman);
Expand Down Expand Up @@ -703,12 +688,6 @@ bool CPrivateSendServer::IsAcceptableDSA(const CDarksendAccept& dsa, PoolMessage
return false;
}

if(dsa.nInputCount < 0 || dsa.nInputCount > PRIVATESEND_ENTRY_MAX_SIZE) {
LogPrint("privatesend", "CPrivateSendServer::%s -- requested count is not valid!\n", __func__);
nMessageIDRet = ERR_INVALID_INPUT_COUNT;
return false;
}

return true;
}

Expand All @@ -731,16 +710,13 @@ bool CPrivateSendServer::CreateNewSession(const CDarksendAccept& dsa, PoolMessag
nMessageIDRet = MSG_NOERR;
nSessionID = GetRandInt(999999)+1;
nSessionDenom = dsa.nDenom;
// nInputCount is not covered by legacy signature, require SPORK_6_NEW_SIGS to activate to use new algo
// (to make sure nInputCount wasn't modified by some intermediary node)
nSessionInputCount = sporkManager.IsSporkActive(SPORK_6_NEW_SIGS) ? dsa.nInputCount : 0;

SetState(POOL_STATE_QUEUE);
nTimeLastSuccessfulStep = GetTime();

if(!fUnitTest) {
//broadcast that I'm accepting entries, only if it's the first entry through
CDarksendQueue dsq(dsa.nDenom, dsa.nInputCount, activeMasternodeInfo.outpoint, GetAdjustedTime(), false);
CDarksendQueue dsq(dsa.nDenom, activeMasternodeInfo.outpoint, GetAdjustedTime(), false);
LogPrint("privatesend", "CPrivateSendServer::CreateNewSession -- signing and relaying new queue: %s\n", dsq.ToString());
dsq.Sign();
dsq.Relay(connman);
Expand Down Expand Up @@ -776,21 +752,14 @@ bool CPrivateSendServer::AddUserToExistingSession(const CDarksendAccept& dsa, Po
return false;
}

if(dsa.nInputCount != nSessionInputCount) {
LogPrintf("CPrivateSendServer::AddUserToExistingSession -- incompatible count %d != nSessionInputCount %d\n",
dsa.nInputCount, nSessionInputCount);
nMessageIDRet = ERR_INVALID_INPUT_COUNT;
return false;
}

// count new user as accepted to an existing session

nMessageIDRet = MSG_NOERR;
nTimeLastSuccessfulStep = GetTime();
vecSessionCollaterals.push_back(MakeTransactionRef(dsa.txCollateral));

LogPrintf("CPrivateSendServer::AddUserToExistingSession -- new user accepted, nSessionID: %d nSessionDenom: %d (%s) nSessionInputCount: %d vecSessionCollaterals.size(): %d\n",
nSessionID, nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom), nSessionInputCount, vecSessionCollaterals.size());
LogPrintf("CPrivateSendServer::AddUserToExistingSession -- new user accepted, nSessionID: %d nSessionDenom: %d (%s) vecSessionCollaterals.size(): %d\n",
nSessionID, nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom), vecSessionCollaterals.size());

return true;
}
Expand Down
2 changes: 0 additions & 2 deletions src/privatesend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ void CPrivateSendBaseSession::SetNull()
nState = POOL_STATE_IDLE;
nSessionID = 0;
nSessionDenom = 0;
nSessionInputCount = 0;
vecEntries.clear();
finalMutableTransaction.vin.clear();
finalMutableTransaction.vout.clear();
Expand Down Expand Up @@ -477,7 +476,6 @@ std::string CPrivateSend::GetMessageByID(PoolMessage nMessageID)
case MSG_NOERR: return _("No errors detected.");
case MSG_SUCCESS: return _("Transaction created successfully.");
case MSG_ENTRIES_ADDED: return _("Your entries added successfully.");
case ERR_INVALID_INPUT_COUNT: return _("Invalid input count.");
default: return _("Unknown response.");
}
}
Expand Down
31 changes: 10 additions & 21 deletions src/privatesend.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ enum PoolMessage {
MSG_NOERR,
MSG_SUCCESS,
MSG_ENTRIES_ADDED,
ERR_INVALID_INPUT_COUNT,
MSG_POOL_MIN = ERR_ALREADY_HAVE,
MSG_POOL_MAX = MSG_ENTRIES_ADDED
};
Expand Down Expand Up @@ -100,18 +99,15 @@ class CDarksendAccept
{
public:
int nDenom;
int nInputCount;
CMutableTransaction txCollateral;

CDarksendAccept() :
nDenom(0),
nInputCount(0),
txCollateral(CMutableTransaction())
{};

CDarksendAccept(int nDenom, int nInputCount, const CMutableTransaction& txCollateral) :
CDarksendAccept(int nDenom, const CMutableTransaction& txCollateral) :
nDenom(nDenom),
nInputCount(nInputCount),
txCollateral(txCollateral)
{};

Expand All @@ -121,10 +117,9 @@ class CDarksendAccept
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(nDenom);
int nVersion = s.GetVersion();
if (nVersion > 70208) {
if (nVersion > 70208 && nVersion <= 70210) {
int nInputCount = 0;
READWRITE(nInputCount);
} else if (ser_action.ForRead()) {
nInputCount = 0;
}
READWRITE(txCollateral);
}
Expand Down Expand Up @@ -179,7 +174,6 @@ class CDarksendQueue
{
public:
int nDenom;
int nInputCount;
COutPoint masternodeOutpoint;
int64_t nTime;
bool fReady; //ready for submit
Expand All @@ -189,17 +183,15 @@ class CDarksendQueue

CDarksendQueue() :
nDenom(0),
nInputCount(0),
masternodeOutpoint(COutPoint()),
nTime(0),
fReady(false),
vchSig(std::vector<unsigned char>()),
fTried(false)
{}

CDarksendQueue(int nDenom, int nInputCount, COutPoint outpoint, int64_t nTime, bool fReady) :
CDarksendQueue(int nDenom, COutPoint outpoint, int64_t nTime, bool fReady) :
nDenom(nDenom),
nInputCount(nInputCount),
masternodeOutpoint(outpoint),
nTime(nTime),
fReady(fReady),
Expand All @@ -213,10 +205,9 @@ class CDarksendQueue
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(nDenom);
int nVersion = s.GetVersion();
if (nVersion > 70208) {
if (nVersion > 70208 && nVersion <= 70210) {
int nInputCount = 0;
READWRITE(nInputCount);
} else if (ser_action.ForRead()) {
nInputCount = 0;
}
if (nVersion == 70208 && (s.GetType() & SER_NETWORK)) {
// converting from/to old format
Expand Down Expand Up @@ -258,13 +249,13 @@ class CDarksendQueue

std::string ToString() const
{
return strprintf("nDenom=%d, nInputCount=%d, nTime=%lld, fReady=%s, fTried=%s, masternode=%s",
nDenom, nInputCount, nTime, fReady ? "true" : "false", fTried ? "true" : "false", masternodeOutpoint.ToStringShort());
return strprintf("nDenom=%d, nTime=%lld, fReady=%s, fTried=%s, masternode=%s",
nDenom, nTime, fReady ? "true" : "false", fTried ? "true" : "false", masternodeOutpoint.ToStringShort());
}

friend bool operator==(const CDarksendQueue& a, const CDarksendQueue& b)
{
return a.nDenom == b.nDenom && a.nInputCount == b.nInputCount && a.masternodeOutpoint == b.masternodeOutpoint && a.nTime == b.nTime && a.fReady == b.fReady;
return a.nDenom == b.nDenom && a.masternodeOutpoint == b.masternodeOutpoint && a.nTime == b.nTime && a.fReady == b.fReady;
}
};

Expand Down Expand Up @@ -366,16 +357,14 @@ class CPrivateSendBaseSession

public:
int nSessionDenom; //Users must submit a denom matching this
int nSessionInputCount; //Users must submit a count matching this

CPrivateSendBaseSession() :
vecEntries(),
nState(POOL_STATE_IDLE),
nTimeLastSuccessfulStep(0),
nSessionID(0),
finalMutableTransaction(),
nSessionDenom(0),
nSessionInputCount(0)
nSessionDenom(0)
{}
CPrivateSendBaseSession(const CPrivateSendBaseSession& other) { /* dummy copy constructor*/ SetNull(); }

Expand Down