From 2f097e5daf85f82b98fce1452f91ac4b63eef860 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Sat, 11 Aug 2018 12:04:55 +0300 Subject: [PATCH 1/2] Revert "Require all participants to submit equal number of inputs (#2075)" This reverts commit 7ac4b972ab0c7a87424f0ffc8e29d12df8aa3314. --- src/privatesend-client.cpp | 51 ++++++++------------------------------ src/privatesend-server.cpp | 39 +++-------------------------- src/privatesend.cpp | 2 -- src/privatesend.h | 32 +++++------------------- 4 files changed, 20 insertions(+), 104 deletions(-) diff --git a/src/privatesend-client.cpp b/src/privatesend-client.cpp index b6e3b44d54cb..e123f8c6733f 100644 --- a/src/privatesend-client.cpp +++ b/src/privatesend-client.cpp @@ -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; @@ -1035,16 +1034,10 @@ bool CPrivateSendClientSession::JoinExistingQueue(CAmount nBalanceNeedsAnonymize std::vector 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; } @@ -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; } @@ -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 vecBits; - if (!CPrivateSend::GetDenominationsBits(nSessionDenom, vecBits)) { - return false; - } - - CAmount nValueInTmp = 0; - std::vector vecTxDSInTmp; - std::vector vCoinsTmp; - std::vector 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; } @@ -1282,7 +1251,7 @@ bool CPrivateSendClientSession::PrepareDenominate(int nMinRounds, int nMaxRounds return false; } std::vector 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; @@ -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) { @@ -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); diff --git a/src/privatesend-server.cpp b/src/privatesend-server.cpp index 7ad012b57613..ad62d7b5bab2 100644 --- a/src/privatesend-server.cpp +++ b/src/privatesend-server.cpp @@ -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); @@ -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; @@ -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"); @@ -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); @@ -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; } @@ -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); @@ -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; } diff --git a/src/privatesend.cpp b/src/privatesend.cpp index 5cac0dc67314..9a315e03fb04 100644 --- a/src/privatesend.cpp +++ b/src/privatesend.cpp @@ -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(); @@ -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."); } } diff --git a/src/privatesend.h b/src/privatesend.h index 47b0158ae192..0e0210d2271c 100644 --- a/src/privatesend.h +++ b/src/privatesend.h @@ -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 }; @@ -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) {}; @@ -120,12 +116,6 @@ class CDarksendAccept template inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(nDenom); - int nVersion = s.GetVersion(); - if (nVersion > 70208) { - READWRITE(nInputCount); - } else if (ser_action.ForRead()) { - nInputCount = 0; - } READWRITE(txCollateral); } @@ -179,7 +169,6 @@ class CDarksendQueue { public: int nDenom; - int nInputCount; COutPoint masternodeOutpoint; int64_t nTime; bool fReady; //ready for submit @@ -189,7 +178,6 @@ class CDarksendQueue CDarksendQueue() : nDenom(0), - nInputCount(0), masternodeOutpoint(COutPoint()), nTime(0), fReady(false), @@ -197,9 +185,8 @@ class CDarksendQueue 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), @@ -213,11 +200,6 @@ class CDarksendQueue inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(nDenom); int nVersion = s.GetVersion(); - if (nVersion > 70208) { - READWRITE(nInputCount); - } else if (ser_action.ForRead()) { - nInputCount = 0; - } if (nVersion == 70208 && (s.GetType() & SER_NETWORK)) { // converting from/to old format CTxIn txin{}; @@ -258,13 +240,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; } }; @@ -366,7 +348,6 @@ class CPrivateSendBaseSession public: int nSessionDenom; //Users must submit a denom matching this - int nSessionInputCount; //Users must submit a count matching this CPrivateSendBaseSession() : vecEntries(), @@ -374,8 +355,7 @@ class CPrivateSendBaseSession nTimeLastSuccessfulStep(0), nSessionID(0), finalMutableTransaction(), - nSessionDenom(0), - nSessionInputCount(0) + nSessionDenom(0) {} CPrivateSendBaseSession(const CPrivateSendBaseSession& other) { /* dummy copy constructor*/ SetNull(); } From 6bd6a47034c878a5dd01d1ee66c1f17723194021 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Thu, 30 Aug 2018 04:31:25 +0300 Subject: [PATCH 2/2] Backward compatibility for nInputCount --- src/privatesend.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/privatesend.h b/src/privatesend.h index 0e0210d2271c..5a63615e6a68 100644 --- a/src/privatesend.h +++ b/src/privatesend.h @@ -116,6 +116,11 @@ class CDarksendAccept template inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(nDenom); + int nVersion = s.GetVersion(); + if (nVersion > 70208 && nVersion <= 70210) { + int nInputCount = 0; + READWRITE(nInputCount); + } READWRITE(txCollateral); } @@ -200,6 +205,10 @@ class CDarksendQueue inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(nDenom); int nVersion = s.GetVersion(); + if (nVersion > 70208 && nVersion <= 70210) { + int nInputCount = 0; + READWRITE(nInputCount); + } if (nVersion == 70208 && (s.GetType() & SER_NETWORK)) { // converting from/to old format CTxIn txin{};