Skip to content

Commit

Permalink
net_processing: try to update iqr member field if "qsendrecsigs" is r…
Browse files Browse the repository at this point in the history
…eceived.

Plus add spam protection for it as well and, as the message is relayed right after the verack and before the mnauth, move the code block above the mnauth first message check.
  • Loading branch information
furszy committed Jan 17, 2022
1 parent a2b478f commit 747f838
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 11 deletions.
9 changes: 9 additions & 0 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2420,6 +2420,15 @@ void CConnman::RemoveAskFor(const uint256& invHash, int invType)
}
}

void CConnman::UpdateQuorumRelayMemberIfNeeded(CNode* pnode)
{
bool hash_verif = WITH_LOCK(pnode->cs_mnauth, return !pnode->verifiedProRegTxHash.IsNull(););
if (hash_verif && !pnode->m_masternode_iqr_connection && pnode->m_masternode_connection &&
m_tiertwo_conn_man->isMasternodeQuorumRelayMember(pnode->verifiedProRegTxHash)) {
pnode->m_masternode_iqr_connection = true;
}
}

void CConnman::RecordBytesRecv(uint64_t bytes)
{
LOCK(cs_totalBytesRecv);
Expand Down
9 changes: 6 additions & 3 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,8 @@ class CConnman
void SetAsmap(std::vector<bool> asmap) { addrman.m_asmap = std::move(asmap); }
/** Unique tier two connections manager */
TierTwoConnMan* GetTierTwoConnMan() { return m_tiertwo_conn_man.get(); };
/** Update the node to be a iqr member if needed */
void UpdateQuorumRelayMemberIfNeeded(CNode* pnode);
private:
struct ListenSocket {
SOCKET socket;
Expand Down Expand Up @@ -664,9 +666,10 @@ class CNode
bool fFeeler; // If true this node is being used as a short lived feeler.
bool fOneShot;
bool fAddnode;
bool m_masternode_connection{false}; // If true this node is only used for quorum related messages.
bool m_masternode_probe_connection{false}; // If true this will be disconnected right after the verack.
bool m_masternode_iqr_connection{false}; // If 'true', we identified it as an intra-quorum relay connection.
std::atomic<bool> m_masternode_connection{false}; // If true this node is only used for quorum related messages.
std::atomic<bool> m_masternode_probe_connection{false}; // If true this will be disconnected right after the verack.
std::atomic<bool> m_masternode_iqr_connection{false}; // If 'true', we identified it as an intra-quorum relay connection.
std::atomic<int64_t> m_last_wants_recsigs_recv{0}; // the last time that a recsigs msg was received, used to avoid spam.
bool fClient;
const bool fInbound;
/**
Expand Down
30 changes: 22 additions & 8 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ void PushNodeVersion(CNode* pnode, CConnman* connman, int64_t nTime)
WITH_LOCK(pnode->cs_mnauth, pnode->sentMNAuthChallenge = mnauthChallenge);

connman->PushMessage(pnode, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERSION, PROTOCOL_VERSION, (uint64_t)nLocalNodeServices, nTime, addrYou, addrMe,
nonce, strSubVersion, nNodeStartingHeight, true, pnode->m_masternode_connection, pnode->sentMNAuthChallenge));
nonce, strSubVersion, nNodeStartingHeight, true, pnode->m_masternode_connection.load(), pnode->sentMNAuthChallenge));

if (fLogIPs)
LogPrint(BCLog::NET, "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nNodeStartingHeight, addrMe.ToString(), addrYou.ToString(), nodeid);
Expand Down Expand Up @@ -1353,6 +1353,27 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
return false;
}

else if (strCommand == NetMsgType::QSENDRECSIGS) {
bool b;
vRecv >> b;
if (pfrom->m_wants_recsigs == b) return true;
// Only accept recsigs messages every 20 min to prevent spam.
int64_t nNow = GetAdjustedTime();
if (pfrom->m_last_wants_recsigs_recv > 0 &&
nNow - pfrom->m_last_wants_recsigs_recv < 20 * 60) {
LOCK(cs_main);
Misbehaving(pfrom->GetId(), 20, "sendrecssigs msg is only accepted every 20 minutes");
return false;
}
pfrom->m_wants_recsigs = b;
pfrom->m_last_wants_recsigs_recv = nNow;
// Check if this is a iqr connection, and update the value
// if we haven't updated the connection during:
// (1) the relay quorum set function call, and (2) the verack receive.
connman->UpdateQuorumRelayMemberIfNeeded(pfrom);
return true;
}

if (strCommand != NetMsgType::SENDADDRV2 && // todo: remove this..
!pfrom->fFirstMessageReceived.exchange(true)) {
// First message after VERSION/VERACK (without counting the SENDADDRV2)
Expand Down Expand Up @@ -1414,13 +1435,6 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
pfrom->fDisconnect = true;
}

else if (strCommand == NetMsgType::QSENDRECSIGS) {
bool b;
vRecv >> b;
pfrom->m_wants_recsigs = b;
return true;
}

else if (strCommand == NetMsgType::INV) {
std::vector<CInv> vInv;
vRecv >> vInv;
Expand Down

0 comments on commit 747f838

Please sign in to comment.