1111#include < init.h>
1212#include < net_processing.h>
1313#include < netmessagemaker.h>
14+ #include < spork.h>
1415#include < validation.h>
1516
1617#include < cxxtimer.hpp>
@@ -236,6 +237,23 @@ void CSigSharesManager::ProcessMessage(CNode* pfrom, const std::string& strComma
236237 return ;
237238 }
238239
240+ if (sporkManager.IsSporkActive (SPORK_21_QUORUM_ALL_CONNECTED)) {
241+ if (strCommand == NetMsgType::QSIGSHARE) {
242+ std::vector<CSigShare> sigShares;
243+ vRecv >> sigShares;
244+
245+ if (sigShares.size () > MAX_MSGS_SIG_SHARES) {
246+ LogPrint (BCLog::LLMQ_SIGS, " CSigSharesManager::%s -- too many sigs in QSIGSHARE message. cnt=%d, max=%d, node=%d\n " , __func__, sigShares.size (), MAX_MSGS_SIG_SHARES, pfrom->GetId ());
247+ BanNode (pfrom->GetId ());
248+ return ;
249+ }
250+
251+ for (auto & sigShare : sigShares) {
252+ ProcessMessageSigShare (pfrom->GetId (), sigShare, connman);
253+ }
254+ }
255+ }
256+
239257 if (strCommand == NetMsgType::QSIGSESANN) {
240258 std::vector<CSigSesAnn> msgs;
241259 vRecv >> msgs;
@@ -465,6 +483,57 @@ bool CSigSharesManager::ProcessMessageBatchedSigShares(CNode* pfrom, const CBatc
465483 return true ;
466484}
467485
486+ void CSigSharesManager::ProcessMessageSigShare (NodeId fromId, const CSigShare& sigShare, CConnman& connman)
487+ {
488+ auto quorum = quorumManager->GetQuorum (sigShare.llmqType , sigShare.quorumHash );
489+ if (!quorum) {
490+ return ;
491+ }
492+ if (!CLLMQUtils::IsQuorumActive (sigShare.llmqType , quorum->qc .quorumHash )) {
493+ // quorum is too old
494+ return ;
495+ }
496+ if (!quorum->IsMember (activeMasternodeInfo.proTxHash )) {
497+ // we're not a member so we can't verify it (we actually shouldn't have received it)
498+ return ;
499+ }
500+ if (quorum->quorumVvec == nullptr ) {
501+ // TODO we should allow to ask other nodes for the quorum vvec if we missed it in the DKG
502+ LogPrint (BCLog::LLMQ_SIGS, " CSigSharesManager::%s -- we don't have the quorum vvec for %s, no verification possible. node=%d\n " , __func__,
503+ quorum->qc .quorumHash .ToString (), fromId);
504+ return ;
505+ }
506+
507+ if (sigShare.quorumMember >= quorum->members .size ()) {
508+ LogPrint (BCLog::LLMQ_SIGS, " CSigSharesManager::%s -- quorumMember out of bounds\n " , __func__);
509+ BanNode (fromId);
510+ return ;
511+ }
512+ if (!quorum->qc .validMembers [sigShare.quorumMember ]) {
513+ LogPrint (BCLog::LLMQ_SIGS, " CSigSharesManager::%s -- quorumMember not valid\n " , __func__);
514+ BanNode (fromId);
515+ return ;
516+ }
517+
518+ {
519+ LOCK (cs);
520+
521+ if (sigShares.Has (sigShare.GetKey ())) {
522+ return ;
523+ }
524+
525+ if (quorumSigningManager->HasRecoveredSigForId ((Consensus::LLMQType)sigShare.llmqType , sigShare.id )) {
526+ return ;
527+ }
528+
529+ auto & nodeState = nodeStates[fromId];
530+ nodeState.pendingIncomingSigShares .Add (sigShare.GetKey (), sigShare);
531+ }
532+
533+ LogPrint (BCLog::LLMQ_SIGS, " CSigSharesManager::%s -- signHash=%s, id=%s, msgHash=%s, member=%d, node=%d\n " , __func__,
534+ sigShare.GetSignHash ().ToString (), sigShare.id .ToString (), sigShare.msgHash .ToString (), sigShare.quorumMember , fromId);
535+ }
536+
468537bool CSigSharesManager::PreVerifyBatchedSigShares (NodeId nodeId, const CSigSharesNodeState::SessionInfo& session, const CBatchedSigShares& batchedSigShares, bool & retBan)
469538{
470539 retBan = false ;
@@ -668,8 +737,10 @@ void CSigSharesManager::ProcessSigShare(NodeId nodeId, const CSigShare& sigShare
668737
669738 // prepare node set for direct-push in case this is our sig share
670739 std::set<NodeId> quorumNodes;
671- if (sigShare.quorumMember == quorum->GetMemberIndex (activeMasternodeInfo.proTxHash )) {
672- quorumNodes = connman.GetMasternodeQuorumNodes ((Consensus::LLMQType) sigShare.llmqType , sigShare.quorumHash );
740+ if (!sporkManager.IsSporkActive (SPORK_21_QUORUM_ALL_CONNECTED)) {
741+ if (sigShare.quorumMember == quorum->GetMemberIndex (activeMasternodeInfo.proTxHash )) {
742+ quorumNodes = connman.GetMasternodeQuorumNodes ((Consensus::LLMQType) sigShare.llmqType , sigShare.quorumHash );
743+ }
673744 }
674745
675746 if (quorumSigningManager->HasRecoveredSigForId (llmqType, sigShare.id )) {
@@ -780,6 +851,21 @@ void CSigSharesManager::TryRecoverSig(const CQuorumCPtr& quorum, const uint256&
780851 quorumSigningManager->ProcessRecoveredSig (-1 , rs, quorum, connman);
781852}
782853
854+ CDeterministicMNCPtr CSigSharesManager::SelectMemberForRecovery (const CQuorumCPtr& quorum, const uint256 &id, int attempt)
855+ {
856+ assert (attempt < quorum->members .size ());
857+
858+ std::vector<std::pair<uint256, CDeterministicMNCPtr>> v;
859+ v.reserve (quorum->members .size ());
860+ for (const auto & dmn : quorum->members ) {
861+ auto h = ::SerializeHash (std::make_pair (dmn->proTxHash , id));
862+ v.emplace_back (h, dmn);
863+ }
864+ std::sort (v.begin (), v.end ());
865+
866+ return v[attempt].second ;
867+ }
868+
783869void CSigSharesManager::CollectSigSharesToRequest (std::unordered_map<NodeId, std::unordered_map<uint256, CSigSharesInv, StaticSaltedHasher>>& sigSharesToRequest)
784870{
785871 AssertLockHeld (cs);
@@ -928,6 +1014,43 @@ void CSigSharesManager::CollectSigSharesToSend(std::unordered_map<NodeId, std::u
9281014 }
9291015}
9301016
1017+ void CSigSharesManager::CollectSigSharesToSend (std::unordered_map<NodeId, std::vector<CSigShare>>& sigSharesToSend, const std::vector<CNode*>& vNodes)
1018+ {
1019+ AssertLockHeld (cs);
1020+
1021+ std::unordered_map<uint256, CNode*> proTxToNode;
1022+ for (const auto & pnode : vNodes) {
1023+ if (pnode->verifiedProRegTxHash .IsNull ()) {
1024+ continue ;
1025+ }
1026+ proTxToNode.emplace (pnode->verifiedProRegTxHash , pnode);
1027+ }
1028+
1029+ auto curTime = GetTime ();
1030+
1031+ for (auto & p : signedSessions) {
1032+ if (p.second .attempt > p.second .quorum ->params .recoveryMembers ) {
1033+ continue ;
1034+ }
1035+
1036+ if (curTime >= p.second .nextAttemptTime ) {
1037+ p.second .nextAttemptTime = curTime + SEND_FOR_RECOVERY_TIMEOUT;
1038+ auto dmn = SelectMemberForRecovery (p.second .quorum , p.second .sigShare .id , p.second .attempt );
1039+ LogPrint (BCLog::LLMQ_SIGS, " CSigSharesManager::%s -- sending to %s, signHash=%s\n " , __func__,
1040+ dmn->proTxHash .ToString (), p.second .sigShare .GetSignHash ().ToString ());
1041+ p.second .attempt ++;
1042+
1043+ auto it = proTxToNode.find (dmn->proTxHash );
1044+ if (it == proTxToNode.end ()) {
1045+ continue ;
1046+ }
1047+
1048+ auto & m = sigSharesToSend[it->second ->GetId ()];
1049+ m.emplace_back (p.second .sigShare );
1050+ }
1051+ }
1052+ }
1053+
9311054void CSigSharesManager::CollectSigSharesToAnnounce (std::unordered_map<NodeId, std::unordered_map<uint256, CSigSharesInv, StaticSaltedHasher>>& sigSharesToAnnounce)
9321055{
9331056 AssertLockHeld (cs);
@@ -983,7 +1106,8 @@ void CSigSharesManager::CollectSigSharesToAnnounce(std::unordered_map<NodeId, st
9831106bool CSigSharesManager::SendMessages ()
9841107{
9851108 std::unordered_map<NodeId, std::unordered_map<uint256, CSigSharesInv, StaticSaltedHasher>> sigSharesToRequest;
986- std::unordered_map<NodeId, std::unordered_map<uint256, CBatchedSigShares, StaticSaltedHasher>> sigSharesToSend;
1109+ std::unordered_map<NodeId, std::unordered_map<uint256, CBatchedSigShares, StaticSaltedHasher>> sigShareBatchesToSend;
1110+ std::unordered_map<NodeId, std::vector<CSigShare>> sigSharesToSend;
9871111 std::unordered_map<NodeId, std::unordered_map<uint256, CSigSharesInv, StaticSaltedHasher>> sigSharesToAnnounce;
9881112 std::unordered_map<NodeId, std::vector<CSigSesAnn>> sigSessionAnnouncements;
9891113
@@ -1006,18 +1130,24 @@ bool CSigSharesManager::SendMessages()
10061130 return session->sendSessionId ;
10071131 };
10081132
1133+ std::vector<CNode*> vNodesCopy = g_connman->CopyNodeVector (CConnman::FullyConnectedOnly);
1134+
10091135 {
10101136 LOCK (cs);
1011- CollectSigSharesToRequest (sigSharesToRequest);
1012- CollectSigSharesToSend (sigSharesToSend);
1013- CollectSigSharesToAnnounce (sigSharesToAnnounce);
1137+ if (!sporkManager.IsSporkActive (SPORK_21_QUORUM_ALL_CONNECTED)) {
1138+ CollectSigSharesToRequest (sigSharesToRequest);
1139+ CollectSigSharesToSend (sigShareBatchesToSend);
1140+ CollectSigSharesToAnnounce (sigSharesToAnnounce);
1141+ } else {
1142+ CollectSigSharesToSend (sigSharesToSend, vNodesCopy);
1143+ }
10141144
10151145 for (auto & p : sigSharesToRequest) {
10161146 for (auto & p2 : p.second ) {
10171147 p2.second .sessionId = addSigSesAnnIfNeeded (p.first , p2.first );
10181148 }
10191149 }
1020- for (auto & p : sigSharesToSend ) {
1150+ for (auto & p : sigShareBatchesToSend ) {
10211151 for (auto & p2 : p.second ) {
10221152 p2.second .sessionId = addSigSesAnnIfNeeded (p.first , p2.first );
10231153 }
@@ -1031,8 +1161,6 @@ bool CSigSharesManager::SendMessages()
10311161
10321162 bool didSend = false ;
10331163
1034- std::vector<CNode*> vNodesCopy = g_connman->CopyNodeVector (CConnman::FullyConnectedOnly);
1035-
10361164 for (auto & pnode : vNodesCopy) {
10371165 CNetMsgMaker msgMaker (pnode->GetSendVersion ());
10381166
@@ -1076,8 +1204,8 @@ bool CSigSharesManager::SendMessages()
10761204 }
10771205 }
10781206
1079- auto jt = sigSharesToSend .find (pnode->GetId ());
1080- if (jt != sigSharesToSend .end ()) {
1207+ auto jt = sigShareBatchesToSend .find (pnode->GetId ());
1208+ if (jt != sigShareBatchesToSend .end ()) {
10811209 size_t totalSigsCount = 0 ;
10821210 std::vector<CBatchedSigShares> msgs;
10831211 for (auto & p : jt->second ) {
@@ -1119,6 +1247,25 @@ bool CSigSharesManager::SendMessages()
11191247 didSend = true ;
11201248 }
11211249 }
1250+
1251+ auto lt = sigSharesToSend.find (pnode->GetId ());
1252+ if (lt != sigSharesToSend.end ()) {
1253+ std::vector<CSigShare> msgs;
1254+ for (auto & sigShare : lt->second ) {
1255+ LogPrint (BCLog::LLMQ_SIGS, " CSigSharesManager::SendMessages -- QSIGSHARE signHash=%s, node=%d\n " ,
1256+ sigShare.GetSignHash ().ToString (), pnode->GetId ());
1257+ msgs.emplace_back (std::move (sigShare));
1258+ if (msgs.size () == MAX_MSGS_SIG_SHARES) {
1259+ g_connman->PushMessage (pnode, msgMaker.Make (NetMsgType::QSIGSHARE, msgs), false );
1260+ msgs.clear ();
1261+ didSend = true ;
1262+ }
1263+ }
1264+ if (!msgs.empty ()) {
1265+ g_connman->PushMessage (pnode, msgMaker.Make (NetMsgType::QSIGSHARE, msgs), false );
1266+ didSend = true ;
1267+ }
1268+ }
11221269 }
11231270
11241271 // looped through all nodes, release them
@@ -1285,6 +1432,7 @@ void CSigSharesManager::RemoveSigSharesForSession(const uint256& signHash)
12851432 sigSharesRequested.EraseAllForSignHash (signHash);
12861433 sigSharesToAnnounce.EraseAllForSignHash (signHash);
12871434 sigShares.EraseAllForSignHash (signHash);
1435+ signedSessions.erase (signHash);
12881436 timeSeenForSessions.erase (signHash);
12891437}
12901438
@@ -1431,6 +1579,15 @@ void CSigSharesManager::Sign(const CQuorumCPtr& quorum, const uint256& id, const
14311579 LogPrint (BCLog::LLMQ_SIGS, " CSigSharesManager::%s -- signed sigShare. signHash=%s, id=%s, msgHash=%s, llmqType=%d, quorum=%s, time=%s\n " , __func__,
14321580 signHash.ToString (), sigShare.id .ToString (), sigShare.msgHash .ToString (), quorum->params .type , quorum->qc .quorumHash .ToString (), t.count ());
14331581 ProcessSigShare (-1 , sigShare, *g_connman, quorum);
1582+
1583+ if (sporkManager.IsSporkActive (SPORK_21_QUORUM_ALL_CONNECTED)) {
1584+ LOCK (cs);
1585+ auto & session = signedSessions[sigShare.GetSignHash ()];
1586+ session.sigShare = sigShare;
1587+ session.quorum = quorum;
1588+ session.nextAttemptTime = 0 ;
1589+ session.attempt = 0 ;
1590+ }
14341591}
14351592
14361593// causes all known sigShares to be re-announced
0 commit comments