From cd4bd73d794a5abf38b89b2be040d25fdec7c6d9 Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Wed, 31 Jan 2024 16:12:54 +0200 Subject: [PATCH 1/8] dkginfo rpc --- src/rpc/quorums.cpp | 45 ++++++++++++++++++++++++ test/functional/feature_llmq_rotation.py | 5 +++ 2 files changed, 50 insertions(+) diff --git a/src/rpc/quorums.cpp b/src/rpc/quorums.cpp index 37059788f1fbf..19cde263445be 100644 --- a/src/rpc/quorums.cpp +++ b/src/rpc/quorums.cpp @@ -1036,6 +1036,50 @@ static UniValue submitchainlock(const JSONRPCRequest& request) return true; } +static void dkginfo_help(const JSONRPCRequest& request) +{ + RPCHelpMan{"dkginfo", + "Return information regarding DKGs.\n" + "Enabled only for Masternode and works only when SPORK_17_QUORUM_DKG_ENABLED spork is ON.\n", + { + {}, + }, + RPCResults{}, + RPCExamples{""}, + }.Check(request); +} + +static UniValue dkginfo(const JSONRPCRequest& request) +{ + dkginfo_help(request); + + if (!fMasternodeMode) { + throw JSONRPCError(RPC_INVALID_REQUEST, "RPC allowed only for Masternodes"); + } + + const NodeContext& node = EnsureAnyNodeContext(request.context); + const ChainstateManager& chainman = EnsureChainman(node); + const LLMQContext& llmq_ctx = EnsureLLMQContext(node); + + llmq::CDKGDebugStatus status; + llmq_ctx.dkg_debugman->GetLocalDebugStatus(status); + UniValue ret(UniValue::VOBJ); + ret.pushKV("nActiveDKGs", (int)status.sessions.size()); + + if (status.sessions.empty()) { + int nTipHeight = WITH_LOCK(cs_main, return chainman.ActiveChain().Height()); + const Consensus::Params &consensus_params = Params().GetConsensus(); + int minDkgWindow = std::numeric_limits::max(); + for (const auto ¶ms: consensus_params.llmqs) { + if (!params.useRotation) + minDkgWindow = std::min(minDkgWindow, params.dkgInterval - (nTipHeight % params.dkgInterval)); + } + ret.pushKV("nextDKG", minDkgWindow); + } + + return ret; +} + void RegisterQuorumsRPCCommands(CRPCTable &tableRPC) { @@ -1047,6 +1091,7 @@ static const CRPCCommand commands[] = { "evo", "submitchainlock", &submitchainlock, {"blockHash", "signature", "blockHeight"} }, { "evo", "verifychainlock", &verifychainlock, {"blockHash", "signature", "blockHeight"} }, { "evo", "verifyislock", &verifyislock, {"id", "txid", "signature", "maxHeight"} }, + { "evo", "dkginfo", &dkginfo, {} }, }; // clang-format on for (const auto& command : commands) { diff --git a/test/functional/feature_llmq_rotation.py b/test/functional/feature_llmq_rotation.py index 117f36666b596..75ecc92ef43d4 100755 --- a/test/functional/feature_llmq_rotation.py +++ b/test/functional/feature_llmq_rotation.py @@ -76,6 +76,11 @@ def run_test(self): b_h_0 = self.nodes[0].getbestblockhash() + tip = self.nodes[0].getblockcount() + assert_equal(self.nodes[1].dkginfo()['nextDKG'], int(24 - (tip % 24))) + assert_equal(self.nodes[2].dkginfo()['nextDKG'], int(24 - (tip % 24))) + assert_equal(self.nodes[3].dkginfo()['nextDKG'], int(24 - (tip % 24))) + #Mine 2 quorums so that Chainlocks can be available: Need them to include CL in CbTx as soon as v20 activates self.log.info("Mining 2 quorums") h_0 = self.mine_quorum() From 9bfe2a3ee6b98c1df18f7af99efaa3d39ae98162 Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Wed, 31 Jan 2024 16:30:38 +0200 Subject: [PATCH 2/8] Added rotation logic --- src/rpc/quorums.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/rpc/quorums.cpp b/src/rpc/quorums.cpp index 19cde263445be..ff6116c248821 100644 --- a/src/rpc/quorums.cpp +++ b/src/rpc/quorums.cpp @@ -1073,6 +1073,16 @@ static UniValue dkginfo(const JSONRPCRequest& request) for (const auto ¶ms: consensus_params.llmqs) { if (!params.useRotation) minDkgWindow = std::min(minDkgWindow, params.dkgInterval - (nTipHeight % params.dkgInterval)); + else { + if (nTipHeight % params.dkgInterval > params.signingActiveQuorumCount) { + // Next potential DKG is the DKG for quorumIndex 0 + minDkgWindow = std::min(minDkgWindow, params.dkgInterval - (nTipHeight % params.dkgInterval)); + } + // We are currently during a rotation cycle. Since sessions.empty(), next we return next potential DKG is 1 (next block for next quorumIndex) + else { + minDkgWindow = std::min(minDkgWindow, 1); + } + } } ret.pushKV("nextDKG", minDkgWindow); } From 8386a3d6be75270c31b9df607c4e35000c3216f1 Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Wed, 31 Jan 2024 16:34:43 +0200 Subject: [PATCH 3/8] Create release-notes-5853.md --- doc/release-notes-5853.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 doc/release-notes-5853.md diff --git a/doc/release-notes-5853.md b/doc/release-notes-5853.md new file mode 100644 index 0000000000000..2533cb4d524dc --- /dev/null +++ b/doc/release-notes-5853.md @@ -0,0 +1,8 @@ +Added RPC +-------- + +- `dkginfo` RPC returns information about DKGs: +`nActiveDKGs`: Total number of active DKG sessions. +`nextDKG`: If `nActiveDKGs` is 0, then `nextDKG` indicates the number of blocks until the next potential DKG session. + +Note: This RPC is enabled only for Masternodes, and it is expected to work only when `SPORK_17_QUORUM_DKG_ENABLED` spork is ON. \ No newline at end of file From 7a05283f55380c11a1e2bd7ae8cb3b681922a71b Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Wed, 31 Jan 2024 18:07:49 +0200 Subject: [PATCH 4/8] suggestions --- src/rpc/quorums.cpp | 110 ++++++++++++----------- test/functional/feature_llmq_rotation.py | 6 +- 2 files changed, 59 insertions(+), 57 deletions(-) diff --git a/src/rpc/quorums.cpp b/src/rpc/quorums.cpp index ff6116c248821..6eba386a74dd3 100644 --- a/src/rpc/quorums.cpp +++ b/src/rpc/quorums.cpp @@ -789,6 +789,59 @@ static UniValue quorum_rotationinfo(const JSONRPCRequest& request, const LLMQCon return quorumRotationInfoRet.ToJson(); } +static void quorum_dkginfo_help(const JSONRPCRequest& request) +{ + RPCHelpMan{"quorum dkginfo", + "Return information regarding DKGs.\n" + "Enabled only for Masternode and works only when SPORK_17_QUORUM_DKG_ENABLED spork is ON.\n", + { + {}, + }, + RPCResults{}, + RPCExamples{""}, + }.Check(request); +} + +static UniValue quorum_dkginfo(const JSONRPCRequest& request, const LLMQContext& llmq_ctx, const ChainstateManager& chainman) +{ + quorum_dkginfo_help(request); + + if (!fMasternodeMode) { + throw JSONRPCError(RPC_INVALID_REQUEST, "RPC allowed only for Masternodes"); + } + + llmq::CDKGDebugStatus status; + llmq_ctx.dkg_debugman->GetLocalDebugStatus(status); + UniValue ret(UniValue::VOBJ); + ret.pushKV("nActiveDKGs", int(status.sessions.size())); + + if (status.sessions.empty()) { + int nTipHeight = WITH_LOCK(cs_main, return chainman.ActiveChain().Height()); + const Consensus::Params &consensus_params = Params().GetConsensus(); + + auto minNextDKG = [&consensus_params, nTipHeight]() { + int minDkgWindow = std::numeric_limits::max(); + for (const auto ¶ms: consensus_params.llmqs) { + if (!params.useRotation) + minDkgWindow = std::min(minDkgWindow, params.dkgInterval - (nTipHeight % params.dkgInterval)); + else { + if (nTipHeight % params.dkgInterval > params.signingActiveQuorumCount) { + // Next potential DKG is the DKG for quorumIndex 0 + minDkgWindow = std::min(minDkgWindow, params.dkgInterval - (nTipHeight % params.dkgInterval)); + } + // We are currently during a rotation cycle. Since sessions.empty(), next we return next potential DKG is 1 (next block for next quorumIndex) + else { + minDkgWindow = std::min(minDkgWindow, 1); + } + } + } + return minDkgWindow; + }; + ret.pushKV("nextDKG", minNextDKG()); + } + + return ret; +} [[ noreturn ]] static void quorum_help() { @@ -801,6 +854,7 @@ static UniValue quorum_rotationinfo(const JSONRPCRequest& request, const LLMQCon " list - List of on-chain quorums\n" " listextended - Extended list of on-chain quorums\n" " info - Return information about a quorum\n" + " dkginfo - Return information about DKGs\n" " dkgsimerror - Simulates DKG errors and malicious behavior\n" " dkgstatus - Return the status of the current DKG process\n" " memberof - Checks which quorums the given masternode is a member of\n" @@ -836,6 +890,8 @@ static UniValue _quorum(const JSONRPCRequest& request) return quorum_list_extended(new_request, chainman, llmq_ctx); } else if (command == "quoruminfo") { return quorum_info(new_request, llmq_ctx); + } else if (command == "quorumdkginfo") { + return quorum_dkginfo(new_request, llmq_ctx, chainman); } else if (command == "quorumdkgstatus") { return quorum_dkgstatus(new_request, chainman, llmq_ctx); } else if (command == "quorummemberof") { @@ -1036,59 +1092,6 @@ static UniValue submitchainlock(const JSONRPCRequest& request) return true; } -static void dkginfo_help(const JSONRPCRequest& request) -{ - RPCHelpMan{"dkginfo", - "Return information regarding DKGs.\n" - "Enabled only for Masternode and works only when SPORK_17_QUORUM_DKG_ENABLED spork is ON.\n", - { - {}, - }, - RPCResults{}, - RPCExamples{""}, - }.Check(request); -} - -static UniValue dkginfo(const JSONRPCRequest& request) -{ - dkginfo_help(request); - - if (!fMasternodeMode) { - throw JSONRPCError(RPC_INVALID_REQUEST, "RPC allowed only for Masternodes"); - } - - const NodeContext& node = EnsureAnyNodeContext(request.context); - const ChainstateManager& chainman = EnsureChainman(node); - const LLMQContext& llmq_ctx = EnsureLLMQContext(node); - - llmq::CDKGDebugStatus status; - llmq_ctx.dkg_debugman->GetLocalDebugStatus(status); - UniValue ret(UniValue::VOBJ); - ret.pushKV("nActiveDKGs", (int)status.sessions.size()); - - if (status.sessions.empty()) { - int nTipHeight = WITH_LOCK(cs_main, return chainman.ActiveChain().Height()); - const Consensus::Params &consensus_params = Params().GetConsensus(); - int minDkgWindow = std::numeric_limits::max(); - for (const auto ¶ms: consensus_params.llmqs) { - if (!params.useRotation) - minDkgWindow = std::min(minDkgWindow, params.dkgInterval - (nTipHeight % params.dkgInterval)); - else { - if (nTipHeight % params.dkgInterval > params.signingActiveQuorumCount) { - // Next potential DKG is the DKG for quorumIndex 0 - minDkgWindow = std::min(minDkgWindow, params.dkgInterval - (nTipHeight % params.dkgInterval)); - } - // We are currently during a rotation cycle. Since sessions.empty(), next we return next potential DKG is 1 (next block for next quorumIndex) - else { - minDkgWindow = std::min(minDkgWindow, 1); - } - } - } - ret.pushKV("nextDKG", minDkgWindow); - } - - return ret; -} void RegisterQuorumsRPCCommands(CRPCTable &tableRPC) @@ -1101,7 +1104,6 @@ static const CRPCCommand commands[] = { "evo", "submitchainlock", &submitchainlock, {"blockHash", "signature", "blockHeight"} }, { "evo", "verifychainlock", &verifychainlock, {"blockHash", "signature", "blockHeight"} }, { "evo", "verifyislock", &verifyislock, {"id", "txid", "signature", "maxHeight"} }, - { "evo", "dkginfo", &dkginfo, {} }, }; // clang-format on for (const auto& command : commands) { diff --git a/test/functional/feature_llmq_rotation.py b/test/functional/feature_llmq_rotation.py index 75ecc92ef43d4..3652058ae2a21 100755 --- a/test/functional/feature_llmq_rotation.py +++ b/test/functional/feature_llmq_rotation.py @@ -77,9 +77,9 @@ def run_test(self): b_h_0 = self.nodes[0].getbestblockhash() tip = self.nodes[0].getblockcount() - assert_equal(self.nodes[1].dkginfo()['nextDKG'], int(24 - (tip % 24))) - assert_equal(self.nodes[2].dkginfo()['nextDKG'], int(24 - (tip % 24))) - assert_equal(self.nodes[3].dkginfo()['nextDKG'], int(24 - (tip % 24))) + assert_equal(self.nodes[1].quorum("dkginfo")['nextDKG'], int(24 - (tip % 24))) + assert_equal(self.nodes[2].quorum("dkginfo")['nextDKG'], int(24 - (tip % 24))) + assert_equal(self.nodes[3].quorum("dkginfo")['nextDKG'], int(24 - (tip % 24))) #Mine 2 quorums so that Chainlocks can be available: Need them to include CL in CbTx as soon as v20 activates self.log.info("Mining 2 quorums") From 7f21872bd80baa10d3622ac933198427b133cdac Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Thu, 1 Feb 2024 00:32:55 +0200 Subject: [PATCH 5/8] refactoring of lambda + always return nextDKG --- src/rpc/quorums.cpp | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/src/rpc/quorums.cpp b/src/rpc/quorums.cpp index 6eba386a74dd3..439e934f6670b 100644 --- a/src/rpc/quorums.cpp +++ b/src/rpc/quorums.cpp @@ -814,31 +814,19 @@ static UniValue quorum_dkginfo(const JSONRPCRequest& request, const LLMQContext& llmq_ctx.dkg_debugman->GetLocalDebugStatus(status); UniValue ret(UniValue::VOBJ); ret.pushKV("nActiveDKGs", int(status.sessions.size())); - - if (status.sessions.empty()) { - int nTipHeight = WITH_LOCK(cs_main, return chainman.ActiveChain().Height()); - const Consensus::Params &consensus_params = Params().GetConsensus(); - - auto minNextDKG = [&consensus_params, nTipHeight]() { - int minDkgWindow = std::numeric_limits::max(); - for (const auto ¶ms: consensus_params.llmqs) { - if (!params.useRotation) - minDkgWindow = std::min(minDkgWindow, params.dkgInterval - (nTipHeight % params.dkgInterval)); - else { - if (nTipHeight % params.dkgInterval > params.signingActiveQuorumCount) { - // Next potential DKG is the DKG for quorumIndex 0 - minDkgWindow = std::min(minDkgWindow, params.dkgInterval - (nTipHeight % params.dkgInterval)); - } - // We are currently during a rotation cycle. Since sessions.empty(), next we return next potential DKG is 1 (next block for next quorumIndex) - else { - minDkgWindow = std::min(minDkgWindow, 1); - } - } + + const int nTipHeight{WITH_LOCK(cs_main, return chainman.ActiveChain().Height())}; + auto minNextDKG = [](const Consensus::Params& consensusParams, int nTipHeight) { + int minDkgWindow{std::numeric_limits::max()}; + for (const auto& params: consensusParams.llmqs) { + if (params.useRotation && (nTipHeight % params.dkgInterval <= params.signingActiveQuorumCount)) { + return 1; } - return minDkgWindow; - }; - ret.pushKV("nextDKG", minNextDKG()); - } + minDkgWindow = std::min(minDkgWindow, params.dkgInterval - (nTipHeight % params.dkgInterval)); + } + return minDkgWindow; + }; + ret.pushKV("nextDKG", minNextDKG(Params().GetConsensus(), nTipHeight)); return ret; } From 9b3f283c6323344fe66caf985b7847c0e175dea2 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Thu, 1 Feb 2024 03:56:30 +0300 Subject: [PATCH 6/8] suggestions --- doc/release-notes-5853.md | 8 +++--- src/rpc/quorums.cpp | 31 ++++++++++++------------ test/functional/feature_llmq_rotation.py | 20 ++++++++++++--- 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/doc/release-notes-5853.md b/doc/release-notes-5853.md index 2533cb4d524dc..f2a52635a5a1d 100644 --- a/doc/release-notes-5853.md +++ b/doc/release-notes-5853.md @@ -1,8 +1,6 @@ Added RPC -------- -- `dkginfo` RPC returns information about DKGs: -`nActiveDKGs`: Total number of active DKG sessions. -`nextDKG`: If `nActiveDKGs` is 0, then `nextDKG` indicates the number of blocks until the next potential DKG session. - -Note: This RPC is enabled only for Masternodes, and it is expected to work only when `SPORK_17_QUORUM_DKG_ENABLED` spork is ON. \ No newline at end of file +- `quorum dkginfo` RPC returns information about DKGs: + - `active_dkgs`: Total number of active DKG sessions this node is participating in right now. + - `next_dkg`: The number of blocks until the next potential DKG session. diff --git a/src/rpc/quorums.cpp b/src/rpc/quorums.cpp index 439e934f6670b..29afab0373245 100644 --- a/src/rpc/quorums.cpp +++ b/src/rpc/quorums.cpp @@ -791,14 +791,20 @@ static UniValue quorum_rotationinfo(const JSONRPCRequest& request, const LLMQCon static void quorum_dkginfo_help(const JSONRPCRequest& request) { - RPCHelpMan{"quorum dkginfo", - "Return information regarding DKGs.\n" - "Enabled only for Masternode and works only when SPORK_17_QUORUM_DKG_ENABLED spork is ON.\n", - { - {}, - }, - RPCResults{}, - RPCExamples{""}, + RPCHelpMan{ + "quorum dkginfo", + "Return information regarding DKGs.\n" + { + {}, + }, + RPCResult{ + RPCResult::Type::OBJ, "", "", + { + {RPCResult::Type::NUM, "active_dkgs", "Total number of active DKG sessions this node is participating in right now"}, + {RPCResult::Type::NUM, "next_dkg", "The number of blocks until the next potential DKG session"}, + } + }, + RPCExamples{""}, }.Check(request); } @@ -806,14 +812,10 @@ static UniValue quorum_dkginfo(const JSONRPCRequest& request, const LLMQContext& { quorum_dkginfo_help(request); - if (!fMasternodeMode) { - throw JSONRPCError(RPC_INVALID_REQUEST, "RPC allowed only for Masternodes"); - } - llmq::CDKGDebugStatus status; llmq_ctx.dkg_debugman->GetLocalDebugStatus(status); UniValue ret(UniValue::VOBJ); - ret.pushKV("nActiveDKGs", int(status.sessions.size())); + ret.pushKV("active_dkgs", int(status.sessions.size())); const int nTipHeight{WITH_LOCK(cs_main, return chainman.ActiveChain().Height())}; auto minNextDKG = [](const Consensus::Params& consensusParams, int nTipHeight) { @@ -826,7 +828,7 @@ static UniValue quorum_dkginfo(const JSONRPCRequest& request, const LLMQContext& } return minDkgWindow; }; - ret.pushKV("nextDKG", minNextDKG(Params().GetConsensus(), nTipHeight)); + ret.pushKV("next_dkg", minNextDKG(Params().GetConsensus(), nTipHeight)); return ret; } @@ -1081,7 +1083,6 @@ static UniValue submitchainlock(const JSONRPCRequest& request) } - void RegisterQuorumsRPCCommands(CRPCTable &tableRPC) { // clang-format off diff --git a/test/functional/feature_llmq_rotation.py b/test/functional/feature_llmq_rotation.py index 3652058ae2a21..df494595229e7 100755 --- a/test/functional/feature_llmq_rotation.py +++ b/test/functional/feature_llmq_rotation.py @@ -77,9 +77,11 @@ def run_test(self): b_h_0 = self.nodes[0].getbestblockhash() tip = self.nodes[0].getblockcount() - assert_equal(self.nodes[1].quorum("dkginfo")['nextDKG'], int(24 - (tip % 24))) - assert_equal(self.nodes[2].quorum("dkginfo")['nextDKG'], int(24 - (tip % 24))) - assert_equal(self.nodes[3].quorum("dkginfo")['nextDKG'], int(24 - (tip % 24))) + next_dkg = 24 - (tip % 24); + for node in self.nodes: + dkg_info = node.quorum("dkginfo") + assert_equal(dkg_info['active_dkgs'], 0) + assert_equal(dkg_info['next_dkg'], next_dkg) #Mine 2 quorums so that Chainlocks can be available: Need them to include CL in CbTx as soon as v20 activates self.log.info("Mining 2 quorums") @@ -98,6 +100,18 @@ def run_test(self): b_h_1 = self.nodes[0].getbestblockhash() + tip = self.nodes[0].getblockcount() + next_dkg = 24 - (tip % 24); + assert next_dkg < 24 + nonzero_dkgs = 0 + for i in range(len(self.nodes)): + dkg_info = self.nodes[i].quorum("dkginfo") + if i == 0: + assert_equal(dkg_info['active_dkgs'], 0) + nonzero_dkgs += dkg_info['active_dkgs'] + assert_equal(dkg_info['next_dkg'], next_dkg) + assert_equal(nonzero_dkgs, 11) # 2 quorums 4 nodes each and 1 quorum of 3 nodes + expectedDeleted = [] expectedNew = [h_100_0, h_106_0, h_104_0, h_100_1, h_106_1, h_104_1] quorumList = self.test_getmnlistdiff_quorums(b_h_0, b_h_1, {}, expectedDeleted, expectedNew, testQuorumsCLSigs=False) From 17401ff7009c78e6f99a6f61b4bb95350f36157e Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Thu, 1 Feb 2024 11:19:15 +0200 Subject: [PATCH 7/8] fix --- src/rpc/quorums.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/quorums.cpp b/src/rpc/quorums.cpp index 29afab0373245..6e2487fe9a9ed 100644 --- a/src/rpc/quorums.cpp +++ b/src/rpc/quorums.cpp @@ -793,7 +793,7 @@ static void quorum_dkginfo_help(const JSONRPCRequest& request) { RPCHelpMan{ "quorum dkginfo", - "Return information regarding DKGs.\n" + "Return information regarding DKGs.\n", { {}, }, From fe43467b36f9df35404883400e232c9f23ef11e1 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Thu, 1 Feb 2024 14:49:20 +0300 Subject: [PATCH 8/8] fix linter --- src/rpc/quorums.cpp | 2 +- test/functional/feature_llmq_rotation.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rpc/quorums.cpp b/src/rpc/quorums.cpp index 6e2487fe9a9ed..82ca73c9e26d3 100644 --- a/src/rpc/quorums.cpp +++ b/src/rpc/quorums.cpp @@ -816,7 +816,7 @@ static UniValue quorum_dkginfo(const JSONRPCRequest& request, const LLMQContext& llmq_ctx.dkg_debugman->GetLocalDebugStatus(status); UniValue ret(UniValue::VOBJ); ret.pushKV("active_dkgs", int(status.sessions.size())); - + const int nTipHeight{WITH_LOCK(cs_main, return chainman.ActiveChain().Height())}; auto minNextDKG = [](const Consensus::Params& consensusParams, int nTipHeight) { int minDkgWindow{std::numeric_limits::max()}; diff --git a/test/functional/feature_llmq_rotation.py b/test/functional/feature_llmq_rotation.py index df494595229e7..568358a4ca6dd 100755 --- a/test/functional/feature_llmq_rotation.py +++ b/test/functional/feature_llmq_rotation.py @@ -77,7 +77,7 @@ def run_test(self): b_h_0 = self.nodes[0].getbestblockhash() tip = self.nodes[0].getblockcount() - next_dkg = 24 - (tip % 24); + next_dkg = 24 - (tip % 24) for node in self.nodes: dkg_info = node.quorum("dkginfo") assert_equal(dkg_info['active_dkgs'], 0) @@ -101,7 +101,7 @@ def run_test(self): b_h_1 = self.nodes[0].getbestblockhash() tip = self.nodes[0].getblockcount() - next_dkg = 24 - (tip % 24); + next_dkg = 24 - (tip % 24) assert next_dkg < 24 nonzero_dkgs = 0 for i in range(len(self.nodes)):