Skip to content

Commit

Permalink
net_mn: cache MN quorum relay members + let them know that we are int…
Browse files Browse the repository at this point in the history
…erested in plain LLMQ recovered signatures.
  • Loading branch information
furszy committed Jan 17, 2022
1 parent 1c16a2f commit 3897ae5
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 4 deletions.
11 changes: 10 additions & 1 deletion src/evo/mnauth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "llmq/quorums_utils.h"
#include "util/system.h" // for fMasternode and gArgs access
#include "net_processing.h" // for cs_main
#include "tiertwo/net_masternodes.h"
#include "version.h" // for MNAUTH_NODE_VER_VERSION

void CMNAuth::PushMNAUTH(CNode* pnode, CConnman& connman)
Expand Down Expand Up @@ -189,7 +190,15 @@ void CMNAuth::ProcessMessage(CNode* pnode, const std::string& strCommand, CDataS
pnode->verifiedPubKeyHash = dmn->pdmnState->pubKeyOperator.GetHash();
}

// todo: add iqr connection, send interest in plain LLMQ recovered signatures.
if (!pnode->m_masternode_iqr_connection && connman.GetTierTwoConnMan()->isMasternodeQuorumRelayMember(pnode->verifiedProRegTxHash)) {
// Tell our peer that we're interested in plain LLMQ recovered signatures.
// Otherwise, the peer would only announce/send messages resulting from QRECSIG,
// future e.g. tx locks or chainlocks. SPV and regular full nodes should not send
// this message as they are usually only interested in the higher level messages.
CNetMsgMaker msgMaker(pnode->GetSendVersion());
connman.PushMessage(pnode, msgMaker.Make(NetMsgType::QSENDRECSIGS, true));
pnode->m_masternode_iqr_connection = true;
}

LogPrint(BCLog::NET_MN, "CMNAuth::%s -- Valid MNAUTH for %s, peer=%d\n", __func__, mnauth.proRegTxHash.ToString(), pnode->GetId());
}
Expand Down
10 changes: 7 additions & 3 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,8 @@ class CConnman
unsigned int GetReceiveFloodSize() const;

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(); };
private:
struct ListenSocket {
SOCKET socket;
Expand Down Expand Up @@ -565,6 +567,8 @@ class CNodeStats
bool m_masternode_connection{false};
// If 'true' this node will be disconnected after MNAUTH
bool m_masternode_probe_connection{false};
// If 'true', we identified it as an intra-quorum relay connection
bool m_masternode_iqr_connection{false};
// In case this is a verified MN, this value is the proTx of the MN
uint256 verifiedProRegTxHash;
// In case this is a verified MN, this value is the hashed operator pubkey of the MN
Expand Down Expand Up @@ -661,7 +665,8 @@ class CNode
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_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.
bool fClient;
const bool fInbound;
/**
Expand Down Expand Up @@ -917,8 +922,7 @@ class CNode
//! Sets the addrName only if it was not previously set
void MaybeSetAddrName(const std::string& addrNameIn);

// todo: add iqr connection
bool CanRelay() const { return !m_masternode_connection; }
bool CanRelay() const { return !m_masternode_connection || m_masternode_iqr_connection; }
};

class CExplicitNetCleanup
Expand Down
39 changes: 39 additions & 0 deletions src/tiertwo/net_masternodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "scheduler.h"
#include "tiertwo/masternode_meta_manager.h" // for g_mmetaman
#include "masternode-sync.h" // for IsBlockchainSynced
#include "netmessagemaker.h"

TierTwoConnMan::TierTwoConnMan(CConnman* _connman) : connman(_connman) {}
TierTwoConnMan::~TierTwoConnMan() { connman = nullptr; }
Expand Down Expand Up @@ -37,6 +38,30 @@ void TierTwoConnMan::removeQuorumNodes(Consensus::LLMQType llmqType, const uint2
masternodeQuorumNodes.erase(std::make_pair(llmqType, quorumHash));
}

void TierTwoConnMan::setMasternodeQuorumRelayMembers(Consensus::LLMQType llmqType, const uint256& quorumHash, const std::set<uint256>& proTxHashes)
{
{
LOCK(cs_vPendingMasternodes);
auto it = masternodeQuorumRelayMembers.emplace(std::make_pair(llmqType, quorumHash), proTxHashes);
if (!it.second) {
it.first->second = proTxHashes;
}
}

// Update existing connections
connman->ForEachNode([&](CNode* pnode) {
if (!pnode->verifiedProRegTxHash.IsNull() && !pnode->m_masternode_iqr_connection && isMasternodeQuorumRelayMember(pnode->verifiedProRegTxHash)) {
// Tell our peer that we're interested in plain LLMQ recovered signatures.
// Otherwise, the peer would only announce/send messages resulting from QRECSIG,
// future e.g. tx locks or chainlocks. SPV and regular full nodes should not send
// this message as they are usually only interested in the higher level messages.
CNetMsgMaker msgMaker(pnode->GetSendVersion());
connman->PushMessage(pnode, msgMaker.Make(NetMsgType::QSENDRECSIGS, true));
pnode->m_masternode_iqr_connection = true;
}
});
}

bool TierTwoConnMan::isMasternodeQuorumNode(const CNode* pnode)
{
// Let's see if this is an outgoing connection to an address that is known to be a masternode
Expand Down Expand Up @@ -67,6 +92,20 @@ bool TierTwoConnMan::isMasternodeQuorumNode(const CNode* pnode)
return false;
}

bool TierTwoConnMan::isMasternodeQuorumRelayMember(const uint256& protxHash)
{
if (protxHash.IsNull()) {
return false;
}
LOCK(cs_vPendingMasternodes);
for (const auto& p : masternodeQuorumRelayMembers) {
if (p.second.count(protxHash) > 0) {
return true;
}
}
return false;
}

bool TierTwoConnMan::addPendingMasternode(const uint256& proTxHash)
{
LOCK(cs_vPendingMasternodes);
Expand Down
7 changes: 7 additions & 0 deletions src/tiertwo/net_masternodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,15 @@ class TierTwoConnMan
// Remove the registered quorum from the pending/protected MN connections
void removeQuorumNodes(Consensus::LLMQType llmqType, const uint256& quorumHash);

// Add MNs to the active quorum relay members map and push QSENDRECSIGS to the verified connected peers that are part of this new quorum.
void setMasternodeQuorumRelayMembers(Consensus::LLMQType llmqType, const uint256& quorumHash, const std::set<uint256>& proTxHashes);

// Returns true if the node has the same address as a MN.
bool isMasternodeQuorumNode(const CNode* pnode);

// Whether protxHash an active quorum relay member
bool isMasternodeQuorumRelayMember(const uint256& protxHash);

// Add DMN to the pending connection list
bool addPendingMasternode(const uint256& proTxHash);

Expand All @@ -63,6 +69,7 @@ class TierTwoConnMan
std::vector<uint256> vPendingMasternodes GUARDED_BY(cs_vPendingMasternodes);
typedef std::pair<Consensus::LLMQType, uint256> QuorumTypeAndHash;
std::map<QuorumTypeAndHash, std::set<uint256>> masternodeQuorumNodes GUARDED_BY(cs_vPendingMasternodes);
std::map<QuorumTypeAndHash, std::set<uint256>> masternodeQuorumRelayMembers GUARDED_BY(cs_vPendingMasternodes);
std::set<uint256> masternodePendingProbes GUARDED_BY(cs_vPendingMasternodes);

// parent connections manager
Expand Down

0 comments on commit 3897ae5

Please sign in to comment.