Skip to content

Commit 9694658

Browse files
authored
Make sure mixing messages are relayed/accepted properly (#1547)
* 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
1 parent a085149 commit 9694658

File tree

4 files changed

+69
-15
lines changed

4 files changed

+69
-15
lines changed

src/privatesend-client.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ void CPrivateSendClient::ProcessMessage(CNode* pfrom, std::string& strCommand, C
6060
// if the queue is ready, submit if we can
6161
if(dsq.fReady) {
6262
if(!infoMixingMasternode.fInfoValid) return;
63-
if((CNetAddr)infoMixingMasternode.addr != (CNetAddr)infoMn.addr) {
63+
if(infoMixingMasternode.addr != infoMn.addr) {
6464
LogPrintf("DSQUEUE -- message doesn't match current Masternode: infoMixingMasternode=%s, addr=%s\n", infoMixingMasternode.addr.ToString(), infoMn.addr.ToString());
6565
return;
6666
}
@@ -105,7 +105,7 @@ void CPrivateSendClient::ProcessMessage(CNode* pfrom, std::string& strCommand, C
105105
}
106106

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

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

178178
if(!infoMixingMasternode.fInfoValid) return;
179-
if((CNetAddr)infoMixingMasternode.addr != (CNetAddr)pfrom->addr) {
179+
if(infoMixingMasternode.addr != pfrom->addr) {
180180
LogPrint("privatesend", "DSCOMPLETE -- message doesn't match current Masternode: infoMixingMasternode=%s addr=%s\n", infoMixingMasternode.addr.ToString(), pfrom->addr.ToString());
181181
return;
182182
}

src/privatesend-server.cpp

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, std::string& strCommand, C
229229

230230
PoolMessage nMessageID = MSG_NOERR;
231231

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

796797
void CPrivateSendServer::RelayFinalTransaction(const CTransaction& txFinal)
797798
{
798-
g_connman->ForEachNode([&txFinal, this](CNode* pnode) {
799-
if(pnode->nVersion >= MIN_PRIVATESEND_PEER_PROTO_VERSION)
799+
LogPrint("privatesend", "CPrivateSendServer::%s -- nSessionID: %d nSessionDenom: %d (%s)\n",
800+
__func__, nSessionID, nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom));
801+
802+
// final mixing tx with empty signatures should be relayed to mixing participants only
803+
for (const auto entry : vecEntries) {
804+
bool fOk = g_connman->ForNode(entry.addr, [&txFinal, this](CNode* pnode) {
800805
pnode->PushMessage(NetMsgType::DSFINALTX, nSessionID, txFinal);
801-
});
806+
return true;
807+
});
808+
if(!fOk) {
809+
// no such node? maybe this client disconnected or our own connection went down
810+
RelayStatus(STATUS_REJECTED);
811+
break;
812+
}
813+
}
802814
}
803815

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

810822
void CPrivateSendServer::RelayStatus(PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID)
811823
{
812-
g_connman->ForEachNode([nStatusUpdate, nMessageID, this](CNode* pnode) {
813-
if(pnode->nVersion >= MIN_PRIVATESEND_PEER_PROTO_VERSION)
824+
unsigned int nDisconnected{};
825+
// status updates should be relayed to mixing participants only
826+
for (const auto entry : vecEntries) {
827+
// make sure everyone is still connected
828+
bool fOk = g_connman->ForNode(entry.addr, [&nStatusUpdate, &nMessageID, this](CNode* pnode) {
814829
PushStatus(pnode, nStatusUpdate, nMessageID);
815-
});
830+
return true;
831+
});
832+
if(!fOk) {
833+
// no such node? maybe this client disconnected or our own connection went down
834+
++nDisconnected;
835+
}
836+
}
837+
if (nDisconnected == 0) return; // all is clear
838+
839+
// smth went wrong
840+
LogPrintf("CPrivateSendServer::%s -- can't continue, %llu client(s) disconnected, nSessionID: %d nSessionDenom: %d (%s)\n",
841+
__func__, nDisconnected, nSessionID, nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom));
842+
843+
// notify everyone else that this session should be terminated
844+
for (const auto entry : vecEntries) {
845+
g_connman->ForNode(entry.addr, [this](CNode* pnode) {
846+
PushStatus(pnode, STATUS_REJECTED, MSG_NOERR);
847+
return true;
848+
});
849+
}
850+
851+
if(nDisconnected == vecEntries.size()) {
852+
// all clients disconnected, there is probably some issues with our own connection
853+
// do not charge any fees, just reset the pool
854+
SetNull();
855+
}
816856
}
817857

818858
void CPrivateSendServer::RelayCompletedTransaction(PoolMessage nMessageID)
819859
{
820-
g_connman->ForEachNode([nMessageID, this](CNode* pnode) {
821-
if(pnode->nVersion >= MIN_PRIVATESEND_PEER_PROTO_VERSION)
860+
LogPrint("privatesend", "CPrivateSendServer::%s -- nSessionID: %d nSessionDenom: %d (%s)\n",
861+
__func__, nSessionID, nSessionDenom, CPrivateSend::GetDenominationsToString(nSessionDenom));
862+
863+
// final mixing tx with empty signatures should be relayed to mixing participants only
864+
for (const auto entry : vecEntries) {
865+
bool fOk = g_connman->ForNode(entry.addr, [&nMessageID, this](CNode* pnode) {
822866
pnode->PushMessage(NetMsgType::DSCOMPLETE, nSessionID, (int)nMessageID);
823-
});
867+
return true;
868+
});
869+
if(!fOk) {
870+
// no such node? maybe client disconnected or our own connection went down
871+
RelayStatus(STATUS_REJECTED);
872+
break;
873+
}
874+
}
824875
}
825876

826877
void CPrivateSendServer::SetState(PoolState nStateNew)

src/privatesend.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include <boost/lexical_cast.hpp>
2121

2222
CDarkSendEntry::CDarkSendEntry(const std::vector<CTxIn>& vecTxIn, const std::vector<CTxOut>& vecTxOut, const CTransaction& txCollateral) :
23-
txCollateral(txCollateral)
23+
txCollateral(txCollateral), addr(CService())
2424
{
2525
BOOST_FOREACH(CTxIn txin, vecTxIn)
2626
vecTxDSIn.push_back(txin);

src/privatesend.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,14 @@ class CDarkSendEntry
117117
std::vector<CTxDSIn> vecTxDSIn;
118118
std::vector<CTxDSOut> vecTxDSOut;
119119
CTransaction txCollateral;
120+
// memory only
121+
CService addr;
120122

121123
CDarkSendEntry() :
122124
vecTxDSIn(std::vector<CTxDSIn>()),
123125
vecTxDSOut(std::vector<CTxDSOut>()),
124-
txCollateral(CTransaction())
126+
txCollateral(CTransaction()),
127+
addr(CService())
125128
{}
126129

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

0 commit comments

Comments
 (0)