Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop tracking interested/participating nodes and send/announce to MNAUTH peers #2798

Merged
merged 5 commits into from
Mar 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 7 additions & 16 deletions src/llmq/quorums_dkgsession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1244,26 +1244,17 @@ void CDKGSession::MarkBadMember(size_t idx)
member->bad = true;
}

void CDKGSession::AddParticipatingNode(NodeId nodeId)
{
LOCK(invCs);
g_connman->ForNode(nodeId, [&](CNode* pnode) {
if (!participatingNodes.emplace(pnode->addr).second) {
return true;
}

for (const auto& inv : invSet) {
pnode->PushInventory(inv);
}
return true;
});
}

void CDKGSession::RelayInvToParticipants(const CInv& inv) const
{
LOCK(invCs);
g_connman->ForEachNode([&](CNode* pnode) {
if (participatingNodes.count(pnode->addr)) {
bool relay = false;
if (pnode->qwatch) {
relay = true;
} else if (!pnode->verifiedProRegTxHash.IsNull() && membersMap.count(pnode->verifiedProRegTxHash)) {
relay = true;
}
if (relay) {
pnode->PushInventory(inv);
}
});
Expand Down
2 changes: 0 additions & 2 deletions src/llmq/quorums_dkgsession.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,6 @@ class CDKGSession
std::map<uint256, CDKGJustification> justifications;
std::map<uint256, CDKGPrematureCommitment> prematureCommitments;
std::set<CInv> invSet;
std::set<CService> participatingNodes;

std::vector<size_t> pendingContributionVerifications;

Expand Down Expand Up @@ -336,7 +335,6 @@ class CDKGSession
bool AreWeMember() const { return !myProTxHash.IsNull(); }
void MarkBadMember(size_t idx);

void AddParticipatingNode(NodeId nodeId);
void RelayInvToParticipants(const CInv& inv) const;

public:
Expand Down
14 changes: 0 additions & 14 deletions src/llmq/quorums_dkgsessionhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,14 +435,6 @@ bool ProcessPendingMessageBatch(CDKGSession& session, CDKGPendingMessages& pendi
}
}

for (const auto& p : preverifiedMessages) {
NodeId nodeId = p.first;
if (badNodes.count(nodeId)) {
continue;
}
session.AddParticipatingNode(nodeId);
}

return true;
}

Expand Down Expand Up @@ -492,12 +484,6 @@ void CDKGSessionHandler::HandleDKGRound()
}
LogPrint("llmq", debugMsg);
g_connman->AddMasternodeQuorumNodes(params.type, curQuorumHash, connections);

auto participatingNodesTmp = g_connman->GetMasternodeQuorumAddresses(params.type, curQuorumHash);
LOCK(curSession->invCs);
for (auto& p : participatingNodesTmp) {
curSession->participatingNodes.emplace(p.first);
}
}
}

Expand Down
4 changes: 0 additions & 4 deletions src/llmq/quorums_dkgsessionmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,6 @@ void CDKGSessionManager::ProcessMessage(CNode* pfrom, const std::string& strComm

if (strCommand == NetMsgType::QWATCH) {
pfrom->qwatch = true;
for (auto& p : dkgSessionHandlers) {
LOCK2(p.second.cs, p.second.curSession->invCs);
p.second.curSession->participatingNodes.emplace(pfrom->addr);
}
return;
}

Expand Down
50 changes: 12 additions & 38 deletions src/llmq/quorums_signing_shares.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -644,13 +644,7 @@ void CSigSharesManager::ProcessPendingSigSharesFromNode(NodeId nodeId,

cxxtimer::Timer t(true);
for (auto& sigShare : sigShares) {
// he sent us some valid sig shares, so he must be part of this quorum and is thus interested in our sig shares as well
// if this is the first time we received a sig share from this node, we won't announce the currently locally known sig shares to him.
// only the upcoming sig shares will be announced to him. this means the first signing session for a fresh quorum will be a bit
// slower than for older ones. TODO: fix this (risk of DoS when announcing all at once?)
auto quorumKey = std::make_pair((Consensus::LLMQType)sigShare.llmqType, sigShare.quorumHash);
nodeState.interestedIn.emplace(quorumKey);

ProcessSigShare(nodeId, sigShare, connman, quorums.at(quorumKey));
}
t.stop();
Expand All @@ -670,10 +664,6 @@ void CSigSharesManager::ProcessSigShare(NodeId nodeId, const CSigShare& sigShare
std::set<NodeId> quorumNodes;
if (sigShare.quorumMember == quorum->GetMemberIndex(activeMasternodeInfo.proTxHash)) {
quorumNodes = connman.GetMasternodeQuorumNodes((Consensus::LLMQType) sigShare.llmqType, sigShare.quorumHash);
// make sure node states are created for these nodes (we might have not received any message from these yet)
for (auto otherNodeId : quorumNodes) {
nodeStates[otherNodeId].interestedIn.emplace(std::make_pair((Consensus::LLMQType)sigShare.llmqType, sigShare.quorumHash));
}
}

if (quorumSigningManager->HasRecoveredSigForId(llmqType, sigShare.id)) {
Expand Down Expand Up @@ -702,12 +692,9 @@ void CSigSharesManager::ProcessSigShare(NodeId nodeId, const CSigShare& sigShare
if (!quorumNodes.empty()) {
// don't announce and wait for other nodes to request this share and directly send it to them
// there is no way the other nodes know about this share as this is the one created on this node
// this will also indicate interest to the other nodes in sig shares for this quorum
for (auto& p : nodeStates) {
if (!quorumNodes.count(p.first) && !p.second.interestedIn.count(std::make_pair((Consensus::LLMQType)sigShare.llmqType, sigShare.quorumHash))) {
continue;
}
auto& session = p.second.GetOrCreateSessionFromShare(sigShare);
for (auto otherNodeId : quorumNodes) {
auto& nodeState = nodeStates[otherNodeId];
auto& session = nodeState.GetOrCreateSessionFromShare(sigShare);
session.quorum = quorum;
session.requested.Set(sigShare.quorumMember, true);
session.knows.Set(sigShare.quorumMember, true);
Expand Down Expand Up @@ -942,7 +929,7 @@ void CSigSharesManager::CollectSigSharesToAnnounce(std::unordered_map<NodeId, st
{
AssertLockHeld(cs);

std::unordered_set<std::pair<Consensus::LLMQType, uint256>, StaticSaltedHasher> quorumNodesPrepared;
std::unordered_map<std::pair<Consensus::LLMQType, uint256>, std::unordered_set<NodeId>, StaticSaltedHasher> quorumNodesMap;

this->sigSharesToAnnounce.ForEach([&](const SigShareKey& sigShareKey, bool) {
auto& signHash = sigShareKey.first;
Expand All @@ -952,30 +939,20 @@ void CSigSharesManager::CollectSigSharesToAnnounce(std::unordered_map<NodeId, st
return;
}

// announce to the nodes which we know through the intra-quorum-communication system
auto quorumKey = std::make_pair((Consensus::LLMQType)sigShare->llmqType, sigShare->quorumHash);
if (quorumNodesPrepared.emplace(quorumKey).second) {
// make sure we announce to at least the nodes which we know through the inter-quorum-communication system
auto it = quorumNodesMap.find(quorumKey);
if (it == quorumNodesMap.end()) {
auto nodeIds = g_connman->GetMasternodeQuorumNodes(quorumKey.first, quorumKey.second);
for (auto nodeId : nodeIds) {
auto& nodeState = nodeStates[nodeId];
nodeState.interestedIn.emplace(quorumKey);
}
it = quorumNodesMap.emplace(std::piecewise_construct, std::forward_as_tuple(quorumKey), std::forward_as_tuple(nodeIds.begin(), nodeIds.end())).first;
}

for (auto& p : nodeStates) {
auto nodeId = p.first;
auto& nodeState = p.second;
auto& quorumNodes = it->second;

if (nodeState.banned) {
continue;
}
for (auto& nodeId : quorumNodes) {
auto& nodeState = nodeStates[nodeId];

if (!nodeState.interestedIn.count(quorumKey)) {
// node is not interested in this sig share
// we only consider nodes to be interested if they sent us valid sig share before
// the sig share that we sign by ourself circumvents the inv system and is directly sent to all quorum members
// which are known by the deterministic inter-quorum-communication system. This is also the sig share that
// will tell the other nodes that we are interested in future sig shares
if (nodeState.banned) {
continue;
}

Expand All @@ -997,9 +974,6 @@ void CSigSharesManager::CollectSigSharesToAnnounce(std::unordered_map<NodeId, st
});

// don't announce these anymore
// nodes which did not send us a valid sig share before were left out now, but this is ok as it only results in slower
// propagation for the first signing session of a fresh quorum. The sig shares should still arrive on all nodes due to
// the deterministic inter-quorum-communication system
this->sigSharesToAnnounce.Clear();
}

Expand Down
4 changes: 0 additions & 4 deletions src/llmq/quorums_signing_shares.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,10 +316,6 @@ class CSigSharesNodeState
SigShareMap<CSigShare> pendingIncomingSigShares;
SigShareMap<int64_t> requestedSigShares;

// elements are added whenever we receive a valid sig share from this node
// this triggers us to send inventory items to him as he seems to be interested in these
std::unordered_set<std::pair<Consensus::LLMQType, uint256>, StaticSaltedHasher> interestedIn;

bool banned{false};

Session& GetOrCreateSessionFromShare(const CSigShare& sigShare);
Expand Down
2 changes: 1 addition & 1 deletion src/masternode-utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void CMasternodeUtils::ProcessMasternodeConnections(CConnman& connman)
#endif // ENABLE_WALLET

connman.ForEachNode(CConnman::AllNodes, [&](CNode* pnode) {
if (pnode->fMasternode && !connman.IsMasternodeQuorumNode(pnode->addr)) {
if (pnode->fMasternode && !connman.IsMasternodeQuorumNode(pnode)) {
#ifdef ENABLE_WALLET
bool fFound = false;
for (const auto& dmn : vecDmns) {
Expand Down
29 changes: 15 additions & 14 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2749,29 +2749,25 @@ std::set<uint256> CConnman::GetMasternodeQuorums(Consensus::LLMQType llmqType)
return result;
}

std::map<CService, uint256> CConnman::GetMasternodeQuorumAddresses(Consensus::LLMQType llmqType, const uint256& quorumHash) const
{
LOCK(cs_vPendingMasternodes);
auto it = masternodeQuorumNodes.find(std::make_pair(llmqType, quorumHash));
if (it == masternodeQuorumNodes.end()) {
return {};
}
return it->second;
}

std::set<NodeId> CConnman::GetMasternodeQuorumNodes(Consensus::LLMQType llmqType, const uint256& quorumHash) const
{
LOCK2(cs_vNodes, cs_vPendingMasternodes);
auto it = masternodeQuorumNodes.find(std::make_pair(llmqType, quorumHash));
if (it == masternodeQuorumNodes.end()) {
return {};
}
std::set<uint256> proRegTxHashes;
for (auto& p : it->second) {
proRegTxHashes.emplace(p.second);
}

std::set<NodeId> nodes;
for (const auto pnode : vNodes) {
if (pnode->fDisconnect) {
continue;
}
if (!pnode->qwatch && !it->second.count(pnode->addr)) {
if (!pnode->qwatch && !it->second.count(pnode->addr) &&
(pnode->verifiedProRegTxHash.IsNull() || !proRegTxHashes.count(pnode->verifiedProRegTxHash))) {
continue;
}
nodes.emplace(pnode->id);
Expand All @@ -2785,12 +2781,17 @@ void CConnman::RemoveMasternodeQuorumNodes(Consensus::LLMQType llmqType, const u
masternodeQuorumNodes.erase(std::make_pair(llmqType, quorumHash));
}

bool CConnman::IsMasternodeQuorumNode(const CService& addr)
bool CConnman::IsMasternodeQuorumNode(const CNode* pnode)
{
LOCK(cs_vPendingMasternodes);
for (const auto& p : masternodeQuorumNodes) {
if (p.second.count(addr)) {
return true;
for (const auto& p2 : p.second) {
if (p2.first == (CService)pnode->addr) {
return true;
}
if (!pnode->verifiedProRegTxHash.IsNull() && p2.second == pnode->verifiedProRegTxHash) {
return true;
}
}
}
return false;
Expand Down
3 changes: 1 addition & 2 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,11 +361,10 @@ class CConnman
bool AddMasternodeQuorumNodes(Consensus::LLMQType llmqType, const uint256& quorumHash, const std::map<CService, uint256>& addresses);
bool HasMasternodeQuorumNodes(Consensus::LLMQType llmqType, const uint256& quorumHash);
std::set<uint256> GetMasternodeQuorums(Consensus::LLMQType llmqType);
std::map<CService, uint256> GetMasternodeQuorumAddresses(Consensus::LLMQType llmqType, const uint256& quorumHash) const;
// also returns QWATCH nodes
std::set<NodeId> GetMasternodeQuorumNodes(Consensus::LLMQType llmqType, const uint256& quorumHash) const;
void RemoveMasternodeQuorumNodes(Consensus::LLMQType llmqType, const uint256& quorumHash);
bool IsMasternodeQuorumNode(const CService& addr);
bool IsMasternodeQuorumNode(const CNode* pnode);

size_t GetNodeCount(NumConnections num);
void GetNodeStats(std::vector<CNodeStats>& vstats);
Expand Down