From 5958f8b81db0a72d58ed98d3f6223e5c165b2b44 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Thu, 10 Jan 2019 07:07:58 +0100 Subject: [PATCH] Remove dkgRndSleepTime from consensus params and make sleeping it non-random --- src/chainparams.cpp | 4 --- src/consensus/params.h | 4 --- src/llmq/quorums_dkgsession.h | 2 ++ src/llmq/quorums_dkgsessionhandler.cpp | 36 ++++++++++++++++++-------- src/llmq/quorums_dkgsessionhandler.h | 2 +- 5 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 278a73f13..a0392f5d7 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -118,7 +118,6 @@ static Consensus::LLMQParams llmq10_60 = { .dkgPhaseBlocks = 2, .dkgMiningWindowStart = 10, // dkgPhaseBlocks * 5 = after finalization .dkgMiningWindowEnd = 18, - .dkgRndSleepTime = 0, .dkgBadVotesThreshold = 8, .neighborConnections = 2, @@ -137,7 +136,6 @@ static Consensus::LLMQParams llmq50_60 = { .dkgPhaseBlocks = 2, .dkgMiningWindowStart = 10, // dkgPhaseBlocks * 5 = after finalization .dkgMiningWindowEnd = 18, - .dkgRndSleepTime = 1 * 60 * 1000, .dkgBadVotesThreshold = 40, .neighborConnections = 2, @@ -156,7 +154,6 @@ static Consensus::LLMQParams llmq400_60 = { .dkgPhaseBlocks = 4, .dkgMiningWindowStart = 20, // dkgPhaseBlocks * 5 = after finalization .dkgMiningWindowEnd = 28, - .dkgRndSleepTime = 2 * 60 * 1000, .dkgBadVotesThreshold = 300, .neighborConnections = 4, @@ -176,7 +173,6 @@ static Consensus::LLMQParams llmq400_85 = { .dkgPhaseBlocks = 4, .dkgMiningWindowStart = 20, // dkgPhaseBlocks * 5 = after finalization .dkgMiningWindowEnd = 48, // give it a larger mining window to make sure it is mined - .dkgRndSleepTime = 2 * 60 * 1000, .dkgBadVotesThreshold = 300, .neighborConnections = 4, diff --git a/src/consensus/params.h b/src/consensus/params.h index c59e01783..b6ca12fe3 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -98,10 +98,6 @@ struct LLMQParams { // session failed. int dkgMiningWindowEnd; - // Each member will sleep for a random time between 0 and dkgRndSleepTime milliseconds. The purpose of this is to - // avoid overloading the network due to all members sending out expensive-to-verify DKG messages at once - int dkgRndSleepTime; - // In the complaint phase, members will vote on other members being bad (missing valid contribution). If at least // dkgBadVotesThreshold have voted for another member to be bad, it will considered to be bad by all other members // as well. This serves as a protection against late-comers who send their contribution on the bring of diff --git a/src/llmq/quorums_dkgsession.h b/src/llmq/quorums_dkgsession.h index 7620bcf06..186517a08 100644 --- a/src/llmq/quorums_dkgsession.h +++ b/src/llmq/quorums_dkgsession.h @@ -293,6 +293,8 @@ public: bool Init(int _height, const uint256& _quorumHash, const std::vector& mns, const uint256& _myProTxHash); + size_t GetMyMemberIndex() const { return myIdx; } + /** * The following sets of methods are for the first 4 phases handled in the session. The flow of message calls * is identical for all phases: diff --git a/src/llmq/quorums_dkgsessionhandler.cpp b/src/llmq/quorums_dkgsessionhandler.cpp index 7fe3d6e34..0a7f632ba 100644 --- a/src/llmq/quorums_dkgsessionhandler.cpp +++ b/src/llmq/quorums_dkgsessionhandler.cpp @@ -236,13 +236,27 @@ void CDKGSessionHandler::WaitForNewQuorum(const uint256& oldQuorumHash) } } -void CDKGSessionHandler::RandomSleep(QuorumPhase curPhase, - uint256& expectedQuorumHash, - double randomSleepFactor, - const WhileWaitFunc& runWhileWaiting) +// Sleep some time to not fully overload the whole network +void CDKGSessionHandler::SleepBeforePhase(QuorumPhase curPhase, + uint256& expectedQuorumHash, + double randomSleepFactor, + const WhileWaitFunc& runWhileWaiting) { - // Randomly sleep some time to not fully overload the whole network - int64_t endTime = GetTimeMillis() + GetRandInt((int)(params.dkgRndSleepTime * randomSleepFactor)); + // expected time for a full phase + double phaseTime = params.dkgPhaseBlocks * Params().GetConsensus().nPowTargetSpacing * 1000; + // expected time per member + phaseTime = phaseTime / 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; + + if (Params().MineBlocksOnDemand()) { + // on regtest, blocks can be mined on demand without any significant time passing between these. We shouldn't + // wait before phases in this case + phaseTime = 0; + } + + int64_t sleepTime = (int64_t)(phaseTime * curSession->GetMyMemberIndex()); + int64_t endTime = GetTimeMillis() + sleepTime; while (GetTimeMillis() < endTime) { if (stopRequested || ShutdownRequested()) { throw AbortPhaseException(); @@ -264,7 +278,7 @@ void CDKGSessionHandler::HandlePhase(QuorumPhase curPhase, const StartPhaseFunc& startPhaseFunc, const WhileWaitFunc& runWhileWaiting) { - RandomSleep(curPhase, expectedQuorumHash, randomSleepFactor, runWhileWaiting); + SleepBeforePhase(curPhase, expectedQuorumHash, randomSleepFactor, runWhileWaiting); startPhaseFunc(); WaitForNextPhase(curPhase, nextPhase, expectedQuorumHash, runWhileWaiting); } @@ -501,7 +515,7 @@ void CDKGSessionHandler::HandleDKGRound() auto fContributeWait = [this] { return ProcessPendingMessageBatch(*curSession, pendingContributions, 8); }; - HandlePhase(QuorumPhase_Contribute, QuorumPhase_Complain, curQuorumHash, 1, fContributeStart, fContributeWait); + HandlePhase(QuorumPhase_Contribute, QuorumPhase_Complain, curQuorumHash, 0.5, fContributeStart, fContributeWait); // Complain auto fComplainStart = [this]() { @@ -510,7 +524,7 @@ void CDKGSessionHandler::HandleDKGRound() auto fComplainWait = [this] { return ProcessPendingMessageBatch(*curSession, pendingComplaints, 8); }; - HandlePhase(QuorumPhase_Complain, QuorumPhase_Justify, curQuorumHash, 0, fComplainStart, fComplainWait); + HandlePhase(QuorumPhase_Complain, QuorumPhase_Justify, curQuorumHash, 0.1, fComplainStart, fComplainWait); // Justify auto fJustifyStart = [this]() { @@ -519,7 +533,7 @@ void CDKGSessionHandler::HandleDKGRound() auto fJustifyWait = [this] { return ProcessPendingMessageBatch(*curSession, pendingJustifications, 8); }; - HandlePhase(QuorumPhase_Justify, QuorumPhase_Commit, curQuorumHash, 0, fJustifyStart, fJustifyWait); + HandlePhase(QuorumPhase_Justify, QuorumPhase_Commit, curQuorumHash, 0.1, fJustifyStart, fJustifyWait); // Commit auto fCommitStart = [this]() { @@ -528,7 +542,7 @@ void CDKGSessionHandler::HandleDKGRound() auto fCommitWait = [this] { return ProcessPendingMessageBatch(*curSession, pendingPrematureCommitments, 8); }; - HandlePhase(QuorumPhase_Commit, QuorumPhase_Finalize, curQuorumHash, 1, fCommitStart, fCommitWait); + HandlePhase(QuorumPhase_Commit, QuorumPhase_Finalize, curQuorumHash, 0.5, fCommitStart, fCommitWait); auto finalCommitments = curSession->FinalizeCommitments(); for (auto& fqc : finalCommitments) { diff --git a/src/llmq/quorums_dkgsessionhandler.h b/src/llmq/quorums_dkgsessionhandler.h index 1d5c6fc9e..66343c2cc 100644 --- a/src/llmq/quorums_dkgsessionhandler.h +++ b/src/llmq/quorums_dkgsessionhandler.h @@ -127,7 +127,7 @@ private: typedef std::function WhileWaitFunc; void WaitForNextPhase(QuorumPhase curPhase, QuorumPhase nextPhase, uint256& expectedQuorumHash, const WhileWaitFunc& runWhileWaiting); void WaitForNewQuorum(const uint256& oldQuorumHash); - void RandomSleep(QuorumPhase curPhase, uint256& expectedQuorumHash, double randomSleepFactor, const WhileWaitFunc& runWhileWaiting); + void SleepBeforePhase(QuorumPhase curPhase, uint256& expectedQuorumHash, double randomSleepFactor, const WhileWaitFunc& runWhileWaiting); void HandlePhase(QuorumPhase curPhase, QuorumPhase nextPhase, uint256& expectedQuorumHash, double randomSleepFactor, const StartPhaseFunc& startPhaseFunc, const WhileWaitFunc& runWhileWaiting); void HandleDKGRound(); void PhaseHandlerThread();