@@ -115,6 +115,7 @@ void CDKGSessionHandler::UpdatedBlockTip(const CBlockIndex* pindexNew)
115115 int quorumStageInt = pindexNew->nHeight % params.dkgInterval ;
116116 const CBlockIndex* pindexQuorum = pindexNew->GetAncestor (pindexNew->nHeight - quorumStageInt);
117117
118+ currentHeight = pindexNew->nHeight ;
118119 quorumHeight = pindexQuorum->nHeight ;
119120 quorumHash = pindexQuorum->GetBlockHash ();
120121
@@ -236,22 +237,43 @@ void CDKGSessionHandler::SleepBeforePhase(QuorumPhase curPhase,
236237 return ;
237238 }
238239
239- // expected time for a full phase
240- double phaseTime = params.dkgPhaseBlocks * Params ().GetConsensus ().nPowTargetSpacing * 1000 ;
241- // expected time per member
242- phaseTime = phaseTime / params.size ;
240+ // Two blocks can come very close to each other, this happens pretty regularly. We don't want to be
241+ // left behind and marked as a bad member. This means that we should not count the last block of the
242+ // phase as a safe one to keep sleeping, that's why we calculate the phase sleep time as a time of
243+ // the full phase minus one block here.
244+ double phaseSleepTime = (params.dkgPhaseBlocks - 1 ) * Params ().GetConsensus ().nPowTargetSpacing * 1000 ;
245+ // Expected phase sleep time per member
246+ double phaseSleepTimePerMember = phaseSleepTime / params.size ;
243247 // Don't expect perfect block times and thus reduce the phase time to be on the secure side (caller chooses factor)
244- phaseTime *= randomSleepFactor;
248+ double adjustedPhaseSleepTimePerMember = phaseSleepTimePerMember * randomSleepFactor;
245249
246- int64_t sleepTime = (int64_t )(phaseTime * curSession->GetMyMemberIndex ());
250+ int64_t sleepTime = (int64_t )(adjustedPhaseSleepTimePerMember * curSession->GetMyMemberIndex ());
247251 int64_t endTime = GetTimeMillis () + sleepTime;
252+ int heightTmp{-1 };
253+ int heightStart{-1 };
254+ {
255+ LOCK (cs);
256+ heightTmp = heightStart = currentHeight;
257+ }
248258 while (GetTimeMillis () < endTime) {
249259 if (stopRequested || ShutdownRequested ()) {
250260 throw AbortPhaseException ();
251261 }
252- auto p = GetPhaseAndQuorumHash ();
253- if (p.first != curPhase || p.second != expectedQuorumHash) {
254- throw AbortPhaseException ();
262+ {
263+ LOCK (cs);
264+ if (currentHeight > heightTmp) {
265+ // New block(s) just came in
266+ int64_t expectedBlockTime = (currentHeight - heightStart) * Params ().GetConsensus ().nPowTargetSpacing * 1000 ;
267+ if (expectedBlockTime > sleepTime) {
268+ // Blocks came faster than we expected, jump into the phase func asap
269+ break ;
270+ }
271+ heightTmp = currentHeight;
272+ }
273+ if (phase != curPhase || quorumHash != expectedQuorumHash) {
274+ // Smth went wrong and/or we missed quite a few blocks and it's just too late now
275+ throw AbortPhaseException ();
276+ }
255277 }
256278 if (!runWhileWaiting ()) {
257279 MilliSleep (100 );
0 commit comments