diff --git a/src/avalanche/peermanager.cpp b/src/avalanche/peermanager.cpp --- a/src/avalanche/peermanager.cpp +++ b/src/avalanche/peermanager.cpp @@ -849,14 +849,16 @@ compact(); // Don't select proofs that have not been known for long enough, i.e. at - // least since the last block time and and twice the dangling proof cleanup - // timeout, so we're sure to not account for proofs more recent than the + // least since twice the dangling proof cleanup timeout before the last + // block time, so we're sure to not account for proofs more recent than the // previous block or lacking node connected. - int64_t maxRegistrationTime = - std::min(pprev->GetBlockTime(), - GetTime() - std::chrono::duration_cast<std::chrono::seconds>( - 2 * Peer::DANGLING_TIMEOUT) - .count()); + // The previous block time is capped to now for the unlikely event the + // previous block time is in the future. + const int64_t maxRegistrationTime = + std::min(pprev->GetBlockTime(), GetTime()) - + std::chrono::duration_cast<std::chrono::seconds>(2 * + Peer::DANGLING_TIMEOUT) + .count(); std::vector<Slot> stakingRewardsSlots; stakingRewardsSlots.reserve(peers.size()); diff --git a/src/avalanche/test/peermanager_tests.cpp b/src/avalanche/test/peermanager_tests.cpp --- a/src/avalanche/test/peermanager_tests.cpp +++ b/src/avalanche/test/peermanager_tests.cpp @@ -2299,8 +2299,8 @@ return lhs->getId() < rhs->getId(); }); - // Make sure the proofs have been registered before the prev block was found - // and before 2x the peer replacement cooldown. + // Make sure the proofs have been registered at least 2x the dangling proof + // timeout before the previous block time. now += 30min + 1s; SetMockTime(now); prevBlock.nTime = now.count(); @@ -2408,9 +2408,23 @@ BOOST_CHECK(!pm.selectPayoutScriptPubKey(&prevBlock, winner, acceptableWinners)); - // 3. Now the proof has it all - now += 30min + 1s; + // 3. The proof has been registered 30min from the previous block time, + // but the previous block time is in the future. + now += 20min + 1s; SetMockTime(now); + prevBlock.nTime = (now + 10min).count(); + BOOST_CHECK(!pm.selectPayoutScriptPubKey(&prevBlock, winner, + acceptableWinners)); + + // 4. The proof has been registered 30min from now, but only 20min from + // the previous block time. + now += 10min; + SetMockTime(now); + prevBlock.nTime = (now - 10min).count(); + BOOST_CHECK(!pm.selectPayoutScriptPubKey(&prevBlock, winner, + acceptableWinners)); + + // 5. Now the proof has it all prevBlock.nTime = now.count(); checkWinner(0, payoutScript); }