21 #include "validation.h"
36 return strprintf(
"sessionId=%d, llmqType=%d, quorumHash=%s, id=%s, msgHash=%s",
42 for (
size_t i = 0; i <
inv.size(); i++) {
51 return (
size_t)std::count(
inv.begin(),
inv.end(),
true);
56 std::string str =
"(";
58 for (
size_t i = 0; i <
inv.size(); i++) {
75 inv.resize(size,
false);
80 assert(quorumMember <
inv.size());
81 return inv[quorumMember];
86 assert(quorumMember <
inv.size());
87 inv[quorumMember] = v;
92 for (
size_t i = 0; i <
inv.size(); i++) {
102 for (
size_t i = 0; i <
sigShares.size(); i++) {
108 template <
typename T>
137 InitSession(s, signHash, ann);
248 std::vector<CSigSesAnn> msgs;
251 LogPrintf(
"CSigSharesManager::%s -- too many announcements in QSIGSESANN message. cnt=%d, max=%d, node=%d\n", __func__, msgs.size(),
MAX_MSGS_CNT_QSIGSESANN, pfrom->
GetId());
255 for (
auto& ann : msgs) {
262 std::vector<CSigSharesInv> msgs;
265 LogPrintf(
"CSigSharesManager::%s -- too many invs in QSIGSHARESINV message. cnt=%d, max=%d, node=%d\n", __func__, msgs.size(),
MAX_MSGS_CNT_QSIGSHARESINV, pfrom->
GetId());
269 for (
auto& inv : msgs) {
276 std::vector<CSigSharesInv> msgs;
279 LogPrintf(
"CSigSharesManager::%s -- too many invs in QGETSIGSHARES message. cnt=%d, max=%d, node=%d\n", __func__, msgs.size(),
MAX_MSGS_CNT_QGETSIGSHARES, pfrom->
GetId());
283 for (
auto& inv : msgs) {
290 std::vector<CBatchedSigShares> msgs;
292 size_t totalSigsCount = 0;
293 for (
auto& bs : msgs) {
294 totalSigsCount += bs.sigShares.
size();
297 LogPrintf(
"CSigSharesManager::%s -- too many sigs in QBSIGSHARES message. cnt=%d, max=%d, node=%d\n", __func__, msgs.size(),
MAX_MSGS_TOTAL_BATCHED_SIGS, pfrom->
GetId());
301 for (
auto& bs : msgs) {
334 auto& session = nodeState.GetOrCreateSessionFromAnn(ann);
335 nodeState.sessionByRecvId.erase(session.recvSessionId);
336 nodeState.sessionByRecvId.erase(ann.
sessionId);
338 session.quorum = quorum;
339 nodeState.sessionByRecvId.emplace(ann.
sessionId, &session);
348 if (inv.
inv.size() != quorumSize) {
370 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::%s -- signHash=%s, inv={%s}, node=%d\n", __func__,
373 if (sessionInfo.
quorum->quorumVvec ==
nullptr) {
375 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::%s -- we don't have the quorum vvec for %s, not requesting sig shares. node=%d\n", __func__,
382 auto session = nodeState.GetSessionByRecvId(inv.
sessionId);
386 session->announced.Merge(inv);
387 session->knows.Merge(inv);
407 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::%s -- signHash=%s, inv={%s}, node=%d\n", __func__,
412 auto session = nodeState.GetSessionByRecvId(inv.
sessionId);
416 session->requested.Merge(inv);
417 session->knows.Merge(inv);
440 for (
size_t i = 0; i < batchedSigShares.
sigShares.size(); i++) {
442 nodeState.requestedSigShares.Erase(sigShare.
GetKey());
448 if (this->sigShares.Has(sigShare.
GetKey())) {
461 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::%s -- signHash=%s, shares=%d, new=%d, inv={%s}, node=%d\n", __func__,
471 nodeState.pendingIncomingSigShares.Add(s.GetKey(), s);
490 if (quorum->quorumVvec ==
nullptr) {
492 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::%s -- we don't have the quorum vvec for %s, no verification possible. node=%d\n", __func__,
493 quorum->qc.quorumHash.ToString(), fromId);
520 nodeState.pendingIncomingSigShares.Add(sigShare.
GetKey(), sigShare);
523 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::%s -- signHash=%s, id=%s, msgHash=%s, member=%d, node=%d\n", __func__,
539 if (session.
quorum->quorumVvec ==
nullptr) {
541 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::%s -- we don't have the quorum vvec for %s, no verification possible. node=%d\n", __func__,
546 std::unordered_set<uint16_t> dupMembers;
548 for (
size_t i = 0; i < batchedSigShares.
sigShares.size(); i++) {
549 auto quorumMember = batchedSigShares.
sigShares[i].first;
550 if (!dupMembers.emplace(quorumMember).second) {
555 if (quorumMember >= session.
quorum->members.size()) {
556 LogPrintf(
"CSigSharesManager::%s -- quorumMember out of bounds\n", __func__);
560 if (!session.
quorum->qc.validMembers[quorumMember]) {
561 LogPrintf(
"CSigSharesManager::%s -- quorumMember not valid\n", __func__);
570 size_t maxUniqueSessions,
571 std::unordered_map<
NodeId, std::vector<CSigShare>>& retSigShares,
588 if (ns.pendingIncomingSigShares.Empty()) {
591 auto& sigShare = *ns.pendingIncomingSigShares.GetFirst();
593 bool alreadyHave = this->
sigShares.Has(sigShare.GetKey());
595 uniqueSignHashes.emplace(nodeId, sigShare.GetSignHash());
596 retSigShares[nodeId].emplace_back(sigShare);
598 ns.pendingIncomingSigShares.Erase(sigShare.GetKey());
599 return !ns.pendingIncomingSigShares.Empty(); },
rnd);
601 if (retSigShares.empty()) {
611 for (
auto& p : retSigShares) {
612 for (
auto& sigShare : p.second) {
615 auto k = std::make_pair(llmqType, sigShare.quorumHash);
616 if (retQuorums.count(k)) {
621 assert(quorum !=
nullptr);
622 retQuorums.emplace(k, quorum);
630 std::unordered_map<NodeId, std::vector<CSigShare>> sigSharesByNodes;
634 if (sigSharesByNodes.empty()) {
643 size_t verifyCount = 0;
644 for (
auto& p : sigSharesByNodes) {
645 auto nodeId = p.first;
648 for (
auto& sigShare : v) {
655 if (!sigShare.sigShare.Get().IsValid()) {
661 auto quorum = quorums.at(std::make_pair((
Consensus::LLMQType)sigShare.llmqType, sigShare.quorumHash));
662 auto pubKeyShare = quorum->GetPubKeyShare(sigShare.quorumMember);
664 if (!pubKeyShare.IsValid()) {
667 LogPrintf(
"CSigSharesManager::%s -- pubKeyShare is invalid, which should not be possible here.\n", __func__);
671 batchVerifier.
PushMessage(nodeId, sigShare.GetKey(), sigShare.GetSignHash(), sigShare.sigShare.Get(), pubKeyShare);
681 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::%s -- verified sig shares. count=%d, pt=%d, vt=%d, nodes=%d\n", __func__, verifyCount, prepareTimer.
count(), verifyTimer.
count(), sigSharesByNodes.size());
683 for (
auto& p : sigSharesByNodes) {
684 auto nodeId = p.first;
688 LogPrintf(
"CSigSharesManager::%s -- invalid sig shares from other node, banning peer=%d\n",
703 const std::vector<CSigShare>& sigShares,
712 auto quorumKey = std::make_pair((
Consensus::LLMQType)sigShare.llmqType, sigShare.quorumHash);
717 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::%s -- processed sigShare batch. shares=%d, time=%d, node=%d\n", __func__,
724 auto llmqType = quorum->params.type;
726 bool canTryRecovery =
false;
729 std::set<NodeId> quorumNodes;
747 if (!quorumNodes.empty()) {
750 for (
auto otherNodeId : quorumNodes) {
752 auto& session = nodeState.GetOrCreateSessionFromShare(sigShare);
753 session.quorum = quorum;
760 if (sigShareCount >= quorum->params.threshold) {
761 canTryRecovery =
true;
765 if (canTryRecovery) {
776 std::vector<CBLSSignature> sigSharesForRecovery;
777 std::vector<CBLSId> idsForRecovery;
781 auto k = std::make_pair(quorum->params.type,
id);
789 sigSharesForRecovery.reserve((
size_t)quorum->params.threshold);
790 idsForRecovery.reserve((
size_t)quorum->params.threshold);
791 for (
auto it =
sigShares->begin(); it !=
sigShares->end() && sigSharesForRecovery.size() < quorum->params.threshold; ++it) {
792 auto& sigShare = it->second;
793 sigSharesForRecovery.emplace_back(sigShare.sigShare.Get());
794 idsForRecovery.emplace_back(
CBLSId(quorum->members[sigShare.quorumMember]->proTxHash));
798 if (sigSharesForRecovery.size() < quorum->params.threshold) {
806 if (!recoveredSig.
Recover(sigSharesForRecovery, idsForRecovery)) {
807 LogPrintf(
"CSigSharesManager::%s -- failed to recover signature. id=%s, msgHash=%s, time=%d\n", __func__,
812 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::%s -- recovered signature. id=%s, msgHash=%s, time=%d\n", __func__,
828 bool valid = recoveredSig.
VerifyInsecure(quorum->qc.quorumPublicKey, signHash);
831 LogPrintf(
"CSigSharesManager::%s -- own recovered signature is invalid. id=%s, msgHash=%s\n", __func__,
842 assert(attempt < quorum->members.size());
844 std::vector<std::pair<uint256, CDeterministicMNCPtr>> v;
845 v.reserve(quorum->members.size());
846 for (
const auto& dmn : quorum->members) {
848 v.emplace_back(h, dmn);
850 std::sort(v.begin(), v.end());
852 return v[attempt].second;
861 const size_t maxRequestsForNode = 32;
864 std::vector<NodeId> shuffledNodeIds;
867 if (p.second.sessions.empty()) {
870 shuffledNodeIds.emplace_back(p.first);
872 Shuffle(shuffledNodeIds.begin(), shuffledNodeIds.end(),
rnd);
874 for (
auto& nodeId : shuffledNodeIds) {
877 if (nodeState.banned) {
881 nodeState.requestedSigShares.EraseIf([&](
const SigShareKey& k, int64_t t) {
884 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::CollectSigSharesToRequest -- timeout while waiting for %s-%d, node=%d\n",
885 k.first.ToString(), k.second, nodeId);
891 decltype(sigSharesToRequest.begin()->second)* invMap =
nullptr;
893 for (
auto& p2 : nodeState.sessions) {
894 auto& signHash = p2.first;
895 auto& session = p2.second;
901 for (
size_t i = 0; i < session.announced.inv.size(); i++) {
902 if (!session.announced.inv[i]) {
905 auto k = std::make_pair(signHash, (uint16_t)i);
908 session.announced.inv[i] =
false;
911 if (nodeState.requestedSigShares.Size() >= maxRequestsForNode) {
919 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::%s -- other node timeout while waiting for %s-%d, re-request from=%d, node=%d\n", __func__,
920 k.first.ToString(), k.second, nodeId, p->first);
928 nodeState.requestedSigShares.Add(k, now);
936 invMap = &sigSharesToRequest[nodeId];
938 auto& inv = (*invMap)[signHash];
939 if (inv.inv.empty()) {
941 inv.Init((
size_t)params.size);
943 inv.inv[k.second] =
true;
946 session.announced.inv[i] =
false;
958 auto nodeId = p.first;
959 auto& nodeState = p.second;
961 if (nodeState.banned) {
965 decltype(sigSharesToSend.begin()->second)* sigSharesToSend2 =
nullptr;
967 for (
auto& p2 : nodeState.sessions) {
968 auto& signHash = p2.first;
969 auto& session = p2.second;
977 for (
size_t i = 0; i < session.requested.inv.size(); i++) {
978 if (!session.requested.inv[i]) {
981 session.requested.inv[i] =
false;
983 auto k = std::make_pair(signHash, (uint16_t)i);
987 session.requested.inv[i] =
false;
994 if (!batchedSigShares.
sigShares.empty()) {
995 if (sigSharesToSend2 ==
nullptr) {
997 sigSharesToSend2 = &sigSharesToSend[nodeId];
999 (*sigSharesToSend2).emplace(signHash, std::move(batchedSigShares));
1009 std::unordered_map<uint256, CNode*> proTxToNode;
1010 for (
const auto& pnode : vNodes) {
1011 if (pnode->verifiedProRegTxHash.IsNull()) {
1014 proTxToNode.emplace(pnode->verifiedProRegTxHash, pnode);
1017 auto curTime = GetTime<std::chrono::milliseconds>().count();
1020 if (p.second.attempt >= p.second.quorum->params.recoveryMembers) {
1024 if (curTime >= p.second.nextAttemptTime) {
1027 p.second.nextAttemptTime = curTime + waitTime;
1031 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::%s -- signHash=%s, sending to %s, attempt=%d\n", __func__,
1032 p.second.sigShare.GetSignHash().ToString(), dmn->proTxHash.ToString(), p.second.attempt);
1034 auto it = proTxToNode.find(dmn->proTxHash);
1035 if (it == proTxToNode.end()) {
1039 auto& m = sigSharesToSend[it->second->GetId()];
1040 m.emplace_back(p.second.sigShare);
1050 std::unordered_map<std::pair<Consensus::LLMQType, uint256>, std::unordered_set<NodeId>,
StaticSaltedHasher> quorumNodesMap;
1053 auto& signHash = sigShareKey.first;
1054 auto quorumMember = sigShareKey.second;
1062 auto it = quorumNodesMap.find(quorumKey);
1063 if (it == quorumNodesMap.end()) {
1064 auto nodeIds =
g_connman->GetTierTwoConnMan()->getQuorumNodes(quorumKey.first, quorumKey.second);
1065 it = quorumNodesMap.emplace(std::piecewise_construct, std::forward_as_tuple(quorumKey), std::forward_as_tuple(nodeIds.begin(), nodeIds.end())).first;
1068 auto& quorumNodes = it->second;
1070 for (
auto& nodeId : quorumNodes) {
1073 if (nodeState.banned) {
1077 auto& session = nodeState.GetOrCreateSessionFromShare(*sigShare);
1079 if (session.knows.inv[quorumMember]) {
1085 if (inv.inv.empty()) {
1087 inv.Init((
size_t)params.size);
1089 inv.inv[quorumMember] =
true;
1090 session.knows.inv[quorumMember] =
true;
1100 std::unordered_map<NodeId, std::unordered_map<uint256, CSigSharesInv, StaticSaltedHasher>> sigSharesToRequest;
1101 std::unordered_map<NodeId, std::unordered_map<uint256, CBatchedSigShares, StaticSaltedHasher>> sigShareBatchesToSend;
1102 std::unordered_map<NodeId, std::vector<CSigShare>> sigSharesToSend;
1103 std::unordered_map<NodeId, std::unordered_map<uint256, CSigSharesInv, StaticSaltedHasher>>
sigSharesToAnnounce;
1104 std::unordered_map<NodeId, std::vector<CSigSesAnn>> sigSessionAnnouncements;
1106 auto addSigSesAnnIfNeeded = [&](
NodeId nodeId,
const uint256& signHash) {
1108 auto session = nodeState.GetSessionBySignHash(signHash);
1110 if (session->sendSessionId == (uint32_t)-1) {
1111 session->sendSessionId = nodeState.nextSendSessionId++;
1114 sigSesAnn.
sessionId = session->sendSessionId;
1115 sigSesAnn.
llmqType = (uint8_t)session->llmqType;
1117 sigSesAnn.
id = session->id;
1118 sigSesAnn.
msgHash = session->msgHash;
1120 sigSessionAnnouncements[nodeId].emplace_back(sigSesAnn);
1122 return session->sendSessionId;
1131 for (
auto& p : sigSharesToRequest) {
1132 for (
auto& p2 : p.second) {
1133 p2.second.sessionId = addSigSesAnnIfNeeded(p.first, p2.first);
1136 for (
auto& p : sigShareBatchesToSend) {
1137 for (
auto& p2 : p.second) {
1138 p2.second.sessionId = addSigSesAnnIfNeeded(p.first, p2.first);
1142 for (
auto& p2 : p.second) {
1143 p2.second.sessionId = addSigSesAnnIfNeeded(p.first, p2.first);
1148 bool didSend =
false;
1150 for (
auto& pnode : vNodesCopy) {
1153 auto it1 = sigSessionAnnouncements.find(pnode->GetId());
1154 if (it1 != sigSessionAnnouncements.end()) {
1155 std::vector<CSigSesAnn> msgs;
1156 msgs.reserve(it1->second.size());
1157 for (
auto& sigSesAnn : it1->second) {
1158 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::SendMessages -- QSIGSESANN signHash=%s, sessionId=%d, node=%d\n",
1160 msgs.emplace_back(sigSesAnn);
1167 if (!msgs.empty()) {
1173 auto it = sigSharesToRequest.find(pnode->GetId());
1174 if (it != sigSharesToRequest.end()) {
1175 std::vector<CSigSharesInv> msgs;
1176 for (
auto& p : it->second) {
1177 assert(p.second.CountSet() != 0);
1178 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::SendMessages -- QGETSIGSHARES signHash=%s, inv={%s}, node=%d\n",
1179 p.first.ToString(), p.second.ToString(), pnode->GetId());
1180 msgs.emplace_back(std::move(p.second));
1187 if (!msgs.empty()) {
1193 auto jt = sigShareBatchesToSend.find(pnode->GetId());
1194 if (jt != sigShareBatchesToSend.end()) {
1195 size_t totalSigsCount = 0;
1196 std::vector<CBatchedSigShares> msgs;
1197 for (
auto& p : jt->second) {
1198 assert(!p.second.sigShares.empty());
1199 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::SendMessages -- QBSIGSHARES signHash=%s, inv={%s}, node=%d\n",
1200 p.first.ToString(), p.second.ToInvString(), pnode->GetId());
1207 totalSigsCount += p.second.sigShares.size();
1208 msgs.emplace_back(std::move(p.second));
1210 if (!msgs.empty()) {
1218 std::vector<CSigSharesInv> msgs;
1219 for (
auto& p : kt->second) {
1220 assert(p.second.CountSet() != 0);
1221 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::SendMessages -- QSIGSHARESINV signHash=%s, inv={%s}, node=%d\n",
1222 p.first.ToString(), p.second.ToString(), pnode->GetId());
1223 msgs.emplace_back(std::move(p.second));
1230 if (!msgs.empty()) {
1236 auto lt = sigSharesToSend.find(pnode->GetId());
1237 if (lt != sigSharesToSend.end()) {
1238 std::vector<CSigShare> msgs;
1239 for (
auto& sigShare : lt->second) {
1240 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::SendMessages -- QSIGSHARE signHash=%s, node=%d\n",
1241 sigShare.GetSignHash().ToString(), pnode->GetId());
1242 msgs.emplace_back(std::move(sigShare));
1249 if (!msgs.empty()) {
1257 g_connman->ReleaseNodeVector(vNodesCopy);
1265 return nodeStates[nodeId].GetSessionInfoByRecvId(sessionId, retInfo);
1270 assert(idx < batchedSigShares.
sigShares.size());
1271 auto& s = batchedSigShares.
sigShares[idx];
1276 sigShare.
id = session.
id;
1304 for (
auto it = quorums.begin(); it != quorums.end(); ) {
1306 it->second =
quorumManager->GetQuorum(it->first.first, it->first.second);
1309 it = quorums.erase(it);
1316 std::unordered_set<uint256, StaticSaltedHasher> inactiveQuorumSessions;
1319 inactiveQuorumSessions.emplace(sigShare.GetSignHash());
1322 for (
auto& signHash : inactiveQuorumSessions) {
1331 std::unordered_set<uint256, StaticSaltedHasher> doneSessions;
1337 doneSessions.emplace(sigShare.GetSignHash());
1340 for (
auto& signHash : doneSessions) {
1345 std::unordered_set<uint256, StaticSaltedHasher> timeoutSessions;
1347 auto& signHash = p.first;
1348 int64_t lastSeenTime = p.second;
1351 timeoutSessions.emplace(signHash);
1354 for (
auto& signHash : timeoutSessions) {
1355 size_t count =
sigShares.CountForSignHash(signHash);
1358 auto m =
sigShares.GetAllForSignHash(signHash);
1361 auto& oneSigShare = m->begin()->second;
1363 std::string strMissingMembers;
1365 auto quorumIt = quorums.find(std::make_pair((
Consensus::LLMQType)oneSigShare.llmqType, oneSigShare.quorumHash));
1366 if (quorumIt != quorums.end()) {
1367 auto& quorum = quorumIt->second;
1368 for (
size_t i = 0; i < quorum->members.size(); i++) {
1369 if (!m->count((uint16_t)i)) {
1370 auto& dmn = quorum->members[i];
1371 strMissingMembers +=
strprintf(
"\n %s", dmn->proTxHash.ToString());
1377 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::%s -- signing session timed out. signHash=%s, id=%s, msgHash=%s, sigShareCount=%d, missingMembers=%s\n", __func__,
1378 signHash.
ToString(), oneSigShare.id.ToString(), oneSigShare.msgHash.ToString(), count, strMissingMembers);
1380 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::%s -- signing session timed out. signHash=%s, sigShareCount=%d\n", __func__,
1388 std::unordered_set<NodeId> nodeStatesToDelete;
1390 nodeStatesToDelete.emplace(p.first);
1393 nodeStatesToDelete.erase(pnode->
GetId());
1398 for (
auto nodeId : nodeStatesToDelete) {
1401 nodeState.requestedSigShares.ForEach([&](
const SigShareKey& k,
bool) {
1413 auto& ns = p.second;
1414 ns.RemoveSession(signHash);
1419 sigShares.EraseAllForSignHash(signHash);
1429 std::unordered_set<NodeId> toRemove;
1433 it->second.requestedSigShares.ForEach([&](
const SigShareKey& k, int64_t) {
1459 auto& nodeState = it->second;
1462 nodeState.requestedSigShares.ForEach([&](
const SigShareKey& k, int64_t) {
1465 nodeState.requestedSigShares.Clear();
1467 nodeState.banned =
true;
1472 int64_t lastSendTime = 0;
1474 bool didWork =
false;
1506 std::vector<std::tuple<const CQuorumCPtr, uint256, uint256>> v;
1513 Sign(std::get<0>(t), std::get<1>(t), std::get<2>(t));
1529 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::%s -- we don't have our skShare for quorum %s\n", __func__, quorum->qc.quorumHash.ToString());
1534 if (memberIdx == -1) {
1540 sigShare.
llmqType = quorum->params.type;
1549 LogPrintf(
"CSigSharesManager::%s -- failed to sign sigShare. signHahs=%s, id=%s, msgHash=%s, time=%s\n", __func__,
1556 LogPrint(
BCLog::LLMQ,
"CSigSharesManager::%s -- signed sigShare. signHash=%s, id=%s, msgHash=%s, llmqType=%d, quorum=%s, time=%s\n", __func__,
1562 session.sigShare = sigShare;
1563 session.quorum = quorum;
1564 session.nextAttemptTime = 0;
1565 session.attempt = 0;
1573 auto sigs =
sigShares.GetAllForSignHash(signHash);
1575 for (
auto& p : *sigs) {
1589 session->sendSessionId = (uint32_t)-1;
CActiveDeterministicMasternodeManager * activeMasternodeManager
const CChainParams & Params()
Return the currently selected parameters.
const uint256 GetProTx() const
std::set< SourceId > badSources
void PushMessage(const SourceId &sourceId, const MessageId &msgId, const uint256 &msgHash, const CBLSSignature &sig, const CBLSPublicKey &pubKey)
const BLSObject & Get() const
void Set(const BLSObject &_obj)
CBLSSignature Sign(const uint256 &hash) const
bool VerifyInsecure(const CBLSPublicKey &pubKey, const uint256 &hash) const
bool Recover(const std::vector< CBLSSignature > &sigs, const std::vector< CBLSId > &ids)
const Consensus::Params & GetConsensus() const
constexpr static const CFullyConnectedOnly FullyConnectedOnly
CSerializedNetMsg Make(int nFlags, std::string sCommand, Args &&... args)
Information about a peer.
bool sleep_for(std::chrono::milliseconds rel_time)
std::string ToString() const
This class works as a stopwatch.
void stop()
Stop/pause the timer.
duration_t::rep count() const
Return the elapsed time.
std::vector< std::pair< uint16_t, CBLSLazySignature > > sigShares
std::string ToInvString() const
std::string ToString() const
const SigShareKey & GetKey() const
CBLSLazySignature sigShare
const uint256 & GetSignHash() const
std::string ToString() const
void Set(uint16_t quorumMember, bool v)
void Merge(const CSigSharesInv &inv2)
bool IsSet(uint16_t quorumMember) const
void AsyncSign(const CQuorumCPtr &quorum, const uint256 &id, const uint256 &msgHash)
void CollectSigSharesToAnnounce(std::unordered_map< NodeId, std::unordered_map< uint256, CSigSharesInv, StaticSaltedHasher >> &sigSharesToAnnounce)
const size_t MAX_MSGS_TOTAL_BATCHED_SIGS
static const int64_t SESSION_NEW_SHARES_TIMEOUT
bool VerifySigSharesInv(NodeId from, Consensus::LLMQType llmqType, const CSigSharesInv &inv)
const size_t MAX_MSGS_CNT_QSIGSHARESINV
const size_t MAX_MSGS_SIG_SHARES
bool ProcessMessageGetSigShares(CNode *pfrom, const CSigSharesInv &inv, CConnman &connman)
bool GetSessionInfoByRecvId(NodeId nodeId, uint32_t sessionId, CSigSharesNodeState::SessionInfo &retInfo)
void ProcessMessageSigShare(NodeId fromId, const CSigShare &sigShare, CConnman &connman)
std::unordered_map< NodeId, CSigSharesNodeState > nodeStates
void RemoveSigSharesForSession(const uint256 &signHash)
void UnregisterAsRecoveredSigsListener()
void CollectPendingSigSharesToVerify(size_t maxUniqueSessions, std::unordered_map< NodeId, std::vector< CSigShare >> &retSigShares, std::unordered_map< std::pair< Consensus::LLMQType, uint256 >, CQuorumCPtr, StaticSaltedHasher > &retQuorums)
std::vector< std::tuple< const CQuorumCPtr, uint256, uint256 > > pendingSigns
void ProcessPendingSigSharesFromNode(NodeId nodeId, const std::vector< CSigShare > &sigShares, const std::unordered_map< std::pair< Consensus::LLMQType, uint256 >, CQuorumCPtr, StaticSaltedHasher > &quorums, CConnman &connman)
void ProcessMessage(CNode *pnode, const std::string &strCommand, CDataStream &vRecv, CConnman &connman)
void CollectSigSharesToSend(std::unordered_map< NodeId, std::unordered_map< uint256, CBatchedSigShares, StaticSaltedHasher >> &sigSharesToSend)
const size_t MAX_MSGS_CNT_QGETSIGSHARES
std::unordered_map< uint256, int64_t, StaticSaltedHasher > timeSeenForSessions
SigShareMap< CSigShare > sigShares
std::atomic< uint32_t > recoveredSigsCounter
SigShareMap< bool > sigSharesToAnnounce
std::unordered_map< uint256, CSignedSession, StaticSaltedHasher > signedSessions
CSigShare RebuildSigShare(const CSigSharesNodeState::SessionInfo &session, const CBatchedSigShares &batchedSigShares, size_t idx)
static const int64_t SIG_SHARE_REQUEST_TIMEOUT
bool ProcessMessageSigSharesInv(CNode *pfrom, const CSigSharesInv &inv, CConnman &connman)
void Sign(const CQuorumCPtr &quorum, const uint256 &id, const uint256 &msgHash)
void ProcessSigShare(NodeId nodeId, const CSigShare &sigShare, CConnman &connman, const CQuorumCPtr &quorum)
CThreadInterrupt interruptSigningShare
void BanNode(NodeId nodeId)
bool ProcessMessageBatchedSigShares(CNode *pfrom, const CBatchedSigShares &batchedSigShares, CConnman &connman)
bool ProcessPendingSigShares(CConnman &connman)
bool PreVerifyBatchedSigShares(NodeId nodeId, const CSigSharesNodeState::SessionInfo &session, const CBatchedSigShares &batchedSigShares, bool &retBan)
void TryRecoverSig(const CQuorumCPtr &quorum, const uint256 &id, const uint256 &msgHash, CConnman &connman)
const int64_t MAX_SEND_FOR_RECOVERY_TIMEOUT
void RemoveBannedNodeStates()
void CollectSigSharesToRequest(std::unordered_map< NodeId, std::unordered_map< uint256, CSigSharesInv, StaticSaltedHasher >> &sigSharesToRequest)
bool ProcessMessageSigSesAnn(CNode *pfrom, const CSigSesAnn &ann, CConnman &connman)
bool SignPendingSigShares()
void HandleNewRecoveredSig(const CRecoveredSig &recoveredSig)
const int64_t EXP_SEND_FOR_RECOVERY_TIMEOUT
static CDeterministicMNCPtr SelectMemberForRecovery(const CQuorumCPtr &quorum, const uint256 &id, int attempt)
const size_t MAX_MSGS_CNT_QSIGSESANN
void RegisterAsRecoveredSigsListener()
SigShareMap< std::pair< NodeId, int64_t > > sigSharesRequested
void ForceReAnnouncement(const CQuorumCPtr &quorum, Consensus::LLMQType llmqType, const uint256 &id, const uint256 &msgHash)
SigShareMap< CSigShare > pendingIncomingSigShares
Session * GetSessionBySignHash(const uint256 &signHash)
Session & GetOrCreateSessionFromShare(const CSigShare &sigShare)
std::unordered_map< uint32_t, Session * > sessionByRecvId
void RemoveSession(const uint256 &signHash)
Session & GetOrCreateSessionFromAnn(const CSigSesAnn &ann)
bool GetSessionInfoByRecvId(uint32_t sessionId, SessionInfo &retInfo)
std::unordered_map< uint256, Session, StaticSaltedHasher > sessions
SigShareMap< int64_t > requestedSigShares
Session * GetSessionByRecvId(uint32_t sessionId)
void Erase(const SigShareKey &k)
T * Get(const SigShareKey &k)
void EraseAllForSignHash(const uint256 &signHash)
T & GetOrAdd(const SigShareKey &k)
bool Add(const SigShareKey &k, const T &v)
std::shared_ptr< const CDeterministicMN > CDeterministicMNCPtr
uint256 SerializeHash(const T &obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
Compute the 256-bit hash of an object's serialization.
#define T(expected, seed, data)
std::unique_ptr< CConnman > g_connman
#define LogPrint(category,...)
const char * QGETSIGSHARES
const char * QSIGSHARESINV
uint256 BuildSignHash(Consensus::LLMQType llmqType, const uint256 &quorumHash, const uint256 &id, const uint256 &msgHash)
bool IsQuorumActive(Consensus::LLMQType llmqType, const uint256 &quorumHash)
std::shared_ptr< const CQuorum > CQuorumCPtr
std::unique_ptr< CQuorumManager > quorumManager
std::pair< uint256, uint16_t > SigShareKey
std::unique_ptr< CSigningManager > quorumSigningManager
std::unique_ptr< CSigSharesManager > quorumSigSharesManager
void Misbehaving(NodeId pnode, int howmuch, const std::string &message) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Increase a node's misbehavior score.
bool IsBanned(NodeId pnode)
RecursiveMutex cs_main
Global state.
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
std::map< LLMQType, LLMQParams > llmqs
Consensus::LLMQType llmqType
Consensus::LLMQType llmqType
#define AssertLockHeld(cs)
void TraceThread(const std::string name, Callable func)
int64_t GetAdjustedTime()
int64_t GetTimeMillis()
Returns the system time (not mockable)