LCOV - code coverage report
Current view: top level - src/evo - core_write.cpp (source / functions) Hit Total Coverage
Test: test_dash_coverage.info Lines: 229 481 47.6 %
Date: 2026-06-25 07:23:51 Functions: 17 33 51.5 %

          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 <evo/assetlocktx.h>
       6             : #include <evo/cbtx.h>
       7             : #include <evo/deterministicmns.h>
       8             : #include <evo/dmnstate.h>
       9             : #include <evo/mnhftx.h>
      10             : #include <evo/netinfo.h>
      11             : #include <evo/providertx.h>
      12             : #include <evo/simplifiedmns.h>
      13             : #include <evo/smldiff.h>
      14             : #include <llmq/commitment.h>
      15             : #include <rpc/evo_util.h>
      16             : #include <util/std23.h>
      17             : 
      18             : #include <core_io.h>
      19             : #include <rpc/util.h>
      20             : #include <util/check.h>
      21             : 
      22             : #include <univalue.h>
      23             : 
      24             : #include <map>
      25             : #include <string>
      26             : 
      27             : namespace {
      28             : #define RESULT_MAP_ENTRY(name, type, desc) {name, {type, name, desc}}
      29        7848 : const std::map<std::string, RPCResult> RPCRESULT_MAP{{
      30         436 :     {"addresses",
      31         436 :         {RPCResult::Type::OBJ, "addresses", "Network addresses of the masternode",
      32         872 :     {
      33         436 :         {RPCResult::Type::ARR, "core_p2p", /*optional=*/true, "Addresses used for protocol P2P",
      34         218 :             {{RPCResult::Type::STR, "address", ""}}},
      35         436 :         {RPCResult::Type::ARR, "platform_p2p", /*optional=*/true, "Addresses used for Platform P2P",
      36         218 :             {{RPCResult::Type::STR, "address", ""}}},
      37         436 :         {RPCResult::Type::ARR, "platform_https", /*optional=*/true, "Addresses used for Platform HTTPS API",
      38         218 :             {{RPCResult::Type::STR, "address", ""}}},
      39             :     }}},
      40         218 :     RESULT_MAP_ENTRY("collateralAddress", RPCResult::Type::STR, "Dash address used for collateral"),
      41         218 :     RESULT_MAP_ENTRY("collateralHash", RPCResult::Type::STR_HEX, "Collateral transaction hash"),
      42         218 :     RESULT_MAP_ENTRY("collateralIndex", RPCResult::Type::NUM, "Collateral transaction output index"),
      43         218 :     RESULT_MAP_ENTRY("consecutivePayments", RPCResult::Type::NUM, "Consecutive payments masternode has received in payment cycle"),
      44         218 :     RESULT_MAP_ENTRY("height", RPCResult::Type::NUM, "Block height"),
      45         218 :     RESULT_MAP_ENTRY("inputsHash", RPCResult::Type::STR_HEX, "Hash of all the outpoints of the transaction inputs"),
      46         218 :     RESULT_MAP_ENTRY("lastPaidHeight", RPCResult::Type::NUM, "Height masternode was last paid"),
      47         218 :     RESULT_MAP_ENTRY("llmqType", RPCResult::Type::NUM, "Quorum type"),
      48         218 :     RESULT_MAP_ENTRY("memberIndex", RPCResult::Type::NUM, "Quorum member index"),
      49         218 :     RESULT_MAP_ENTRY("merkleRootMNList", RPCResult::Type::STR_HEX, "Merkle root of the masternode list"),
      50         218 :     RESULT_MAP_ENTRY("merkleRootQuorums", RPCResult::Type::STR_HEX, "Merkle root of the quorum list"),
      51         218 :     RESULT_MAP_ENTRY("operatorPayoutAddress", RPCResult::Type::STR, "Dash address used for operator reward payments"),
      52         218 :     RESULT_MAP_ENTRY("operatorReward", RPCResult::Type::NUM, "Fraction in %% of reward shared with the operator between 0 and 10000"),
      53         218 :     RESULT_MAP_ENTRY("outpoint", RPCResult::Type::STR_HEX,"The outpoint of the masternode"),
      54         218 :     RESULT_MAP_ENTRY("ownerAddress", RPCResult::Type::STR, "Dash address used for payee updates and proposal voting"),
      55         218 :     RESULT_MAP_ENTRY("payoutAddress", RPCResult::Type::STR, "Dash address used for masternode reward payments"),
      56         218 :     RESULT_MAP_ENTRY("platformHTTPPort", RPCResult::Type::NUM, "TCP port of Platform HTTP API (DEPRECATED, returned only if config option -deprecatedrpc=service is passed)"),
      57         218 :     RESULT_MAP_ENTRY("platformNodeID", RPCResult::Type::STR_HEX, "Node ID derived from P2P public key for Platform P2P"),
      58         218 :     RESULT_MAP_ENTRY("platformP2PPort", RPCResult::Type::NUM, "TCP port of Platform P2P (DEPRECATED, returned only if config option -deprecatedrpc=service is passed)"),
      59         218 :     RESULT_MAP_ENTRY("PoSeBanHeight", RPCResult::Type::NUM, "Height masternode was banned for Proof of Service violations"),
      60         218 :     RESULT_MAP_ENTRY("PoSePenalty", RPCResult::Type::NUM, "Proof of Service penalty score"),
      61         218 :     RESULT_MAP_ENTRY("PoSeRevivedHeight", RPCResult::Type::NUM, "Height masternode recovered from Proof of Service violations"),
      62         218 :     RESULT_MAP_ENTRY("proTxHash", RPCResult::Type::STR_HEX, "Hash of the masternode's initial ProRegTx"),
      63         218 :     RESULT_MAP_ENTRY("pubKeyOperator", RPCResult::Type::STR, "BLS public key used for operator signing"),
      64         218 :     RESULT_MAP_ENTRY("quorumIndex", RPCResult::Type::NUM, "Quorum index. Relevant for rotation quorums only, 0 for non-rotating quorums"),
      65         218 :     RESULT_MAP_ENTRY("quorumHash", RPCResult::Type::STR_HEX, "Hash of the quorum"),
      66         218 :     RESULT_MAP_ENTRY("quorumSig", RPCResult::Type::STR_HEX, "BLS recovered threshold signature of quorum"),
      67         218 :     RESULT_MAP_ENTRY("registeredHeight", RPCResult::Type::NUM, "Height masternode was registered"),
      68         218 :     RESULT_MAP_ENTRY("revocationReason", RPCResult::Type::NUM, "Reason for ProUpRegTx revocation"),
      69         218 :     RESULT_MAP_ENTRY("service", RPCResult::Type::STR, "IP address and port of the masternode (DEPRECATED, returned only if config option -deprecatedrpc=service is passed)"),
      70         218 :     RESULT_MAP_ENTRY("type", RPCResult::Type::NUM, "Masternode type"),
      71         218 :     RESULT_MAP_ENTRY("type_str", RPCResult::Type::STR, "Masternode type (human-readable string)"),
      72         218 :     RESULT_MAP_ENTRY("version", RPCResult::Type::NUM, "Special transaction version"),
      73         218 :     RESULT_MAP_ENTRY("votingAddress", RPCResult::Type::STR, "Dash address used for voting"),
      74             : }};
      75             : #undef RESULT_MAP_ENTRY
      76             : 
      77             : template <typename Obj>
      78           0 : std::string GetDeprecatedServiceField(const Obj& obj)
      79             : {
      80           0 :     return CHECK_NONFATAL(obj.netInfo)->GetPrimary().ToStringAddrPort();
      81           0 : }
      82             : } // anonymous namespace
      83             : 
      84       33555 : RPCResult GetRpcResult(const std::string& key, bool optional, const std::string& override_name)
      85             : {
      86       33555 :     if (const auto it = RPCRESULT_MAP.find(key); it != RPCRESULT_MAP.end()) {
      87       33555 :         const auto& ret{it->second};
      88       33555 :         return RPCResult{ret.m_type, override_name.empty() ? ret.m_key_name : override_name, optional, ret.m_description, ret.m_inner};
      89             :     }
      90           0 :     throw NonFatalCheckError(strprintf("Requested invalid RPCResult for nonexistent key \"%s\"", key).c_str(),
      91             :                              __FILE__, __LINE__, __func__);
      92           0 : }
      93             : 
      94         191 : RPCResult CAssetLockPayload::GetJsonHelp(const std::string& key, bool optional)
      95             : {
      96         382 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The asset lock special transaction",
      97         573 :     {
      98         191 :         GetRpcResult("version"),
      99         382 :         {RPCResult::Type::ARR, "creditOutputs", "", {
     100         764 :             {RPCResult::Type::OBJ, "", "", {
     101         191 :                 {RPCResult::Type::NUM, "value", "The value in Dash"},
     102         191 :                 {RPCResult::Type::NUM, "valueSat", "The value in duffs"},
     103         764 :                 {RPCResult::Type::OBJ, "scriptPubKey", "", {
     104         191 :                     {RPCResult::Type::STR, "asm", "The asm"},
     105         191 :                     {RPCResult::Type::STR_HEX, "hex", "The hex"},
     106         191 :                     {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
     107             :         }}}}}}
     108             :     }};
     109           0 : }
     110             : 
     111           0 : UniValue CAssetLockPayload::ToJson() const
     112             : {
     113           0 :     UniValue outputs(UniValue::VARR);
     114           0 :     for (const CTxOut& credit_output : creditOutputs) {
     115           0 :         UniValue out(UniValue::VOBJ);
     116           0 :         out.pushKV("value", ValueFromAmount(credit_output.nValue));
     117           0 :         out.pushKV("valueSat", credit_output.nValue);
     118           0 :         UniValue spk(UniValue::VOBJ);
     119           0 :         ScriptToUniv(credit_output.scriptPubKey, spk, /*include_hex=*/true, /*include_address=*/false);
     120           0 :         out.pushKV("scriptPubKey", spk);
     121           0 :         outputs.push_back(out);
     122           0 :     }
     123             : 
     124           0 :     UniValue ret(UniValue::VOBJ);
     125           0 :     ret.pushKV("version", nVersion);
     126           0 :     ret.pushKV("creditOutputs", outputs);
     127           0 :     return ret;
     128           0 : }
     129             : 
     130         191 : RPCResult CAssetUnlockPayload::GetJsonHelp(const std::string& key, bool optional)
     131             : {
     132         382 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The asset unlock special transaction",
     133        1337 :     {
     134         191 :         GetRpcResult("version"),
     135         191 :         {RPCResult::Type::NUM, "index", "Index of the transaction"},
     136         191 :         {RPCResult::Type::NUM, "fee", "Transaction fee in duffs awarded to the miner"},
     137         191 :         {RPCResult::Type::NUM, "requestedHeight", "Payment chain block height known by Platform when signing the withdrawal"},
     138         191 :         GetRpcResult("quorumHash"),
     139         191 :         GetRpcResult("quorumSig"),
     140             :     }};
     141           0 : }
     142             : 
     143           0 : UniValue CAssetUnlockPayload::ToJson() const
     144             : {
     145           0 :     UniValue ret(UniValue::VOBJ);
     146           0 :     ret.pushKV("version", nVersion);
     147           0 :     ret.pushKV("index", index);
     148           0 :     ret.pushKV("fee", fee);
     149           0 :     ret.pushKV("requestedHeight", requestedHeight);
     150           0 :     ret.pushKV("quorumHash", quorumHash.ToString());
     151           0 :     ret.pushKV("quorumSig", quorumSig.ToString());
     152           0 :     return ret;
     153           0 : }
     154             : 
     155         283 : RPCResult CCbTx::GetJsonHelp(const std::string& key, bool optional)
     156             : {
     157         566 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The coinbase special transaction",
     158        2264 :     {
     159         283 :         GetRpcResult("version"),
     160         283 :         GetRpcResult("height"),
     161         283 :         GetRpcResult("merkleRootMNList"),
     162         283 :         GetRpcResult("merkleRootQuorums", /*optional=*/true),
     163         283 :         {RPCResult::Type::NUM, "bestCLHeightDiff", /*optional=*/true, "Blocks between the current block and the last known block with a ChainLock"},
     164         283 :         {RPCResult::Type::STR_HEX, "bestCLSignature", /*optional=*/true, "Best ChainLock signature known by the miner"},
     165         283 :         {RPCResult::Type::NUM, "creditPoolBalance", /*optional=*/true, "Balance in the Platform credit pool"},
     166             :     }};
     167           0 : }
     168             : 
     169           0 : UniValue CCbTx::ToJson() const
     170             : {
     171           0 :     UniValue ret(UniValue::VOBJ);
     172           0 :     ret.pushKV("version", std23::to_underlying(nVersion));
     173           0 :     ret.pushKV("height", nHeight);
     174           0 :     ret.pushKV("merkleRootMNList", merkleRootMNList.ToString());
     175           0 :     if (nVersion >= CCbTx::Version::MERKLE_ROOT_QUORUMS) {
     176           0 :         ret.pushKV("merkleRootQuorums", merkleRootQuorums.ToString());
     177           0 :         if (nVersion >= CCbTx::Version::CLSIG_AND_BALANCE) {
     178           0 :             ret.pushKV("bestCLHeightDiff", bestCLHeightDiff);
     179           0 :             ret.pushKV("bestCLSignature", bestCLSignature.ToString());
     180           0 :             ret.pushKV("creditPoolBalance", ValueFromAmount(creditPoolBalance));
     181           0 :         }
     182           0 :     }
     183           0 :     return ret;
     184           0 : }
     185             : 
     186             : // CDeterministicMN::ToJson() defined in evo/deterministicmns.cpp
     187          92 : RPCResult CDeterministicMN::GetJsonHelp(const std::string& key, bool optional)
     188             : {
     189         184 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The masternode's details",
     190         736 :     {
     191          92 :         GetRpcResult("type_str", /*optional=*/false, /*override_name=*/"type"),
     192          92 :         GetRpcResult("proTxHash"),
     193          92 :         GetRpcResult("collateralHash"),
     194          92 :         GetRpcResult("collateralIndex"),
     195          92 :         GetRpcResult("collateralAddress", /*optional=*/true),
     196          92 :         GetRpcResult("operatorReward"),
     197          92 :         CDeterministicMNState::GetJsonHelp(/*key=*/"state", /*optional=*/false),
     198             :     }};
     199           0 : }
     200             : 
     201         184 : RPCResult CDeterministicMNState::GetJsonHelp(const std::string& key, bool optional)
     202             : {
     203         368 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The masternode state",
     204        3496 :     {
     205         184 :         {RPCResult::Type::NUM, "version", "Version of the masternode state"},
     206         184 :         GetRpcResult("service", /*optional=*/true),
     207         184 :         GetRpcResult("addresses"),
     208         184 :         GetRpcResult("registeredHeight"),
     209         184 :         GetRpcResult("lastPaidHeight"),
     210         184 :         GetRpcResult("consecutivePayments"),
     211         184 :         GetRpcResult("PoSePenalty"),
     212         184 :         GetRpcResult("PoSeRevivedHeight"),
     213         184 :         GetRpcResult("PoSeBanHeight"),
     214         184 :         GetRpcResult("revocationReason"),
     215         184 :         GetRpcResult("ownerAddress"),
     216         184 :         GetRpcResult("votingAddress"),
     217         184 :         GetRpcResult("platformNodeID", /*optional=*/true),
     218         184 :         GetRpcResult("platformP2PPort", /*optional=*/true),
     219         184 :         GetRpcResult("platformHTTPPort", /*optional=*/true),
     220         184 :         GetRpcResult("payoutAddress", /*optional=*/true),
     221         184 :         GetRpcResult("pubKeyOperator"),
     222         184 :         GetRpcResult("operatorPayoutAddress", /*optional=*/true),
     223             :     }};
     224           0 : }
     225             : 
     226           0 : UniValue CDeterministicMNState::ToJson(MnType nType) const
     227             : {
     228           0 :     UniValue obj(UniValue::VOBJ);
     229           0 :     obj.pushKV("version", nVersion);
     230           0 :     if (IsServiceDeprecatedRPCEnabled()) {
     231           0 :         obj.pushKV("service", GetDeprecatedServiceField(*this));
     232           0 :     }
     233           0 :     obj.pushKV("addresses", GetNetInfoWithLegacyFields(*this, nType));
     234           0 :     obj.pushKV("registeredHeight", nRegisteredHeight);
     235           0 :     obj.pushKV("lastPaidHeight", nLastPaidHeight);
     236           0 :     obj.pushKV("consecutivePayments", nConsecutivePayments);
     237           0 :     obj.pushKV("PoSePenalty", nPoSePenalty);
     238           0 :     obj.pushKV("PoSeRevivedHeight", nPoSeRevivedHeight);
     239           0 :     obj.pushKV("PoSeBanHeight", nPoSeBanHeight);
     240           0 :     obj.pushKV("revocationReason", nRevocationReason);
     241           0 :     obj.pushKV("ownerAddress", EncodeDestination(PKHash(keyIDOwner)));
     242           0 :     obj.pushKV("votingAddress", EncodeDestination(PKHash(keyIDVoting)));
     243           0 :     if (nType == MnType::Evo) {
     244           0 :         obj.pushKV("platformNodeID", platformNodeID.ToString());
     245           0 :         if (IsServiceDeprecatedRPCEnabled()) {
     246           0 :             obj.pushKV("platformP2PPort", GetPlatformPort</*is_p2p=*/true>(*this));
     247           0 :             obj.pushKV("platformHTTPPort", GetPlatformPort</*is_p2p=*/false>(*this));
     248           0 :         }
     249           0 :     }
     250             : 
     251           0 :     CTxDestination dest;
     252           0 :     if (ExtractDestination(scriptPayout, dest)) {
     253           0 :         obj.pushKV("payoutAddress", EncodeDestination(dest));
     254           0 :     }
     255           0 :     obj.pushKV("pubKeyOperator", pubKeyOperator.ToString());
     256           0 :     if (ExtractDestination(scriptOperatorPayout, dest)) {
     257           0 :         obj.pushKV("operatorPayoutAddress", EncodeDestination(dest));
     258           0 :     }
     259           0 :     return obj;
     260           0 : }
     261             : 
     262             : // CDeterministicMNStateDiff::ToJson() defined in evo/dmnstate.cpp
     263          92 : RPCResult CDeterministicMNStateDiff::GetJsonHelp(const std::string& key, bool optional)
     264             : {
     265         184 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The masternode state diff",
     266        1748 :     {
     267          92 :         {RPCResult::Type::NUM, "version", "Version of the masternode state diff"},
     268          92 :         GetRpcResult("service", /*optional=*/true),
     269          92 :         GetRpcResult("registeredHeight", /*optional=*/true),
     270          92 :         GetRpcResult("lastPaidHeight", /*optional=*/true),
     271          92 :         GetRpcResult("consecutivePayments", /*optional=*/true),
     272          92 :         GetRpcResult("PoSePenalty", /*optional=*/true),
     273          92 :         GetRpcResult("PoSeRevivedHeight", /*optional=*/true),
     274          92 :         GetRpcResult("PoSeBanHeight", /*optional=*/true),
     275          92 :         GetRpcResult("revocationReason", /*optional=*/true),
     276          92 :         GetRpcResult("ownerAddress", /*optional=*/true),
     277          92 :         GetRpcResult("votingAddress", /*optional=*/true),
     278          92 :         GetRpcResult("payoutAddress", /*optional=*/true),
     279          92 :         GetRpcResult("operatorPayoutAddress", /*optional=*/true),
     280          92 :         GetRpcResult("pubKeyOperator", /*optional=*/true),
     281          92 :         GetRpcResult("platformNodeID", /*optional=*/true),
     282          92 :         GetRpcResult("platformP2PPort", /*optional=*/true),
     283          92 :         GetRpcResult("platformHTTPPort", /*optional=*/true),
     284          92 :         GetRpcResult("addresses", /*optional=*/true),
     285             :     }};
     286           0 : }
     287             : 
     288         191 : RPCResult CProRegTx::GetJsonHelp(const std::string& key, bool optional)
     289             : {
     290         382 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The masternode registration special transaction",
     291        3056 :     {
     292         191 :         GetRpcResult("version"),
     293         191 :         GetRpcResult("type"),
     294         191 :         GetRpcResult("collateralHash"),
     295         191 :         GetRpcResult("collateralIndex"),
     296         191 :         GetRpcResult("service", /*optional=*/true),
     297         191 :         GetRpcResult("addresses"),
     298         191 :         GetRpcResult("ownerAddress"),
     299         191 :         GetRpcResult("votingAddress"),
     300         191 :         GetRpcResult("payoutAddress", /*optional=*/true),
     301         191 :         GetRpcResult("pubKeyOperator"),
     302         191 :         GetRpcResult("operatorReward"),
     303         191 :         GetRpcResult("platformNodeID", /*optional=*/true),
     304         191 :         GetRpcResult("platformP2PPort", /*optional=*/true),
     305         191 :         GetRpcResult("platformHTTPPort", /*optional=*/true),
     306         191 :         GetRpcResult("inputsHash"),
     307             :     }};
     308           0 : }
     309             : 
     310           0 : UniValue CProRegTx::ToJson() const
     311             : {
     312           0 :     UniValue ret(UniValue::VOBJ);
     313           0 :     ret.pushKV("version", nVersion);
     314           0 :     ret.pushKV("type", std23::to_underlying(nType));
     315           0 :     ret.pushKV("collateralHash", collateralOutpoint.hash.ToString());
     316           0 :     ret.pushKV("collateralIndex", collateralOutpoint.n);
     317           0 :     if (IsServiceDeprecatedRPCEnabled()) {
     318           0 :         ret.pushKV("service", GetDeprecatedServiceField(*this));
     319           0 :     }
     320           0 :     ret.pushKV("addresses", GetNetInfoWithLegacyFields(*this, nType));
     321           0 :     ret.pushKV("ownerAddress", EncodeDestination(PKHash(keyIDOwner)));
     322           0 :     ret.pushKV("votingAddress", EncodeDestination(PKHash(keyIDVoting)));
     323           0 :     if (CTxDestination dest; ExtractDestination(scriptPayout, dest)) {
     324           0 :         ret.pushKV("payoutAddress", EncodeDestination(dest));
     325           0 :     }
     326           0 :     ret.pushKV("pubKeyOperator", pubKeyOperator.ToString());
     327           0 :     ret.pushKV("operatorReward", (double)nOperatorReward / 100);
     328           0 :     if (nType == MnType::Evo) {
     329           0 :         ret.pushKV("platformNodeID", platformNodeID.ToString());
     330           0 :         if (IsServiceDeprecatedRPCEnabled()) {
     331           0 :             ret.pushKV("platformP2PPort", GetPlatformPort</*is_p2p=*/true>(*this));
     332           0 :             ret.pushKV("platformHTTPPort", GetPlatformPort</*is_p2p=*/false>(*this));
     333           0 :         }
     334           0 :     }
     335           0 :     ret.pushKV("inputsHash", inputsHash.ToString());
     336           0 :     return ret;
     337           0 : }
     338             : 
     339         191 : RPCResult CProUpRegTx::GetJsonHelp(const std::string& key, bool optional)
     340             : {
     341         382 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The masternode update registrar special transaction",
     342        1337 :     {
     343         191 :         GetRpcResult("version"),
     344         191 :         GetRpcResult("proTxHash"),
     345         191 :         GetRpcResult("votingAddress"),
     346         191 :         GetRpcResult("payoutAddress", /*optional=*/true),
     347         191 :         GetRpcResult("pubKeyOperator"),
     348         191 :         GetRpcResult("inputsHash"),
     349             :     }};
     350           0 : }
     351             : 
     352           0 : UniValue CProUpRegTx::ToJson() const
     353             : {
     354           0 :     UniValue ret(UniValue::VOBJ);
     355           0 :     ret.pushKV("version", nVersion);
     356           0 :     ret.pushKV("proTxHash", proTxHash.ToString());
     357           0 :     ret.pushKV("votingAddress", EncodeDestination(PKHash(keyIDVoting)));
     358           0 :     if (CTxDestination dest; ExtractDestination(scriptPayout, dest)) {
     359           0 :         ret.pushKV("payoutAddress", EncodeDestination(dest));
     360           0 :     }
     361           0 :     ret.pushKV("pubKeyOperator", pubKeyOperator.ToString());
     362           0 :     ret.pushKV("inputsHash", inputsHash.ToString());
     363           0 :     return ret;
     364           0 : }
     365             : 
     366         191 : RPCResult CProUpRevTx::GetJsonHelp(const std::string& key, bool optional)
     367             : {
     368         382 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The masternode operator revocation special transaction",
     369         955 :     {
     370         191 :         GetRpcResult("version"),
     371         191 :         GetRpcResult("proTxHash"),
     372         191 :         {RPCResult::Type::NUM, "reason", "Reason for masternode service revocation"},
     373         191 :         GetRpcResult("inputsHash", /*optional=*/true),
     374             :     }};
     375           0 : }
     376             : 
     377           0 : UniValue CProUpRevTx::ToJson() const
     378             : {
     379           0 :     UniValue ret(UniValue::VOBJ);
     380           0 :     ret.pushKV("version", nVersion);
     381           0 :     ret.pushKV("proTxHash", proTxHash.ToString());
     382           0 :     ret.pushKV("reason", nReason);
     383           0 :     ret.pushKV("inputsHash", inputsHash.ToString());
     384           0 :     return ret;
     385           0 : }
     386             : 
     387         191 : RPCResult CProUpServTx::GetJsonHelp(const std::string& key, bool optional)
     388             : {
     389         382 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The masternode update service special transaction",
     390        2101 :     {
     391         191 :         GetRpcResult("version"),
     392         191 :         GetRpcResult("type"),
     393         191 :         GetRpcResult("proTxHash"),
     394         191 :         GetRpcResult("service", /*optional=*/true),
     395         191 :         GetRpcResult("addresses"),
     396         191 :         GetRpcResult("operatorPayoutAddress", /*optional=*/true),
     397         191 :         GetRpcResult("platformNodeID", /*optional=*/true),
     398         191 :         GetRpcResult("platformP2PPort", /*optional=*/true),
     399         191 :         GetRpcResult("platformHTTPPort", /*optional=*/true),
     400         191 :         GetRpcResult("inputsHash"),
     401             :     }};
     402           0 : }
     403             : 
     404           0 : UniValue CProUpServTx::ToJson() const
     405             : {
     406           0 :     UniValue ret(UniValue::VOBJ);
     407           0 :     ret.pushKV("version", nVersion);
     408           0 :     ret.pushKV("type", std23::to_underlying(nType));
     409           0 :     ret.pushKV("proTxHash", proTxHash.ToString());
     410           0 :     if (IsServiceDeprecatedRPCEnabled()) {
     411           0 :         ret.pushKV("service", GetDeprecatedServiceField(*this));
     412           0 :     }
     413           0 :     ret.pushKV("addresses", GetNetInfoWithLegacyFields(*this, nType));
     414           0 :     if (CTxDestination dest; ExtractDestination(scriptOperatorPayout, dest)) {
     415           0 :         ret.pushKV("operatorPayoutAddress", EncodeDestination(dest));
     416           0 :     }
     417           0 :     if (nType == MnType::Evo) {
     418           0 :         ret.pushKV("platformNodeID", platformNodeID.ToString());
     419           0 :         if (IsServiceDeprecatedRPCEnabled()) {
     420           0 :             ret.pushKV("platformP2PPort", GetPlatformPort</*is_p2p=*/true>(*this));
     421           0 :             ret.pushKV("platformHTTPPort", GetPlatformPort</*is_p2p=*/false>(*this));
     422           0 :         }
     423           0 :     }
     424           0 :     ret.pushKV("inputsHash", inputsHash.ToString());
     425           0 :     return ret;
     426           0 : }
     427             : 
     428         736 : RPCResult CSimplifiedMNListDiff::GetJsonHelp(const std::string& key, bool optional)
     429             : {
     430        1472 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The simplified masternode list diff",
     431        9568 :     {
     432         736 :         {RPCResult::Type::NUM, "nVersion", "Version of the diff"},
     433         736 :         {RPCResult::Type::STR_HEX, "baseBlockHash", "Hash of the base block"},
     434         736 :         {RPCResult::Type::STR_HEX, "blockHash", "Hash of the ending block"},
     435         736 :         {RPCResult::Type::STR_HEX, "cbTxMerkleTree", "Coinbase transaction merkle tree"},
     436         736 :         {RPCResult::Type::STR_HEX, "cbTx", "Coinbase raw transaction"},
     437        1472 :         {RPCResult::Type::ARR, "deletedMNs", "ProRegTx hashes of deleted masternodes",
     438         736 :             {{RPCResult::Type::STR_HEX, "hash", ""}}},
     439        1472 :         {RPCResult::Type::ARR, "mnList", "Masternode list details",
     440         736 :             {CSimplifiedMNListEntry::GetJsonHelp(/*key=*/"", /*optional=*/false)}},
     441        1472 :         {RPCResult::Type::ARR, "deletedQuorums", "Deleted quorums",
     442        2208 :             {{RPCResult::Type::OBJ, "", "", {
     443         736 :                 GetRpcResult("llmqType"),
     444         736 :                 GetRpcResult("quorumHash"),
     445             :         }}}},
     446        1472 :         {RPCResult::Type::ARR, "newQuorums", "New quorums",
     447         736 :             {llmq::CFinalCommitment::GetJsonHelp(/*key=*/"", /*optional=*/false)}},
     448         736 :         GetRpcResult("merkleRootMNList", /*optional=*/true),
     449         736 :         GetRpcResult("merkleRootQuorums", /*optional=*/true),
     450        1472 :         {RPCResult::Type::ARR, "quorumsCLSigs", "ChainLock signature details", {
     451        1472 :             {RPCResult::Type::OBJ, "", "", {
     452        1472 :                 {RPCResult::Type::ARR, "<sig_hex>", "Array of quorum indices, keyed by BLS signature", {
     453         736 :                     {RPCResult::Type::NUM, "", "Quorum index"}
     454             :         }}}}}},
     455             :     }};
     456           0 : }
     457             : 
     458           0 : UniValue CSimplifiedMNListDiff::ToJson(bool extended) const
     459             : {
     460           0 :     UniValue obj(UniValue::VOBJ);
     461             : 
     462           0 :     obj.pushKV("nVersion", nVersion);
     463           0 :     obj.pushKV("baseBlockHash", baseBlockHash.ToString());
     464           0 :     obj.pushKV("blockHash", blockHash.ToString());
     465             : 
     466           0 :     CDataStream ssCbTxMerkleTree(SER_NETWORK, PROTOCOL_VERSION);
     467           0 :     ssCbTxMerkleTree << cbTxMerkleTree;
     468           0 :     obj.pushKV("cbTxMerkleTree", HexStr(ssCbTxMerkleTree));
     469             : 
     470           0 :     obj.pushKV("cbTx", EncodeHexTx(CTransaction(cbTx)));
     471             : 
     472           0 :     UniValue deletedMNsArr(UniValue::VARR);
     473           0 :     for (const auto& h : deletedMNs) {
     474           0 :         deletedMNsArr.push_back(h.ToString());
     475             :     }
     476           0 :     obj.pushKV("deletedMNs", deletedMNsArr);
     477             : 
     478           0 :     UniValue mnListArr(UniValue::VARR);
     479           0 :     for (const auto& e : mnList) {
     480           0 :         mnListArr.push_back(e.ToJson(extended));
     481             :     }
     482           0 :     obj.pushKV("mnList", mnListArr);
     483             : 
     484           0 :     UniValue deletedQuorumsArr(UniValue::VARR);
     485           0 :     for (const auto& e : deletedQuorums) {
     486           0 :         UniValue eObj(UniValue::VOBJ);
     487           0 :         eObj.pushKV("llmqType", e.first);
     488           0 :         eObj.pushKV("quorumHash", e.second.ToString());
     489           0 :         deletedQuorumsArr.push_back(eObj);
     490           0 :     }
     491           0 :     obj.pushKV("deletedQuorums", deletedQuorumsArr);
     492             : 
     493           0 :     UniValue newQuorumsArr(UniValue::VARR);
     494           0 :     for (const auto& e : newQuorums) {
     495           0 :         newQuorumsArr.push_back(e.ToJson());
     496             :     }
     497           0 :     obj.pushKV("newQuorums", newQuorumsArr);
     498             : 
     499             :     // Do not assert special tx type here since this can be called prior to DIP0003 activation
     500           0 :     if (const auto opt_cbTxPayload = GetTxPayload<CCbTx>(cbTx, /*assert_type=*/false)) {
     501           0 :         obj.pushKV("merkleRootMNList", opt_cbTxPayload->merkleRootMNList.ToString());
     502           0 :         if (opt_cbTxPayload->nVersion >= CCbTx::Version::MERKLE_ROOT_QUORUMS) {
     503           0 :             obj.pushKV("merkleRootQuorums", opt_cbTxPayload->merkleRootQuorums.ToString());
     504           0 :         }
     505           0 :     }
     506             : 
     507           0 :     UniValue quorumsCLSigsArr(UniValue::VARR);
     508           0 :     for (const auto& [signature, quorumsIndexes] : quorumsCLSigs) {
     509           0 :         UniValue j(UniValue::VOBJ);
     510           0 :         UniValue idxArr(UniValue::VARR);
     511           0 :         for (const auto& idx : quorumsIndexes) {
     512           0 :             idxArr.push_back(idx);
     513             :         }
     514           0 :         j.pushKV(signature.ToString(), idxArr);
     515           0 :         quorumsCLSigsArr.push_back(j);
     516           0 :     }
     517           0 :     obj.pushKV("quorumsCLSigs", quorumsCLSigsArr);
     518           0 :     return obj;
     519           0 : }
     520             : 
     521         736 : RPCResult CSimplifiedMNListEntry::GetJsonHelp(const std::string& key, bool optional)
     522             : {
     523        1472 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The simplified masternode list entry",
     524       10304 :     {
     525         736 :         {RPCResult::Type::NUM, "nVersion", "Version of the entry"},
     526         736 :         GetRpcResult("type", /*optional=*/false, /*override_name=*/"nType"),
     527         736 :         {RPCResult::Type::STR_HEX, "proRegTxHash", "Hash of the ProRegTx identifying the masternode"},
     528         736 :         {RPCResult::Type::STR_HEX, "confirmedHash", "Hash of the block where the masternode was confirmed"},
     529         736 :         GetRpcResult("service", /*optional=*/true),
     530         736 :         GetRpcResult("addresses"),
     531         736 :         GetRpcResult("pubKeyOperator"),
     532         736 :         GetRpcResult("votingAddress"),
     533         736 :         {RPCResult::Type::BOOL, "isValid", "Returns true if the masternode is not Proof-of-Service banned"},
     534         736 :         GetRpcResult("platformHTTPPort", /*optional=*/true),
     535         736 :         GetRpcResult("platformNodeID", /*optional=*/true),
     536         736 :         GetRpcResult("payoutAddress", /*optional=*/true),
     537         736 :         GetRpcResult("operatorPayoutAddress", /*optional=*/true),
     538             :     }};
     539           0 : }
     540             : 
     541           0 : UniValue CSimplifiedMNListEntry::ToJson(bool extended) const
     542             : {
     543           0 :     UniValue obj(UniValue::VOBJ);
     544           0 :     obj.pushKV("nVersion", nVersion);
     545           0 :     obj.pushKV("nType", std23::to_underlying(nType));
     546           0 :     obj.pushKV("proRegTxHash", proRegTxHash.ToString());
     547           0 :     obj.pushKV("confirmedHash", confirmedHash.ToString());
     548           0 :     if (IsServiceDeprecatedRPCEnabled()) {
     549           0 :         obj.pushKV("service", GetDeprecatedServiceField(*this));
     550           0 :     }
     551           0 :     obj.pushKV("addresses", GetNetInfoWithLegacyFields(*this, nType));
     552           0 :     obj.pushKV("pubKeyOperator", pubKeyOperator.ToString());
     553           0 :     obj.pushKV("votingAddress", EncodeDestination(PKHash(keyIDVoting)));
     554           0 :     obj.pushKV("isValid", isValid);
     555           0 :     if (nType == MnType::Evo) {
     556           0 :         if (IsServiceDeprecatedRPCEnabled()) {
     557           0 :             obj.pushKV("platformHTTPPort", GetPlatformPort</*is_p2p=*/false>(*this));
     558           0 :         }
     559           0 :         obj.pushKV("platformNodeID", platformNodeID.ToString());
     560           0 :     }
     561             : 
     562           0 :     if (extended) {
     563           0 :         CTxDestination dest;
     564           0 :         if (ExtractDestination(scriptPayout, dest)) {
     565           0 :             obj.pushKV("payoutAddress", EncodeDestination(dest));
     566           0 :         }
     567           0 :         if (ExtractDestination(scriptOperatorPayout, dest)) {
     568           0 :             obj.pushKV("operatorPayoutAddress", EncodeDestination(dest));
     569           0 :         }
     570           0 :     }
     571           0 :     return obj;
     572           0 : }
     573             : 
     574         191 : RPCResult MNHFTx::GetJsonHelp(const std::string& key, bool optional)
     575             : {
     576         382 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The masternode hard fork payload",
     577         764 :     {
     578         191 :         {RPCResult::Type::NUM, "versionBit", "Version bit associated with the hard fork"},
     579         191 :         GetRpcResult("quorumHash"),
     580         191 :         {RPCResult::Type::STR_HEX, "sig", "BLS signature by a quorum public key"},
     581             :     }};
     582           0 : }
     583             : 
     584           0 : UniValue MNHFTx::ToJson() const
     585             : {
     586           0 :     UniValue obj(UniValue::VOBJ);
     587           0 :     obj.pushKV("versionBit", versionBit);
     588           0 :     obj.pushKV("quorumHash", quorumHash.ToString());
     589           0 :     obj.pushKV("sig", sig.ToString());
     590           0 :     return obj;
     591           0 : }
     592             : 
     593         191 : RPCResult MNHFTxPayload::GetJsonHelp(const std::string& key, bool optional)
     594             : {
     595         382 :     return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The masternode hard fork signal special transaction",
     596         573 :     {
     597         191 :         GetRpcResult("version"),
     598         191 :         MNHFTx::GetJsonHelp(/*key=*/"signal", /*optional=*/false),
     599             :     }};
     600           0 : }
     601             : 
     602           0 : UniValue MNHFTxPayload::ToJson() const
     603             : {
     604           0 :     UniValue ret(UniValue::VOBJ);
     605           0 :     ret.pushKV("version", nVersion);
     606           0 :     ret.pushKV("signal", signal.ToJson());
     607           0 :     return ret;
     608           0 : }

Generated by: LCOV version 1.16