From cd4bd73d794a5abf38b89b2be040d25fdec7c6d9 Mon Sep 17 00:00:00 2001
From: Odysseas Gabrielides <odysseas.gabrielides@gmail.com>
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<int>::max();
+        for (const auto &params: 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 <odysseas.gabrielides@gmail.com>
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 &params: 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 <odysseas.gabrielides@gmail.com>
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 <odysseas.gabrielides@gmail.com>
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<int>::max();
+            for (const auto &params: 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<int>::max();
-        for (const auto &params: 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 <odysseas.gabrielides@gmail.com>
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<int>::max();
-            for (const auto &params: 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<int>::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 <UdjinM6@users.noreply.github.com>
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 <odysseas.gabrielides@gmail.com>
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 <UdjinM6@users.noreply.github.com>
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<int>::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)):