Skip to content

Commit

Permalink
Make sure mixing messages are relayed/accepted properly (#1547)
Browse files Browse the repository at this point in the history
* make sure addr of mixing mn matches peer's addr exactly (including port)

* Store addr of every mixing client and relay mixing mesasges to them only
  • Loading branch information
UdjinM6 authored Jul 25, 2017
1 parent a085149 commit 9694658
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 15 deletions.
8 changes: 4 additions & 4 deletions src/privatesend-client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void CPrivateSendClient::ProcessMessage(CNode* pfrom, std::string& strCommand, C
// if the queue is ready, submit if we can
if(dsq.fReady) {
if(!infoMixingMasternode.fInfoValid) return;
if((CNetAddr)infoMixingMasternode.addr != (CNetAddr)infoMn.addr) {
if(infoMixingMasternode.addr != infoMn.addr) {
LogPrintf("DSQUEUE -- message doesn't match current Masternode: infoMixingMasternode=%s, addr=%s\n", infoMixingMasternode.addr.ToString(), infoMn.addr.ToString());
return;
}
Expand Down Expand Up @@ -105,7 +105,7 @@ void CPrivateSendClient::ProcessMessage(CNode* pfrom, std::string& strCommand, C
}

if(!infoMixingMasternode.fInfoValid) return;
if((CNetAddr)infoMixingMasternode.addr != (CNetAddr)pfrom->addr) {
if(infoMixingMasternode.addr != pfrom->addr) {
//LogPrintf("DSSTATUSUPDATE -- message doesn't match current Masternode: infoMixingMasternode %s addr %s\n", infoMixingMasternode.addr.ToString(), pfrom->addr.ToString());
return;
}
Expand Down Expand Up @@ -149,7 +149,7 @@ void CPrivateSendClient::ProcessMessage(CNode* pfrom, std::string& strCommand, C
}

if(!infoMixingMasternode.fInfoValid) return;
if((CNetAddr)infoMixingMasternode.addr != (CNetAddr)pfrom->addr) {
if(infoMixingMasternode.addr != pfrom->addr) {
//LogPrintf("DSFINALTX -- message doesn't match current Masternode: infoMixingMasternode %s addr %s\n", infoMixingMasternode.addr.ToString(), pfrom->addr.ToString());
return;
}
Expand All @@ -176,7 +176,7 @@ void CPrivateSendClient::ProcessMessage(CNode* pfrom, std::string& strCommand, C
}

if(!infoMixingMasternode.fInfoValid) return;
if((CNetAddr)infoMixingMasternode.addr != (CNetAddr)pfrom->addr) {
if(infoMixingMasternode.addr != pfrom->addr) {
LogPrint("privatesend", "DSCOMPLETE -- message doesn't match current Masternode: infoMixingMasternode=%s addr=%s\n", infoMixingMasternode.addr.ToString(), pfrom->addr.ToString());
return;
}
Expand Down
69 changes: 60 additions & 9 deletions src/privatesend-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, std::string& strCommand, C

PoolMessage nMessageID = MSG_NOERR;

entry.addr = pfrom->addr;
if(AddEntry(entry, nMessageID)) {
PushStatus(pfrom, STATUS_ACCEPTED, nMessageID);
CheckPool();
Expand Down Expand Up @@ -795,10 +796,21 @@ bool CPrivateSendServer::AddUserToExistingSession(int nDenom, CTransaction txCol

void CPrivateSendServer::RelayFinalTransaction(const CTransaction& txFinal)
{
g_connman->ForEachNode([&txFinal, this](CNode* pnode) {
if(pnode->nVersion >= MIN_PRIVATESEND_PEER_PROTO_VERSION)
LogPrint("privatesend", "CPrivateSendServer::%s -- nSessionID: %d nSessionDenom: %d (%s)\n",
__func__, nSessionID, nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom));

// final mixing tx with empty signatures should be relayed to mixing participants only
for (const auto entry : vecEntries) {
bool fOk = g_connman->ForNode(entry.addr, [&txFinal, this](CNode* pnode) {
pnode->PushMessage(NetMsgType::DSFINALTX, nSessionID, txFinal);
});
return true;
});
if(!fOk) {
// no such node? maybe this client disconnected or our own connection went down
RelayStatus(STATUS_REJECTED);
break;
}
}
}

void CPrivateSendServer::PushStatus(CNode* pnode, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID)
Expand All @@ -809,18 +821,57 @@ void CPrivateSendServer::PushStatus(CNode* pnode, PoolStatusUpdate nStatusUpdate

void CPrivateSendServer::RelayStatus(PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID)
{
g_connman->ForEachNode([nStatusUpdate, nMessageID, this](CNode* pnode) {
if(pnode->nVersion >= MIN_PRIVATESEND_PEER_PROTO_VERSION)
unsigned int nDisconnected{};
// status updates should be relayed to mixing participants only
for (const auto entry : vecEntries) {
// make sure everyone is still connected
bool fOk = g_connman->ForNode(entry.addr, [&nStatusUpdate, &nMessageID, this](CNode* pnode) {
PushStatus(pnode, nStatusUpdate, nMessageID);
});
return true;
});
if(!fOk) {
// no such node? maybe this client disconnected or our own connection went down
++nDisconnected;
}
}
if (nDisconnected == 0) return; // all is clear

// smth went wrong
LogPrintf("CPrivateSendServer::%s -- can't continue, %llu client(s) disconnected, nSessionID: %d nSessionDenom: %d (%s)\n",
__func__, nDisconnected, nSessionID, nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom));

// notify everyone else that this session should be terminated
for (const auto entry : vecEntries) {
g_connman->ForNode(entry.addr, [this](CNode* pnode) {
PushStatus(pnode, STATUS_REJECTED, MSG_NOERR);
return true;
});
}

if(nDisconnected == vecEntries.size()) {
// all clients disconnected, there is probably some issues with our own connection
// do not charge any fees, just reset the pool
SetNull();
}
}

void CPrivateSendServer::RelayCompletedTransaction(PoolMessage nMessageID)
{
g_connman->ForEachNode([nMessageID, this](CNode* pnode) {
if(pnode->nVersion >= MIN_PRIVATESEND_PEER_PROTO_VERSION)
LogPrint("privatesend", "CPrivateSendServer::%s -- nSessionID: %d nSessionDenom: %d (%s)\n",
__func__, nSessionID, nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom));

// final mixing tx with empty signatures should be relayed to mixing participants only
for (const auto entry : vecEntries) {
bool fOk = g_connman->ForNode(entry.addr, [&nMessageID, this](CNode* pnode) {
pnode->PushMessage(NetMsgType::DSCOMPLETE, nSessionID, (int)nMessageID);
});
return true;
});
if(!fOk) {
// no such node? maybe client disconnected or our own connection went down
RelayStatus(STATUS_REJECTED);
break;
}
}
}

void CPrivateSendServer::SetState(PoolState nStateNew)
Expand Down
2 changes: 1 addition & 1 deletion src/privatesend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include <boost/lexical_cast.hpp>

CDarkSendEntry::CDarkSendEntry(const std::vector<CTxIn>& vecTxIn, const std::vector<CTxOut>& vecTxOut, const CTransaction& txCollateral) :
txCollateral(txCollateral)
txCollateral(txCollateral), addr(CService())
{
BOOST_FOREACH(CTxIn txin, vecTxIn)
vecTxDSIn.push_back(txin);
Expand Down
5 changes: 4 additions & 1 deletion src/privatesend.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,14 @@ class CDarkSendEntry
std::vector<CTxDSIn> vecTxDSIn;
std::vector<CTxDSOut> vecTxDSOut;
CTransaction txCollateral;
// memory only
CService addr;

CDarkSendEntry() :
vecTxDSIn(std::vector<CTxDSIn>()),
vecTxDSOut(std::vector<CTxDSOut>()),
txCollateral(CTransaction())
txCollateral(CTransaction()),
addr(CService())
{}

CDarkSendEntry(const std::vector<CTxIn>& vecTxIn, const std::vector<CTxOut>& vecTxOut, const CTransaction& txCollateral);
Expand Down

0 comments on commit 9694658

Please sign in to comment.