LCOV - code coverage report
Current view: top level - src/llmq - core_write.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 195 208 93.8 %
Date: 2026-06-25 07:23:43 Functions: 13 13 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2018-2025 The Dash Core developers
       2             : // Distributed under the MIT software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #include <llmq/commitment.h>
       6             : #include <llmq/debug.h>
       7             : #include <llmq/signing.h>
       8             : #include <llmq/snapshot.h>
       9             : 
      10             : #include <core_io.h>
      11             : #include <rpc/util.h>
      12             : 
      13             : #include <univalue.h>
      14             : 
      15             : #include <map>
      16             : #include <string>
      17             : 
      18             : namespace llmq {
      19             : // CDKGDebugSessionStatus::ToJson() defined in llmq/debug.cpp
      20       21495 : RPCResult CDKGDebugSessionStatus::GetJsonHelp(const std::string& key, bool optional)
      21             : {
      22       42990 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The state of a DKG session",
      23      623355 :     {
      24       21495 :         GetRpcResult("llmqType"),
      25       21495 :         GetRpcResult("quorumHash"),
      26       21495 :         {RPCResult::Type::NUM, "quorumHeight", "Block height of the quorum"},
      27       21495 :         {RPCResult::Type::NUM, "phase", "Active DKG phase"},
      28       21495 :         {RPCResult::Type::BOOL, "sentContributions", "Returns true if contributions sent"},
      29       21495 :         {RPCResult::Type::BOOL, "sentComplaint", "Returns true if complaints sent"},
      30       21495 :         {RPCResult::Type::BOOL, "sentJustification", "Returns true if justifications sent"},
      31       21495 :         {RPCResult::Type::BOOL, "sentPrematureCommitment", "Returns true if premature commitments sent"},
      32       21495 :         {RPCResult::Type::BOOL, "aborted", "Returns true if DKG session aborted"},
      33       21495 :         {RPCResult{"for detail_level = 0", RPCResult::Type::NUM, "badMembers", "Number of bad members"}},
      34       21495 :         {RPCResult{"for detail_level = 0", RPCResult::Type::NUM, "weComplain", "Number of complaints sent"}},
      35       21495 :         {RPCResult{"for detail_level = 0", RPCResult::Type::NUM, "receivedContributions", "Number of contributions received"}},
      36       21495 :         {RPCResult{"for detail_level = 0", RPCResult::Type::NUM, "receivedComplaints", "Number of complaints received"}},
      37       21495 :         {RPCResult{"for detail_level = 0", RPCResult::Type::NUM, "receivedJustifications", "Number of justifications received"}},
      38       21495 :         {RPCResult{"for detail_level = 0", RPCResult::Type::NUM, "receivedPrematureCommitments", "Number of premature commitments received"}},
      39       42990 :         {RPCResult{"for detail_level = 1", RPCResult::Type::ARR, "badMembers", "Array of indexes for each bad member", {
      40       21495 :             {RPCResult::Type::NUM, "", "Quorum member index"}}}},
      41       42990 :         {RPCResult{"for detail_level = 1", RPCResult::Type::ARR, "weComplain", "Array of indexes for each complaint sent", {
      42       21495 :             {RPCResult::Type::NUM, "", "Quorum member index"}}}},
      43       42990 :         {RPCResult{"for detail_level = 1", RPCResult::Type::ARR, "receivedContributions", "Array of indexes for each contribution received", {
      44       21495 :             {RPCResult::Type::NUM, "", "Quorum member index"}}}},
      45       42990 :         {RPCResult{"for detail_level = 1", RPCResult::Type::ARR, "receivedComplaints", "Array of indexes for each complaint received", {
      46       21495 :             {RPCResult::Type::NUM, "", "Quorum member index"}}}},
      47       42990 :         {RPCResult{"for detail_level = 1", RPCResult::Type::ARR, "receivedJustifications", "Array of indexes for each justification received", {
      48       21495 :             {RPCResult::Type::NUM, "", "Quorum member index"}}}},
      49       42990 :         {RPCResult{"for detail_level = 1", RPCResult::Type::ARR, "receivedPrematureCommitments", "Array of indexes for each commitment received", {
      50       21495 :             {RPCResult::Type::NUM, "", "Quorum member index"}}}},
      51       42990 :         {RPCResult{"for detail_level = 2", RPCResult::Type::ARR, "badMembers", "Array of objects for each bad member", {
      52       64485 :             {RPCResult::Type::OBJ, "", "", {
      53       21495 :                 GetRpcResult("memberIndex"),
      54       21495 :                 GetRpcResult("proTxHash", /*optional=*/true)}}}}},
      55       42990 :         {RPCResult{"for detail_level = 2", RPCResult::Type::ARR, "weComplain", "Array of objects for each complaint sent", {
      56       64485 :             {RPCResult::Type::OBJ, "", "", {
      57       21495 :                 GetRpcResult("memberIndex"),
      58       21495 :                 GetRpcResult("proTxHash", /*optional=*/true)}}}}},
      59       42990 :         {RPCResult{"for detail_level = 2", RPCResult::Type::ARR, "receivedContributions", "Array of objects for each contribution received", {
      60       64485 :             {RPCResult::Type::OBJ, "", "", {
      61       21495 :                 GetRpcResult("memberIndex"),
      62       21495 :                 GetRpcResult("proTxHash", /*optional=*/true)}}}}},
      63       42990 :         {RPCResult{"for detail_level = 2", RPCResult::Type::ARR, "receivedComplaints", "Array of objects for each complaint received", {
      64       64485 :             {RPCResult::Type::OBJ, "", "", {
      65       21495 :                 GetRpcResult("memberIndex"),
      66       21495 :                 GetRpcResult("proTxHash", /*optional=*/true)}}}}},
      67       42990 :         {RPCResult{"for detail_level = 2", RPCResult::Type::ARR, "receivedJustifications", "Array of objects for each justification received", {
      68       64485 :             {RPCResult::Type::OBJ, "", "", {
      69       21495 :                 GetRpcResult("memberIndex"),
      70       21495 :                 GetRpcResult("proTxHash", /*optional=*/true)}}}}},
      71       42990 :         {RPCResult{"for detail_level = 2", RPCResult::Type::ARR, "receivedPrematureCommitments", "Array of objects for each commitment received", {
      72       64485 :             {RPCResult::Type::OBJ, "", "", {
      73       21495 :                 GetRpcResult("memberIndex"),
      74       21495 :                 GetRpcResult("proTxHash", /*optional=*/true)}}}}},
      75       42990 :         {RPCResult{"for detail_level = 2", RPCResult::Type::ARR, "allMembers", "Array of provider registration transaction hash for all quorum members", {
      76       21495 :             GetRpcResult("proTxHash")}}},
      77             :     }};
      78           0 : }
      79             : 
      80             : // CDKGDebugManager::ToJson() defined in llmq/debug.cpp
      81       21495 : RPCResult CDKGDebugManager::GetJsonHelp(const std::string& key, bool optional, bool inner_optional)
      82             : {
      83       42990 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The state of the node's DKG sessions",
      84       85980 :     {
      85       21495 :         {RPCResult::Type::NUM, "time", inner_optional, "Adjusted time for the last update, timestamp"},
      86       21495 :         {RPCResult::Type::STR, "timeStr", inner_optional, "Adjusted time for the last update, human friendly"},
      87       42990 :         {RPCResult::Type::ARR, "session", inner_optional, "", {
      88       85980 :             {RPCResult::Type::OBJ, "", "", {
      89       21495 :                 {RPCResult::Type::NUM, "llmqType", "Name of quorum"},
      90       21495 :                 GetRpcResult("quorumIndex"),
      91       21495 :                 CDKGDebugSessionStatus::GetJsonHelp(/*key=*/"status", /*optional=*/false)
      92             :             }},
      93             :         }}
      94             :     }};
      95           0 : }
      96             : 
      97       97343 : RPCResult CFinalCommitment::GetJsonHelp(const std::string& key, bool optional)
      98             : {
      99      194686 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The quorum commitment payload",
     100     1265459 :     {
     101       97343 :         {RPCResult::Type::NUM, "version", "Quorum commitment payload version"},
     102       97343 :         GetRpcResult("llmqType"),
     103       97343 :         GetRpcResult("quorumHash"),
     104       97343 :         {RPCResult::Type::NUM, "quorumIndex", "Index of the quorum"},
     105       97343 :         {RPCResult::Type::NUM, "signersCount", "Number of signers for the quorum"},
     106       97343 :         {RPCResult::Type::STR_HEX, "signers", "Bitset representing the aggregated signers"},
     107       97343 :         {RPCResult::Type::NUM, "validMembersCount", "Number of valid members in the quorum"},
     108       97343 :         {RPCResult::Type::STR_HEX, "validMembers", "Bitset of valid members"},
     109       97343 :         {RPCResult::Type::STR_HEX, "quorumPublicKey", "BLS public key of the quorum"},
     110       97343 :         {RPCResult::Type::STR_HEX, "quorumVvecHash", "Hash of the quorum verification vector"},
     111       97343 :         GetRpcResult("quorumSig"),
     112       97343 :         {RPCResult::Type::STR_HEX, "membersSig", "BLS signature from all included commitments"},
     113             :     }};
     114           0 : }
     115             : 
     116        6329 : UniValue CFinalCommitment::ToJson() const
     117             : {
     118        6329 :     UniValue obj(UniValue::VOBJ);
     119        6329 :     obj.pushKV("version", nVersion);
     120        6329 :     obj.pushKV("llmqType", std23::to_underlying(llmqType));
     121        6329 :     obj.pushKV("quorumHash", quorumHash.ToString());
     122        6329 :     obj.pushKV("quorumIndex", quorumIndex);
     123        6329 :     obj.pushKV("signersCount", CountSigners());
     124        6329 :     obj.pushKV("signers", BitsVectorToHexStr(signers));
     125        6329 :     obj.pushKV("validMembersCount", CountValidMembers());
     126        6329 :     obj.pushKV("validMembers", BitsVectorToHexStr(validMembers));
     127        6329 :     obj.pushKV("quorumPublicKey", quorumPublicKey.ToString(nVersion == LEGACY_BLS_NON_INDEXED_QUORUM_VERSION || nVersion == LEGACY_BLS_INDEXED_QUORUM_VERSION));
     128        6329 :     obj.pushKV("quorumVvecHash", quorumVvecHash.ToString());
     129        6329 :     obj.pushKV("quorumSig", quorumSig.ToString(nVersion == LEGACY_BLS_NON_INDEXED_QUORUM_VERSION || nVersion == LEGACY_BLS_INDEXED_QUORUM_VERSION));
     130        6329 :     obj.pushKV("membersSig", membersSig.ToString(nVersion == LEGACY_BLS_NON_INDEXED_QUORUM_VERSION || nVersion == LEGACY_BLS_INDEXED_QUORUM_VERSION));
     131        6329 :     return obj;
     132        6329 : }
     133             : 
     134       20509 : RPCResult CFinalCommitmentTxPayload::GetJsonHelp(const std::string& key, bool optional)
     135             : {
     136       41018 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The quorum commitment special transaction",
     137       82036 :     {
     138       20509 :         GetRpcResult("version"),
     139       20509 :         GetRpcResult("height"),
     140       20509 :         CFinalCommitment::GetJsonHelp(/*key=*/"commitment", /*optional=*/false),
     141             :     }};
     142           0 : }
     143             : 
     144          64 : UniValue CFinalCommitmentTxPayload::ToJson() const
     145             : {
     146          64 :     UniValue ret(UniValue::VOBJ);
     147          64 :     ret.pushKV("version", nVersion);
     148          64 :     ret.pushKV("height", nHeight);
     149          64 :     ret.pushKV("commitment", commitment.ToJson());
     150          64 :     return ret;
     151          64 : }
     152             : 
     153        6142 : RPCResult CQuorumRotationInfo::GetJsonHelp(const std::string& key, bool optional)
     154             : {
     155       12284 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The quorum rotation",
     156       92130 :     {
     157        6142 :         {RPCResult::Type::BOOL, "extraShare", "Returns true if an extra share is returned"},
     158        6142 :         CQuorumSnapshot::GetJsonHelp(/*key=*/"quorumSnapshotAtHMinusC", /*optional=*/false),
     159        6142 :         CQuorumSnapshot::GetJsonHelp(/*key=*/"quorumSnapshotAtHMinus2C", /*optional=*/false),
     160        6142 :         CQuorumSnapshot::GetJsonHelp(/*key=*/"quorumSnapshotAtHMinus3C", /*optional=*/false),
     161        6142 :         CQuorumSnapshot::GetJsonHelp(/*key=*/"quorumSnapshotAtHMinus4C", /*optional=*/true),
     162        6142 :         CSimplifiedMNListDiff::GetJsonHelp(/*key=*/"mnListDiffTip", /*optional=*/false),
     163        6142 :         CSimplifiedMNListDiff::GetJsonHelp(/*key=*/"mnListDiffH", /*optional=*/false),
     164        6142 :         CSimplifiedMNListDiff::GetJsonHelp(/*key=*/"mnListDiffAtHMinusC", /*optional=*/false),
     165        6142 :         CSimplifiedMNListDiff::GetJsonHelp(/*key=*/"mnListDiffAtHMinus2C", /*optional=*/false),
     166        6142 :         CSimplifiedMNListDiff::GetJsonHelp(/*key=*/"mnListDiffAtHMinus3C", /*optional=*/false),
     167        6142 :         CSimplifiedMNListDiff::GetJsonHelp(/*key=*/"mnListDiffAtHMinus4C", /*optional=*/true),
     168       12284 :         {RPCResult::Type::ARR, "lastCommitmentPerIndex", "Most recent commitment for each quorumIndex", {
     169        6142 :             CFinalCommitment::GetJsonHelp(/*key=*/"", /*optional=*/false),
     170             :         }},
     171       12284 :         {RPCResult::Type::ARR, "quorumSnapshotList", "Snapshots required to reconstruct the quorums built at h' in lastCommitmentPerIndex", {
     172        6142 :             CQuorumSnapshot::GetJsonHelp(/*key=*/"", /*optional=*/false),
     173             :         }},
     174       12284 :         {RPCResult::Type::ARR, "mnListDiffList", "MnListDiffs required to calculate older quorums", {
     175        6142 :             CSimplifiedMNListDiff::GetJsonHelp(/*key=*/"", /*optional=*/false),
     176             :         }},
     177             :     }};
     178           0 : }
     179             : 
     180           4 : UniValue CQuorumRotationInfo::ToJson() const
     181             : {
     182           4 :     UniValue obj(UniValue::VOBJ);
     183           4 :     obj.pushKV("extraShare", extraShare);
     184             : 
     185           4 :     obj.pushKV("quorumSnapshotAtHMinusC", cycleHMinusC.m_snap.ToJson());
     186           4 :     obj.pushKV("quorumSnapshotAtHMinus2C", cycleHMinus2C.m_snap.ToJson());
     187           4 :     obj.pushKV("quorumSnapshotAtHMinus3C", cycleHMinus3C.m_snap.ToJson());
     188             : 
     189           4 :     if (extraShare) {
     190           0 :         obj.pushKV("quorumSnapshotAtHMinus4C", CHECK_NONFATAL(cycleHMinus4C)->m_snap.ToJson());
     191           0 :     }
     192             : 
     193           4 :     obj.pushKV("mnListDiffTip", mnListDiffTip.ToJson());
     194           4 :     obj.pushKV("mnListDiffH", mnListDiffH.ToJson());
     195           4 :     obj.pushKV("mnListDiffAtHMinusC", cycleHMinusC.m_diff.ToJson());
     196           4 :     obj.pushKV("mnListDiffAtHMinus2C", cycleHMinus2C.m_diff.ToJson());
     197           4 :     obj.pushKV("mnListDiffAtHMinus3C", cycleHMinus3C.m_diff.ToJson());
     198             : 
     199           4 :     if (extraShare) {
     200           0 :         obj.pushKV("mnListDiffAtHMinus4C", CHECK_NONFATAL(cycleHMinus4C)->m_diff.ToJson());
     201           0 :     }
     202           4 :     UniValue hqclists(UniValue::VARR);
     203          12 :     for (const auto& qc : lastCommitmentPerIndex) {
     204           8 :         hqclists.push_back(qc.ToJson());
     205             :     }
     206           4 :     obj.pushKV("lastCommitmentPerIndex", hqclists);
     207             : 
     208           4 :     UniValue snapshotlist(UniValue::VARR);
     209           4 :     for (const auto& snap : quorumSnapshotList) {
     210           0 :         snapshotlist.push_back(snap.ToJson());
     211             :     }
     212           4 :     obj.pushKV("quorumSnapshotList", snapshotlist);
     213             : 
     214           4 :     UniValue mnlistdifflist(UniValue::VARR);
     215           4 :     for (const auto& mnlist : mnListDiffList) {
     216           0 :         mnlistdifflist.push_back(mnlist.ToJson());
     217             :     }
     218           4 :     obj.pushKV("mnListDiffList", mnlistdifflist);
     219           4 :     return obj;
     220           4 : }
     221             : 
     222       30710 : RPCResult CQuorumSnapshot::GetJsonHelp(const std::string& key, bool optional)
     223             : {
     224       61420 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The quorum snapshot",
     225      122840 :     {
     226       61420 :         {RPCResult::Type::ARR, "activeQuorumMembers", "Bitset of nodes already in quarters at the start of cycle", {
     227       30710 :             {RPCResult::Type::BOOL, "bit", ""}
     228             :         }},
     229       30710 :         {RPCResult::Type::NUM, "mnSkipListMode", "Mode of the skip list"},
     230       61420 :         {RPCResult::Type::ARR, "mnSkipList", "Skiplist at height", {
     231       30710 :             {RPCResult::Type::NUM, "height", ""}
     232             :         }},
     233             :     }};
     234           0 : }
     235             : 
     236          13 : UniValue CQuorumSnapshot::ToJson() const
     237             : {
     238          13 :     UniValue obj(UniValue::VOBJ);
     239          13 :     UniValue activeQ(UniValue::VARR);
     240         116 :     for (const bool h : activeQuorumMembers) {
     241             :         // cppcheck-suppress useStlAlgorithm
     242         103 :         activeQ.push_back(h);
     243             :     }
     244          13 :     obj.pushKV("activeQuorumMembers", activeQ);
     245          13 :     obj.pushKV("mnSkipListMode", std23::to_underlying(mnSkipListMode));
     246          13 :     UniValue skipList(UniValue::VARR);
     247          17 :     for (const auto& h : mnSkipList) {
     248             :         // cppcheck-suppress useStlAlgorithm
     249           4 :         skipList.push_back(h);
     250             :     }
     251          13 :     obj.pushKV("mnSkipList", skipList);
     252          13 :     return obj;
     253          13 : }
     254             : 
     255        6244 : RPCResult CRecoveredSig::GetJsonHelp(const std::string& key, bool optional)
     256             : {
     257       12488 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The recovered signature",
     258       43708 :     {
     259        6244 :         GetRpcResult("llmqType"),
     260        6244 :         GetRpcResult("quorumHash"),
     261        6244 :         {RPCResult::Type::NUM, "id", "Signing session ID"},
     262        6244 :         {RPCResult::Type::STR_HEX, "msgHash", "Hash of message"},
     263        6244 :         {RPCResult::Type::STR_HEX, "sig", "BLS signature recovered"},
     264        6244 :         {RPCResult::Type::STR_HEX, "hash", "Hash of the BLS signature recovered"},
     265             :     }};
     266           0 : }
     267             : 
     268         106 : UniValue CRecoveredSig::ToJson() const
     269             : {
     270         106 :     UniValue ret(UniValue::VOBJ);
     271         106 :     ret.pushKV("llmqType", std23::to_underlying(llmqType));
     272         106 :     ret.pushKV("quorumHash", quorumHash.ToString());
     273         106 :     ret.pushKV("id", id.ToString());
     274         106 :     ret.pushKV("msgHash", msgHash.ToString());
     275         106 :     ret.pushKV("sig", sig.Get().ToString());
     276         106 :     ret.pushKV("hash", sig.Get().GetHash().ToString());
     277         106 :     return ret;
     278         106 : }
     279             : } // namespace llmq

Generated by: LCOV version 1.16