Skip to content

Commit

Permalink
Don't run into session timeout when sig shares come in slow
Browse files Browse the repository at this point in the history
Instead of just tracking when the first share was received, we now also
track when the last (non-duplicate) share was received. Sessios will now
timeout 5 minutes after the first share arrives, or 1 minute after the last
one arrived.
  • Loading branch information
codablock committed Feb 26, 2019
1 parent 6f92588 commit 971a2cc
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 7 deletions.
20 changes: 15 additions & 5 deletions src/llmq/quorums_signing_shares.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,16 @@ void CSigSharesManager::ProcessSigShare(NodeId nodeId, const CSigShare& sigShare
}

sigSharesToAnnounce.Add(sigShare.GetKey(), true);
firstSeenForSessions.emplace(sigShare.GetSignHash(), GetTimeMillis());

auto it = timeSeenForSessions.find(sigShare.GetSignHash());
if (it == timeSeenForSessions.end()) {
auto t = GetTimeMillis();
// insert first-seen and last-seen time
timeSeenForSessions.emplace(sigShare.GetSignHash(), std::make_pair(t, t));
} else {
// update last-seen time
it->second.second = GetTimeMillis();
}

if (!quorumNodes.empty()) {
// don't announce and wait for other nodes to request this share and directly send it to them
Expand Down Expand Up @@ -968,11 +977,12 @@ void CSigSharesManager::Cleanup()

// Remove sessions which timed out
std::unordered_set<uint256> timeoutSessions;
for (auto& p : firstSeenForSessions) {
for (auto& p : timeSeenForSessions) {
auto& signHash = p.first;
int64_t time = p.second;
int64_t firstSeenTime = p.second.first;
int64_t lastSeenTime = p.second.second;

if (now - time >= SIGNING_SESSION_TIMEOUT) {
if (now - firstSeenTime >= SESSION_TOTAL_TIMEOUT || now - lastSeenTime >= SESSION_NEW_SHARES_TIMEOUT) {
timeoutSessions.emplace(signHash);
}
}
Expand Down Expand Up @@ -1054,7 +1064,7 @@ void CSigSharesManager::RemoveSigSharesForSession(const uint256& signHash)
sigSharesRequested.EraseAllForSignHash(signHash);
sigSharesToAnnounce.EraseAllForSignHash(signHash);
sigShares.EraseAllForSignHash(signHash);
firstSeenForSessions.erase(signHash);
timeSeenForSessions.erase(signHash);
}

void CSigSharesManager::RemoveBannedNodeStates()
Expand Down
7 changes: 5 additions & 2 deletions src/llmq/quorums_signing_shares.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,8 @@ class CSigSharesNodeState

class CSigSharesManager : public CRecoveredSigsListener
{
static const int64_t SIGNING_SESSION_TIMEOUT = 60 * 1000;
static const int64_t SESSION_NEW_SHARES_TIMEOUT = 60 * 1000;
static const int64_t SESSION_TOTAL_TIMEOUT = 5 * 60 * 1000;
static const int64_t SIG_SHARE_REQUEST_TIMEOUT = 5 * 1000;

private:
Expand All @@ -344,7 +345,9 @@ class CSigSharesManager : public CRecoveredSigsListener
CThreadInterrupt workInterrupt;

SigShareMap<CSigShare> sigShares;
std::unordered_map<uint256, int64_t> firstSeenForSessions;

// stores time of first and last receivedSigShare. Used to detect timeouts
std::unordered_map<uint256, std::pair<int64_t, int64_t>> timeSeenForSessions;

std::unordered_map<NodeId, CSigSharesNodeState> nodeStates;
SigShareMap<std::pair<NodeId, int64_t>> sigSharesRequested;
Expand Down

0 comments on commit 971a2cc

Please sign in to comment.