2222
2323#include < cxxtimer.hpp>
2424
25+ #include < algorithm>
2526#include < ranges>
2627
2728namespace llmq
2829{
30+ namespace {
31+ constexpr size_t MAX_SESSIONS_PER_PEER_FACTOR {4 };
32+ constexpr size_t MIN_SESSIONS_PER_PEER {100 };
33+
34+ size_t GetMaxSessionsForPeer (const Consensus::LLMQParams& params)
35+ {
36+ return std::max<size_t >(size_t (params.size ) * MAX_SESSIONS_PER_PEER_FACTOR , MIN_SESSIONS_PER_PEER );
37+ }
38+ } // namespace
39+
2940void CSigShare::UpdateKey ()
3041{
3142 key.first = this ->buildSignHash ().Get ();
@@ -133,6 +144,16 @@ CSigSharesNodeState::Session& CSigSharesNodeState::GetOrCreateSessionFromAnn(con
133144 return s;
134145}
135146
147+ bool CSigSharesNodeState::CanCreateSessionFromAnn (const llmq::CSigSesAnn& ann, size_t maxSessions) const
148+ {
149+ return sessions.count (ann.buildSignHash ().Get ()) != 0 || sessions.size () < maxSessions;
150+ }
151+
152+ size_t CSigSharesNodeState::GetSessionCount () const
153+ {
154+ return sessions.size ();
155+ }
156+
136157CSigSharesNodeState::Session* CSigSharesNodeState::GetSessionBySignHash (const uint256& signHash)
137158{
138159 auto it = sessions.find (signHash);
@@ -206,7 +227,8 @@ void CSigSharesManager::UnregisterRecoveryInterface()
206227bool CSigSharesManager::ProcessMessageSigSesAnn (const CNode& pfrom, const CSigSesAnn& ann)
207228{
208229 auto llmqType = ann.getLlmqType ();
209- if (!Params ().GetLLMQ (llmqType).has_value ()) {
230+ const auto & llmq_params_opt = Params ().GetLLMQ (llmqType);
231+ if (!llmq_params_opt.has_value ()) {
210232 return false ;
211233 }
212234 if (ann.getSessionId () == UNINITIALIZED_SESSION_ID || ann.getQuorumHash ().IsNull () || ann.getId ().IsNull () || ann.getMsgHash ().IsNull ()) {
@@ -225,7 +247,14 @@ bool CSigSharesManager::ProcessMessageSigSesAnn(const CNode& pfrom, const CSigSe
225247
226248 LOCK (cs);
227249 auto & nodeState = nodeStates[pfrom.GetId ()];
250+ const size_t maxSessions = GetMaxSessionsForPeer (*llmq_params_opt);
251+ if (!nodeState.CanCreateSessionFromAnn (ann, maxSessions)) {
252+ LogPrint (BCLog::LLMQ_SIGS , " CSigSharesManager::%s -- too many sessions. cnt=%d, max=%d, node=%d\n " ,
253+ __func__, nodeState.GetSessionCount (), maxSessions, pfrom.GetId ());
254+ return false ;
255+ }
228256 auto & session = nodeState.GetOrCreateSessionFromAnn (ann);
257+ timeSeenForSessions.try_emplace (ann.buildSignHash ().Get (), GetTime<std::chrono::seconds>().count ());
229258 nodeState.sessionByRecvId .erase (session.recvSessionId );
230259 nodeState.sessionByRecvId .erase (ann.getSessionId ());
231260 session.recvSessionId = ann.getSessionId ();
@@ -1247,6 +1276,11 @@ void CSigSharesManager::Cleanup()
12471276 doneSessions.emplace (sigShare.GetSignHash ());
12481277 }
12491278 });
1279+ for (const auto & [signHash, _] : timeSeenForSessions) {
1280+ if (doneSessions.count (signHash) == 0 && sigman.HasRecoveredSigForSession (signHash)) {
1281+ doneSessions.emplace (signHash);
1282+ }
1283+ }
12501284 for (const auto & signHash : doneSessions) {
12511285 RemoveSigSharesForSession (signHash);
12521286 }
0 commit comments