diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 325c5aeae3..6f064512b2 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -1223,6 +1223,9 @@ void CDevNetParams::UpdateDevnetLLMQChainLocksFromArgs(const ArgsManager& args) Consensus::LLMQType llmqType = Consensus::LLMQType::LLMQ_NONE; for (const auto& params : consensus.llmqs) { if (params.name == strLLMQType) { + if (params.useRotation) { + throw std::runtime_error("LLMQ type specified for -llmqchainlocks must NOT use rotation"); + } llmqType = params.type; } } @@ -1242,6 +1245,9 @@ void CDevNetParams::UpdateDevnetLLMQInstantSendFromArgs(const ArgsManager& args) Consensus::LLMQType llmqType = Consensus::LLMQType::LLMQ_NONE; for (const auto& params : consensus.llmqs) { if (params.name == strLLMQType) { + if (params.useRotation) { + throw std::runtime_error("LLMQ type specified for -llmqinstantsend must NOT use rotation"); + } llmqType = params.type; } } @@ -1261,6 +1267,9 @@ void CDevNetParams::UpdateDevnetLLMQInstantSendDIP0024FromArgs(const ArgsManager Consensus::LLMQType llmqType = Consensus::LLMQType::LLMQ_NONE; for (const auto& params : consensus.llmqs) { if (params.name == strLLMQType) { + if (!params.useRotation) { + throw std::runtime_error("LLMQ type specified for -llmqinstantsenddip0024 must use rotation"); + } llmqType = params.type; } } diff --git a/src/llmq/blockprocessor.cpp b/src/llmq/blockprocessor.cpp index 2850aee9de..d1f8c690da 100644 --- a/src/llmq/blockprocessor.cpp +++ b/src/llmq/blockprocessor.cpp @@ -252,7 +252,9 @@ bool CQuorumBlockProcessor::ProcessCommitment(int nHeight, const uint256& blockH return true; } - if (llmq::CLLMQUtils::IsQuorumRotationEnabled(llmq_params.type, pQuorumBaseBlockIndex)) { + bool rotation_enabled = CLLMQUtils::IsQuorumRotationEnabled(llmq_params.type, pQuorumBaseBlockIndex); + + if (rotation_enabled) { LogPrint(BCLog::LLMQ, "[ProcessCommitment] height[%d] pQuorumBaseBlockIndex[%d] quorumIndex[%d] qversion[%d] Built\n", nHeight, pQuorumBaseBlockIndex->nHeight, qc.quorumIndex, qc.nVersion); } @@ -261,7 +263,7 @@ bool CQuorumBlockProcessor::ProcessCommitment(int nHeight, const uint256& blockH auto cacheKey = std::make_pair(llmq_params.type, quorumHash); evoDb.Write(std::make_pair(DB_MINED_COMMITMENT, cacheKey), std::make_pair(qc, blockHash)); - if (llmq::CLLMQUtils::IsQuorumRotationEnabled(llmq_params.type, pQuorumBaseBlockIndex)) { + if (rotation_enabled) { evoDb.Write(BuildInversedHeightKeyIndexed(llmq_params.type, nHeight, int(qc.quorumIndex)), pQuorumBaseBlockIndex->nHeight); } else { evoDb.Write(BuildInversedHeightKey(llmq_params.type, nHeight), pQuorumBaseBlockIndex->nHeight); @@ -415,23 +417,16 @@ bool CQuorumBlockProcessor::IsMiningPhase(const Consensus::LLMQParams& llmqParam // Note: This function can be called for new blocks assert(nHeight <= ::ChainActive().Height() + 1); - const auto pindex = ::ChainActive().Height() < nHeight ? ::ChainActive().Tip() : ::ChainActive().Tip()->GetAncestor(nHeight); - if (CLLMQUtils::IsQuorumRotationEnabled(llmqParams.type, pindex)) { - int quorumCycleStartHeight = nHeight - (nHeight % llmqParams.dkgInterval); - int quorumCycleMiningStartHeight = quorumCycleStartHeight + llmqParams.signingActiveQuorumCount + (5 * llmqParams.dkgPhaseBlocks) + 1; - int quorumCycleMiningEndHeight = quorumCycleMiningStartHeight + (llmqParams.dkgMiningWindowEnd - llmqParams.dkgMiningWindowStart); - LogPrint(BCLog::LLMQ, "[IsMiningPhase] nHeight[%d] quorumCycleStartHeight[%d] -- mining[%d-%d]\n", nHeight, quorumCycleStartHeight, quorumCycleMiningStartHeight, quorumCycleMiningEndHeight); + int quorumCycleStartHeight = nHeight - (nHeight % llmqParams.dkgInterval); + int quorumCycleMiningStartHeight = quorumCycleStartHeight + llmqParams.dkgMiningWindowStart; + int quorumCycleMiningEndHeight = quorumCycleStartHeight + llmqParams.dkgMiningWindowEnd; - if (nHeight >= quorumCycleMiningStartHeight && nHeight <= quorumCycleMiningEndHeight) { - return true; - } - } else { - int phaseIndex = nHeight % llmqParams.dkgInterval; - if (phaseIndex >= llmqParams.dkgMiningWindowStart && phaseIndex <= llmqParams.dkgMiningWindowEnd) { - return true; - } + if (nHeight >= quorumCycleMiningStartHeight && nHeight <= quorumCycleMiningEndHeight) { + LogPrint(BCLog::LLMQ, "[IsMiningPhase] nHeight[%d] llmqType[%d] quorumCycleStartHeight[%d] -- mining[%d-%d]\n", nHeight, int(llmqParams.type), quorumCycleStartHeight, quorumCycleMiningStartHeight, quorumCycleMiningEndHeight); + return true; } + LogPrint(BCLog::LLMQ, "[IsMiningPhase] nHeight[%d] llmqType[%d] quorumCycleStartHeight[%d] -- NOT mining[%d-%d]\n", nHeight, int(llmqParams.type), quorumCycleStartHeight, quorumCycleMiningStartHeight, quorumCycleMiningEndHeight); return false; } @@ -446,13 +441,13 @@ bool CQuorumBlockProcessor::IsCommitmentRequired(const Consensus::LLMQParams& ll assert(nHeight <= ::ChainActive().Height() + 1); const auto pindex = ::ChainActive().Height() < nHeight ? ::ChainActive().Tip() : ::ChainActive().Tip()->GetAncestor(nHeight); - for (int quorumIndex = 0; quorumIndex < llmqParams.signingActiveQuorumCount; ++quorumIndex) { + bool rotation_enabled = CLLMQUtils::IsQuorumRotationEnabled(llmqParams.type, pindex); + size_t quorums_num = rotation_enabled ? llmqParams.signingActiveQuorumCount : 1; + + for (int quorumIndex = 0; quorumIndex < quorums_num; ++quorumIndex) { uint256 quorumHash = GetQuorumBlockHash(llmqParams, nHeight, quorumIndex); if (quorumHash.IsNull()) return false; if (HasMinedCommitment(llmqParams.type, quorumHash)) return false; - if (!CLLMQUtils::IsQuorumRotationEnabled(llmqParams.type, pindex)) { - break; - } } return true; @@ -725,8 +720,11 @@ std::optional> CQuorumBlockProcessor::GetMineableC assert(nHeight <= ::ChainActive().Height() + 1); const auto pindex = ::ChainActive().Height() < nHeight ? ::ChainActive().Tip() : ::ChainActive().Tip()->GetAncestor(nHeight); + bool rotation_enabled = CLLMQUtils::IsQuorumRotationEnabled(llmqParams.type, pindex); + size_t quorums_num = rotation_enabled ? llmqParams.signingActiveQuorumCount : 1; + std::stringstream ss; - for (int quorumIndex = 0; quorumIndex < llmqParams.signingActiveQuorumCount; ++quorumIndex) { + for (int quorumIndex = 0; quorumIndex < quorums_num; ++quorumIndex) { CFinalCommitment cf; uint256 quorumHash = GetQuorumBlockHash(llmqParams, nHeight, quorumIndex); @@ -742,7 +740,7 @@ std::optional> CQuorumBlockProcessor::GetMineableC // null commitment required cf = CFinalCommitment(llmqParams, quorumHash); cf.quorumIndex = static_cast(quorumIndex); - if (CLLMQUtils::IsQuorumRotationEnabled(llmqParams.type, pindex)) { + if (rotation_enabled) { cf.nVersion = CFinalCommitment::INDEXED_QUORUM_VERSION; } ss << "{ created nversion[" << cf.nVersion << "] quorumIndex[" << cf.quorumIndex << "] }"; @@ -752,9 +750,6 @@ std::optional> CQuorumBlockProcessor::GetMineableC } ret.push_back(std::move(cf)); - if (!CLLMQUtils::IsQuorumRotationEnabled(llmqParams.type, pindex)) { - break; - } } LogPrint(BCLog::LLMQ, "GetMineableCommitments cf height[%d] content: %s\n", nHeight, ss.str()); diff --git a/src/llmq/dkgsessionhandler.cpp b/src/llmq/dkgsessionhandler.cpp index c1df8b41bf..d268e81d90 100644 --- a/src/llmq/dkgsessionhandler.cpp +++ b/src/llmq/dkgsessionhandler.cpp @@ -102,7 +102,7 @@ void CDKGSessionHandler::UpdatedBlockTip(const CBlockIndex* pindexNew) phase = static_cast(phaseInt); } - LogPrint(BCLog::LLMQ_DKG, "CDKGSessionHandler::%s -- %s - quorumIndex=%d, currentHeight=%d, pQuorumBaseBlockIndex->nHeight=%d, oldPhase=%d, newPhase=%d\n", __func__, + LogPrint(BCLog::LLMQ_DKG, "CDKGSessionHandler::%s -- %s qi[%d] currentHeight=%d, pQuorumBaseBlockIndex->nHeight=%d, oldPhase=%d, newPhase=%d\n", __func__, params.name, quorumIndex, currentHeight, pQuorumBaseBlockIndex->nHeight, int(oldPhase), int(phase)); } @@ -126,7 +126,7 @@ void CDKGSessionHandler::StartThread() throw std::runtime_error("Tried to start an already started CDKGSessionHandler thread."); } - std::string threadName = strprintf("llmq-%d", (uint8_t)params.type); + std::string threadName = strprintf("llmq-%d-%d", (uint8_t)params.type, quorumIndex); phaseHandlerThread = std::thread(&TraceThread >, threadName, std::function(std::bind(&CDKGSessionHandler::PhaseHandlerThread, this))); } @@ -148,10 +148,10 @@ bool CDKGSessionHandler::InitNewQuorum(const CBlockIndex* pQuorumBaseBlockIndex) auto mns = CLLMQUtils::GetAllQuorumMembers(params.type, pQuorumBaseBlockIndex); if (!curSession->Init(pQuorumBaseBlockIndex, mns, WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash), quorumIndex)) { - LogPrintf("CDKGSessionManager::%s -- height[%d] quorum initialization failed for %s mns[%d]\n", __func__, pQuorumBaseBlockIndex->nHeight, curSession->params.name, mns.size()); + LogPrintf("CDKGSessionManager::%s -- height[%d] quorum initialization failed for %s qi[%d] mns[%d]\n", __func__, pQuorumBaseBlockIndex->nHeight, curSession->params.name, quorumIndex, mns.size()); return false; } else { - LogPrintf("CDKGSessionManager::%s -- height[%d] quorum initialization OK for %s\n", __func__, pQuorumBaseBlockIndex->nHeight, curSession->params.name); + LogPrintf("CDKGSessionManager::%s -- height[%d] quorum initialization OK for %s qi[%d]\n", __func__, pQuorumBaseBlockIndex->nHeight, curSession->params.name, quorumIndex); } return true; @@ -171,23 +171,23 @@ void CDKGSessionHandler::WaitForNextPhase(std::optional curPhase, const uint256& expectedQuorumHash, const WhileWaitFunc& shouldNotWait) const { - LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - starting, curPhase=%d, nextPhase=%d\n", __func__, params.name, curPhase.has_value() ? int(*curPhase) : -1, int(nextPhase)); + LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - starting, curPhase=%d, nextPhase=%d\n", __func__, params.name, quorumIndex, curPhase.has_value() ? int(*curPhase) : -1, int(nextPhase)); while (true) { if (stopRequested) { - LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - aborting due to stop/shutdown requested\n", __func__, params.name); + LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - aborting due to stop/shutdown requested\n", __func__, params.name, quorumIndex); throw AbortPhaseException(); } auto [_phase, _quorumHash] = GetPhaseAndQuorumHash(); if (!expectedQuorumHash.IsNull() && _quorumHash != expectedQuorumHash) { - LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - aborting due unexpected expectedQuorumHash change\n", __func__, params.name); + LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - aborting due unexpected expectedQuorumHash change\n", __func__, params.name, quorumIndex); throw AbortPhaseException(); } if (_phase == nextPhase) { break; } if (curPhase.has_value() && _phase != curPhase) { - LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - aborting due unexpected phase change\n", __func__, params.name); + LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - aborting due unexpected phase change, _phase=%d, curPhase=%d\n", __func__, params.name, quorumIndex, int(_phase), curPhase.has_value() ? int(*curPhase) : -1); throw AbortPhaseException(); } if (!shouldNotWait()) { @@ -195,7 +195,7 @@ void CDKGSessionHandler::WaitForNextPhase(std::optional curPhase, } } - LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - done, curPhase=%d, nextPhase=%d\n", __func__, params.name, curPhase.has_value() ? int(*curPhase) : -1, int(nextPhase)); + LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - done, curPhase=%d, nextPhase=%d\n", __func__, params.name, quorumIndex, curPhase.has_value() ? int(*curPhase) : -1, int(nextPhase)); if (nextPhase == QuorumPhase::Initialized) { quorumDKGDebugManager->ResetLocalSessionStatus(params.type, quorumIndex); @@ -210,21 +210,21 @@ void CDKGSessionHandler::WaitForNextPhase(std::optional curPhase, void CDKGSessionHandler::WaitForNewQuorum(const uint256& oldQuorumHash) const { - LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - starting\n", __func__, params.name); + LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d]- starting\n", __func__, params.name, quorumIndex); while (true) { if (stopRequested) { - LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - aborting due to stop/shutdown requested\n", __func__, params.name); + LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - aborting due to stop/shutdown requested\n", __func__, params.name, quorumIndex); throw AbortPhaseException(); } - auto p = GetPhaseAndQuorumHash(); - if (p.second != oldQuorumHash) { + auto [_, _quorumHash] = GetPhaseAndQuorumHash(); + if (_quorumHash != oldQuorumHash) { break; } UninterruptibleSleep(std::chrono::milliseconds{100}); } - LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - done\n", __func__, params.name); + LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - done\n", __func__, params.name, quorumIndex); } // Sleep some time to not fully overload the whole network @@ -263,11 +263,11 @@ void CDKGSessionHandler::SleepBeforePhase(QuorumPhase curPhase, heightTmp = heightStart = currentHeight; } - LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - starting sleep for %d ms, curPhase=%d\n", __func__, params.name, sleepTime, int(curPhase)); + LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - starting sleep for %d ms, curPhase=%d\n", __func__, params.name, quorumIndex, sleepTime, int(curPhase)); while (GetTimeMillis() < endTime) { if (stopRequested) { - LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - aborting due to stop/shutdown requested\n", __func__, params.name); + LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - aborting due to stop/shutdown requested\n", __func__, params.name, quorumIndex); throw AbortPhaseException(); } { @@ -283,7 +283,7 @@ void CDKGSessionHandler::SleepBeforePhase(QuorumPhase curPhase, } if (phase != curPhase || quorumHash != expectedQuorumHash) { // Something went wrong and/or we missed quite a few blocks and it's just too late now - LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - aborting due unexpected phase/expectedQuorumHash change\n", __func__, params.name); + LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - aborting due unexpected phase/expectedQuorumHash change\n", __func__, params.name, quorumIndex); throw AbortPhaseException(); } } @@ -292,7 +292,7 @@ void CDKGSessionHandler::SleepBeforePhase(QuorumPhase curPhase, } } - LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - done, curPhase=%d\n", __func__, params.name, int(curPhase)); + LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - done, curPhase=%d\n", __func__, params.name, quorumIndex, int(curPhase)); } void CDKGSessionHandler::HandlePhase(QuorumPhase curPhase, @@ -302,13 +302,13 @@ void CDKGSessionHandler::HandlePhase(QuorumPhase curPhase, const StartPhaseFunc& startPhaseFunc, const WhileWaitFunc& runWhileWaiting) { - LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - starting, curPhase=%d, nextPhase=%d\n", __func__, params.name, int(curPhase), int(nextPhase)); + LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - starting, curPhase=%d, nextPhase=%d\n", __func__, params.name, quorumIndex, int(curPhase), int(nextPhase)); SleepBeforePhase(curPhase, expectedQuorumHash, randomSleepFactor, runWhileWaiting); startPhaseFunc(); WaitForNextPhase(curPhase, nextPhase, expectedQuorumHash, runWhileWaiting); - LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s - done, curPhase=%d, nextPhase=%d\n", __func__, params.name, int(curPhase), int(nextPhase)); + LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - done, curPhase=%d, nextPhase=%d\n", __func__, params.name, quorumIndex, int(curPhase), int(nextPhase)); } // returns a set of NodeIds which sent invalid messages @@ -543,14 +543,14 @@ void CDKGSessionHandler::PhaseHandlerThread() { while (!stopRequested) { try { - LogPrint(BCLog::LLMQ_DKG, "CDKGSessionHandler::%s -- %s - starting HandleDKGRound\n", __func__, params.name); + LogPrint(BCLog::LLMQ_DKG, "CDKGSessionHandler::%s -- %s qi[%d] - starting HandleDKGRound\n", __func__, params.name, quorumIndex); HandleDKGRound(); } catch (AbortPhaseException& e) { quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { status.aborted = true; return true; }); - LogPrint(BCLog::LLMQ_DKG, "CDKGSessionHandler::%s -- %s - aborted current DKG session\n", __func__, params.name); + LogPrint(BCLog::LLMQ_DKG, "CDKGSessionHandler::%s -- %s qi[%d] - aborted current DKG session\n", __func__, params.name, quorumIndex); } } } diff --git a/src/llmq/params.h b/src/llmq/params.h index a289ea24e4..1a2d902907 100644 --- a/src/llmq/params.h +++ b/src/llmq/params.h @@ -45,6 +45,9 @@ struct LLMQParams { // not consensus critical, only used in logging, RPC and UI std::string_view name; + // Whether this is a DIP0024 quorum or not + bool useRotation; + // the size of the quorum, e.g. 50 or 400 int size; @@ -113,6 +116,7 @@ static constexpr std::array available_llmqs = { LLMQParams{ .type = LLMQType::LLMQ_TEST, .name = "llmq_test", + .useRotation = false, .size = 3, .minSize = 2, .threshold = 2, @@ -137,6 +141,7 @@ static constexpr std::array available_llmqs = { LLMQParams{ .type = LLMQType::LLMQ_TEST_INSTANTSEND, .name = "llmq_test_instantsend", + .useRotation = false, .size = 3, .minSize = 2, .threshold = 2, @@ -161,6 +166,7 @@ static constexpr std::array available_llmqs = { LLMQParams{ .type = LLMQType::LLMQ_TEST_V17, .name = "llmq_test_v17", + .useRotation = false, .size = 3, .minSize = 2, .threshold = 2, @@ -185,14 +191,15 @@ static constexpr std::array available_llmqs = { LLMQParams{ .type = LLMQType::LLMQ_TEST_DIP0024, .name = "llmq_test_dip0024", + .useRotation = true, .size = 4, .minSize = 3, .threshold = 2, .dkgInterval = 24, // DKG cycle .dkgPhaseBlocks = 2, - .dkgMiningWindowStart = 10, // dkgPhaseBlocks * 5 = after finalization - .dkgMiningWindowEnd = 18, + .dkgMiningWindowStart = 12, // signingActiveQuorumCount + dkgPhaseBlocks * 5 = after finalization + .dkgMiningWindowEnd = 20, .dkgBadVotesThreshold = 2, .signingActiveQuorumCount = 2, // just a few ones to allow easier testing @@ -209,6 +216,7 @@ static constexpr std::array available_llmqs = { LLMQParams{ .type = LLMQType::LLMQ_DEVNET, .name = "llmq_devnet", + .useRotation = false, .size = 12, .minSize = 7, .threshold = 6, @@ -259,6 +267,7 @@ static constexpr std::array available_llmqs = { LLMQParams{ .type = LLMQType::LLMQ_50_60, .name = "llmq_50_60", + .useRotation = false, .size = 50, .minSize = 40, .threshold = 30, @@ -283,14 +292,15 @@ static constexpr std::array available_llmqs = { LLMQParams{ .type = LLMQType::LLMQ_60_75, .name = "llmq_60_75", + .useRotation = true, .size = 60, .minSize = 50, .threshold = 45, .dkgInterval = 24 * 12, // DKG cycle every 12 hours .dkgPhaseBlocks = 2, - .dkgMiningWindowStart = 10, // dkgPhaseBlocks * 5 = after finalization - .dkgMiningWindowEnd = 18, + .dkgMiningWindowStart = 42, // signingActiveQuorumCount + dkgPhaseBlocks * 5 = after finalization + .dkgMiningWindowEnd = 50, .dkgBadVotesThreshold = 48, .signingActiveQuorumCount = 32, @@ -307,6 +317,7 @@ static constexpr std::array available_llmqs = { LLMQParams{ .type = LLMQType::LLMQ_400_60, .name = "llmq_400_60", + .useRotation = false, .size = 400, .minSize = 300, .threshold = 240, @@ -333,6 +344,7 @@ static constexpr std::array available_llmqs = { LLMQParams{ .type = LLMQType::LLMQ_400_85, .name = "llmq_400_85", + .useRotation = false, .size = 400, .minSize = 350, .threshold = 340, @@ -359,6 +371,7 @@ static constexpr std::array available_llmqs = { LLMQParams{ .type = LLMQType::LLMQ_100_67, .name = "llmq_100_67", + .useRotation = false, .size = 100, .minSize = 80, .threshold = 67, diff --git a/src/llmq/utils.cpp b/src/llmq/utils.cpp index cd7b5c6e0b..6f40b551d8 100644 --- a/src/llmq/utils.cpp +++ b/src/llmq/utils.cpp @@ -534,7 +534,7 @@ bool CLLMQUtils::IsQuorumRotationEnabled(Consensus::LLMQType llmqType, const CBl { assert(pindex); - if (llmqType != Params().GetConsensus().llmqTypeDIP0024InstantSend) { + if (!GetLLMQParams(llmqType).useRotation) { return false; } @@ -646,13 +646,19 @@ std::set CLLMQUtils::GetQuorumRelayMembers(const Consensus::LLMQParams& int k = 0; while ((gap_max >>= 1) || k <= 1) { size_t idx = (i + gap) % mns.size(); + // It doesn't matter if this node is going to be added to the resulting set or not, + // we should always bump the gap and the k (step count) regardless. + // Refusing to bump the gap results in an incomplete set in the best case scenario + // (idx won't ever change again once we hit `==`). Not bumping k guarantees an endless + // loop when the first or the second node we check is the one that should be skipped + // (k <= 1 forever). + gap <<= 1; + k++; const auto& otherDmn = mns[idx]; if (otherDmn->proTxHash == proTxHash) { continue; } r.emplace(otherDmn->proTxHash); - gap <<= 1; - k++; } return r; }; diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 7781b9f0b9..d53c0138b4 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -3312,7 +3312,6 @@ bool static ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStrea LogPrintf("Not relaying invalid transaction %s from whitelisted peer=%d (%s)\n", tx.GetHash().ToString(), pfrom->GetId(), FormatStateMessage(state)); } } - llmq::quorumInstantSendManager->TransactionRemovedFromMempool(ptx); } // If a tx has been detected by recentRejects, we will have reached @@ -3345,6 +3344,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStrea if (nDoS > 0) { Misbehaving(pfrom->GetId(), nDoS); } + llmq::quorumInstantSendManager->TransactionRemovedFromMempool(ptx); } return true; } diff --git a/src/rpc/rpcquorums.cpp b/src/rpc/rpcquorums.cpp index 53fa8c9fc9..0421ba313a 100644 --- a/src/rpc/rpcquorums.cpp +++ b/src/rpc/rpcquorums.cpp @@ -198,8 +198,10 @@ static UniValue quorum_dkgstatus(const JSONRPCRequest& request) UniValue quorumArrConnections(UniValue::VARR); for (const auto& type : llmq::CLLMQUtils::GetEnabledQuorumTypes(pindexTip)) { const auto& llmq_params = llmq::GetLLMQParams(type); + bool rotation_enabled = llmq::CLLMQUtils::IsQuorumRotationEnabled(type, pindexTip); + size_t quorums_num = rotation_enabled ? llmq_params.signingActiveQuorumCount : 1; - for (int quorumIndex = 0; quorumIndex < llmq_params.signingActiveQuorumCount; ++quorumIndex) { + for (int quorumIndex = 0; quorumIndex < quorums_num; ++quorumIndex) { UniValue obj(UniValue::VOBJ); obj.pushKV("llmqType", std::string(llmq_params.name)); obj.pushKV("quorumIndex", quorumIndex); @@ -241,9 +243,6 @@ static UniValue quorum_dkgstatus(const JSONRPCRequest& request) } } quorumArrConnections.push_back(obj); - if (!llmq::CLLMQUtils::IsQuorumRotationEnabled(type, pindexTip)) { - break; - } } LOCK(cs_main);