fix: add a bias to IsExpired to avoid potential timing issues where nodeA thinks it's been 300 seconds but nodeB only thinks it's been 295 for some reason (#5276)

## Issue being fixed or feature implemented
add a bias to IsExpired to avoid potential timing issues where nodeA thinks it's been 300 seconds but nodeB only thinks it's been 295 for some reason

## What was done?


## How Has This Been Tested?


## Breaking Changes


## Checklist:
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have added or updated relevant unit/integration/functional/e2e
tests
- [ ] I have made corresponding changes to the documentation

**For repository code-owners and collaborators only**
- [x] I have assigned this pull request to a milestone
This commit is contained in:
PastaPastaPasta 2023-03-30 10:24:44 -05:00 committed by GitHub
parent 2d89442d89
commit 1a96a98481
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 6 additions and 5 deletions

View File

@ -283,7 +283,7 @@ void CQuorumManager::UpdatedBlockTip(const CBlockIndex* pindexNew, bool fInitial
LOCK(cs_data_requests);
auto it = mapQuorumDataRequests.begin();
while (it != mapQuorumDataRequests.end()) {
if (it->second.IsExpired()) {
if (it->second.IsExpired(/*add_bias=*/true)) {
it = mapQuorumDataRequests.erase(it);
} else {
++it;
@ -474,7 +474,7 @@ bool CQuorumManager::RequestQuorumData(CNode* pfrom, Consensus::LLMQType llmqTyp
key.quorumHash = pQuorumBaseBlockIndex->GetBlockHash();
key.llmqType = llmqType;
auto it = mapQuorumDataRequests.emplace(key, CQuorumDataRequest(llmqType, pQuorumBaseBlockIndex->GetBlockHash(), nDataMask, proTxHash));
if (!it.second && !it.first->second.IsExpired()) {
if (!it.second && !it.first->second.IsExpired(/*add_bias=*/true)) {
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- Already requested\n", __func__);
return false;
}
@ -664,7 +664,7 @@ void CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, C
auto it = mapQuorumDataRequests.find(key);
if (it == mapQuorumDataRequests.end()) {
it = mapQuorumDataRequests.emplace(key, request).first;
} else if (it->second.IsExpired()) {
} else if (it->second.IsExpired(/*add_bias=*/false)) {
it->second = request;
} else {
request_limit_exceeded = true;
@ -919,7 +919,7 @@ void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, co
key.quorumHash = pQuorum->qc->quorumHash;
key.llmqType = pQuorum->qc->llmqType;
auto it = mapQuorumDataRequests.find(key);
if (it != mapQuorumDataRequests.end() && !it->second.IsExpired()) {
if (it != mapQuorumDataRequests.end() && !it->second.IsExpired(/*add_bias=*/true)) {
printLog("Already asked");
continue;
}

View File

@ -83,6 +83,7 @@ private:
bool fProcessed{false};
static constexpr int64_t EXPIRATION_TIMEOUT{300};
static constexpr int64_t EXPIRATION_BIAS{60};
public:
@ -119,7 +120,7 @@ public:
Errors GetError() const { return nError; }
std::string GetErrorString() const;
bool IsExpired() const { return (GetTime() - nTime) >= EXPIRATION_TIMEOUT; }
bool IsExpired(bool add_bias) const { return (GetTime() - nTime) >= (EXPIRATION_TIMEOUT + (add_bias ? EXPIRATION_BIAS : 0)); }
bool IsProcessed() const { return fProcessed; }
void SetProcessed() { fProcessed = true; }