mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
Try to avoid being marked as a bad quorum member when we sleep for too long in SleepBeforePhase (#3245)
* Do not sleep at the last block of the phase, it's not safe * Refactor it a bit to make it clearer what's going on here * Stop sleeping if blocks came faster than we expected
This commit is contained in:
parent
db6ea1de8e
commit
c42b200973
@ -115,6 +115,7 @@ void CDKGSessionHandler::UpdatedBlockTip(const CBlockIndex* pindexNew)
|
||||
int quorumStageInt = pindexNew->nHeight % params.dkgInterval;
|
||||
const CBlockIndex* pindexQuorum = pindexNew->GetAncestor(pindexNew->nHeight - quorumStageInt);
|
||||
|
||||
currentHeight = pindexNew->nHeight;
|
||||
quorumHeight = pindexQuorum->nHeight;
|
||||
quorumHash = pindexQuorum->GetBlockHash();
|
||||
|
||||
@ -236,22 +237,43 @@ void CDKGSessionHandler::SleepBeforePhase(QuorumPhase curPhase,
|
||||
return;
|
||||
}
|
||||
|
||||
// expected time for a full phase
|
||||
double phaseTime = params.dkgPhaseBlocks * Params().GetConsensus().nPowTargetSpacing * 1000;
|
||||
// expected time per member
|
||||
phaseTime = phaseTime / params.size;
|
||||
// Two blocks can come very close to each other, this happens pretty regularly. We don't want to be
|
||||
// left behind and marked as a bad member. This means that we should not count the last block of the
|
||||
// phase as a safe one to keep sleeping, that's why we calculate the phase sleep time as a time of
|
||||
// the full phase minus one block here.
|
||||
double phaseSleepTime = (params.dkgPhaseBlocks - 1) * Params().GetConsensus().nPowTargetSpacing * 1000;
|
||||
// Expected phase sleep time per member
|
||||
double phaseSleepTimePerMember = phaseSleepTime / params.size;
|
||||
// Don't expect perfect block times and thus reduce the phase time to be on the secure side (caller chooses factor)
|
||||
phaseTime *= randomSleepFactor;
|
||||
double adjustedPhaseSleepTimePerMember = phaseSleepTimePerMember * randomSleepFactor;
|
||||
|
||||
int64_t sleepTime = (int64_t)(phaseTime * curSession->GetMyMemberIndex());
|
||||
int64_t sleepTime = (int64_t)(adjustedPhaseSleepTimePerMember * curSession->GetMyMemberIndex());
|
||||
int64_t endTime = GetTimeMillis() + sleepTime;
|
||||
int heightTmp{-1};
|
||||
int heightStart{-1};
|
||||
{
|
||||
LOCK(cs);
|
||||
heightTmp = heightStart = currentHeight;
|
||||
}
|
||||
while (GetTimeMillis() < endTime) {
|
||||
if (stopRequested || ShutdownRequested()) {
|
||||
throw AbortPhaseException();
|
||||
}
|
||||
auto p = GetPhaseAndQuorumHash();
|
||||
if (p.first != curPhase || p.second != expectedQuorumHash) {
|
||||
throw AbortPhaseException();
|
||||
{
|
||||
LOCK(cs);
|
||||
if (currentHeight > heightTmp) {
|
||||
// New block(s) just came in
|
||||
int64_t expectedBlockTime = (currentHeight - heightStart) * Params().GetConsensus().nPowTargetSpacing * 1000;
|
||||
if (expectedBlockTime > sleepTime) {
|
||||
// Blocks came faster than we expected, jump into the phase func asap
|
||||
break;
|
||||
}
|
||||
heightTmp = currentHeight;
|
||||
}
|
||||
if (phase != curPhase || quorumHash != expectedQuorumHash) {
|
||||
// Smth went wrong and/or we missed quite a few blocks and it's just too late now
|
||||
throw AbortPhaseException();
|
||||
}
|
||||
}
|
||||
if (!runWhileWaiting()) {
|
||||
MilliSleep(100);
|
||||
|
@ -107,6 +107,7 @@ private:
|
||||
CDKGSessionManager& dkgManager;
|
||||
|
||||
QuorumPhase phase{QuorumPhase_Idle};
|
||||
int currentHeight{-1};
|
||||
int quorumHeight{-1};
|
||||
uint256 quorumHash;
|
||||
std::shared_ptr<CDKGSession> curSession;
|
||||
|
Loading…
Reference in New Issue
Block a user