Skip to content

Commit

Permalink
Revert 2075 (#2259)
Browse files Browse the repository at this point in the history
* Revert "Require all participants to submit equal number of inputs (#2075)"

This reverts commit 7ac4b97.

* Backward compatibility for nInputCount
  • Loading branch information
UdjinM6 authored Sep 5, 2018
1 parent b164bcc commit 8c9cb29
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 99 deletions.
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

0 comments on commit 8c9cb29

Please sign in to comment.