|
| 1 | +// Copyright (c) 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 <governance/common.h> |
| 6 | +#include <governance/governance.h> |
| 7 | + |
| 8 | +#include <rpc/util.h> |
| 9 | +#include <util/check.h> |
| 10 | + |
| 11 | +#include <univalue.h> |
| 12 | + |
| 13 | +RPCResult CGovernanceManager::GetJsonHelp(const std::string& key, bool optional) |
| 14 | +{ |
| 15 | + return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "Count of governance objects and votes", |
| 16 | + { |
| 17 | + {RPCResult::Type::NUM, "objects_total", "Total number of all governance objects"}, |
| 18 | + {RPCResult::Type::NUM, "proposals", "Number of governance proposals"}, |
| 19 | + {RPCResult::Type::NUM, "triggers", "Number of triggers"}, |
| 20 | + {RPCResult::Type::NUM, "other", "Total number of unknown governance objects"}, |
| 21 | + {RPCResult::Type::NUM, "erased", "Number of removed (expired) objects"}, |
| 22 | + {RPCResult::Type::NUM, "votes", "Total number of votes"}, |
| 23 | + }}; |
| 24 | +} |
| 25 | + |
| 26 | +UniValue CGovernanceManager::ToJson() const |
| 27 | +{ |
| 28 | + LOCK(cs_store); |
| 29 | + |
| 30 | + int nProposalCount = 0; |
| 31 | + int nTriggerCount = 0; |
| 32 | + int nOtherCount = 0; |
| 33 | + |
| 34 | + for (const auto& [_, govobj] : mapObjects) { |
| 35 | + switch (Assert(govobj)->GetObjectType()) { |
| 36 | + case GovernanceObject::PROPOSAL: |
| 37 | + nProposalCount++; |
| 38 | + break; |
| 39 | + case GovernanceObject::TRIGGER: |
| 40 | + nTriggerCount++; |
| 41 | + break; |
| 42 | + default: |
| 43 | + nOtherCount++; |
| 44 | + break; |
| 45 | + } |
| 46 | + } |
| 47 | + |
| 48 | + UniValue jsonObj(UniValue::VOBJ); |
| 49 | + jsonObj.pushKV("objects_total", mapObjects.size()); |
| 50 | + jsonObj.pushKV("proposals", nProposalCount); |
| 51 | + jsonObj.pushKV("triggers", nTriggerCount); |
| 52 | + jsonObj.pushKV("other", nOtherCount); |
| 53 | + jsonObj.pushKV("erased", mapErasedGovernanceObjects.size()); |
| 54 | + jsonObj.pushKV("votes", cmapVoteToObject.GetSize()); |
| 55 | + return jsonObj; |
| 56 | +} |
| 57 | + |
| 58 | +RPCResult CGovernanceObject::GetInnerJsonHelp(const std::string& key, bool optional) |
| 59 | +{ |
| 60 | + return Governance::Object::GetJsonHelp(key, optional); |
| 61 | +} |
| 62 | + |
| 63 | +UniValue CGovernanceObject::GetInnerJson() const |
| 64 | +{ |
| 65 | + return m_obj.ToJson(); |
| 66 | +} |
| 67 | + |
| 68 | +// CGovernanceObject::GetStateJson() defined in governance/object.cpp |
| 69 | +RPCResult CGovernanceObject::GetStateJsonHelp(const std::string& key, bool optional, const std::string& local_valid_key) |
| 70 | +{ |
| 71 | + return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "Object state info", |
| 72 | + { |
| 73 | + {RPCResult::Type::STR_HEX, "DataHex", "Governance object (hex)"}, |
| 74 | + {RPCResult::Type::STR, "DataString", "Governance object (string)"}, |
| 75 | + {RPCResult::Type::STR_HEX, "Hash", "Hash of governance object"}, |
| 76 | + GetRpcResult("collateralHash", /*optional=*/false, /*override_name=*/"CollateralHash"), |
| 77 | + {RPCResult::Type::NUM, "ObjectType", "Object types"}, |
| 78 | + {RPCResult::Type::NUM, "CreationTime", "Object creation timestamp"}, |
| 79 | + {RPCResult::Type::STR_HEX, "SigningMasternode", /*optional=*/true, "Signing masternode’s vin (for triggers only)"}, |
| 80 | + {RPCResult::Type::BOOL, local_valid_key, "Returns true if valid"}, |
| 81 | + {RPCResult::Type::STR, "IsValidReason", strprintf("%s error (human-readable string, empty if %s true)", local_valid_key, local_valid_key)}, |
| 82 | + {RPCResult::Type::BOOL, "fCachedValid", "Returns true if minimum support has been reached flagging object as valid"}, |
| 83 | + {RPCResult::Type::BOOL, "fCachedFunding", "Returns true if minimum support has been reached flagging object as fundable"}, |
| 84 | + {RPCResult::Type::BOOL, "fCachedDelete", "Returns true if minimum support has been reached flagging object as marked for deletion"}, |
| 85 | + {RPCResult::Type::BOOL, "fCachedEndorsed", "Returns true if minimum support has been reached flagging object as endorsed"}, |
| 86 | + }}; |
| 87 | +} |
| 88 | + |
| 89 | +RPCResult CGovernanceObject::GetVotesJsonHelp(const std::string& key, bool optional) |
| 90 | +{ |
| 91 | + return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "Object vote counts", |
| 92 | + { |
| 93 | + {RPCResult::Type::NUM, "AbsoluteYesCount", "Number of Yes votes minus number of No votes"}, |
| 94 | + {RPCResult::Type::NUM, "YesCount", "Number of Yes votes"}, |
| 95 | + {RPCResult::Type::NUM, "NoCount", "Number of No votes"}, |
| 96 | + {RPCResult::Type::NUM, "AbstainCount", "Number of Abstain votes"}, |
| 97 | + }}; |
| 98 | +} |
| 99 | + |
| 100 | +UniValue CGovernanceObject::GetVotesJson(const CDeterministicMNList& tip_mn_list, vote_signal_enum_t signal) const |
| 101 | +{ |
| 102 | + UniValue obj(UniValue::VOBJ); |
| 103 | + obj.pushKV("AbsoluteYesCount", GetAbsoluteYesCount(tip_mn_list, signal)); |
| 104 | + obj.pushKV("YesCount", GetYesCount(tip_mn_list, signal)); |
| 105 | + obj.pushKV("NoCount", GetNoCount(tip_mn_list, signal)); |
| 106 | + obj.pushKV("AbstainCount", GetAbstainCount(tip_mn_list, signal)); |
| 107 | + return obj; |
| 108 | +} |
| 109 | + |
| 110 | +namespace Governance { |
| 111 | +RPCResult Object::GetJsonHelp(const std::string& key, bool optional) |
| 112 | +{ |
| 113 | + return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "Object info", |
| 114 | + { |
| 115 | + {RPCResult::Type::STR_HEX, "objectHash", "Hash of proposal object"}, |
| 116 | + {RPCResult::Type::STR_HEX, "parentHash", "Hash of the parent object (root node has a hash of 0)"}, |
| 117 | + GetRpcResult("collateralHash"), |
| 118 | + {RPCResult::Type::NUM, "createdAt", "Proposal creation timestamp"}, |
| 119 | + {RPCResult::Type::NUM, "revision", "Proposal revision number"}, |
| 120 | + {RPCResult::Type::OBJ, "data", "", { |
| 121 | + // Fields emitted through GetDataAsPlainString(), read by CProposalValidator |
| 122 | + {RPCResult::Type::STR, "end_epoch", /*optional=*/true, "Proposal end timestamp"}, |
| 123 | + {RPCResult::Type::STR, "name", /*optional=*/true, "Proposal name"}, |
| 124 | + {RPCResult::Type::STR, "payment_address", /*optional=*/true, "Proposal payment address"}, |
| 125 | + {RPCResult::Type::STR, "payment_amount", /*optional=*/true, "Proposal payment amount"}, |
| 126 | + {RPCResult::Type::STR, "start_epoch", /*optional=*/true, "Proposal start timestamp"}, |
| 127 | + {RPCResult::Type::STR, "type", /*optional=*/true, "Object type"}, |
| 128 | + {RPCResult::Type::STR, "url", /*optional=*/true, "Proposal URL"}, |
| 129 | + // Failure case for GetDataAsPlainString() |
| 130 | + {RPCResult::Type::STR, "plain", /*optional=*/true, "Governance object data as string"}, |
| 131 | + // Always emitted by ToJson() |
| 132 | + {RPCResult::Type::STR_HEX, "hex", "Governance object data as hex"}, |
| 133 | + }}, |
| 134 | + }}; |
| 135 | +} |
| 136 | + |
| 137 | +UniValue Object::ToJson() const |
| 138 | +{ |
| 139 | + UniValue obj(UniValue::VOBJ); |
| 140 | + obj.pushKV("objectHash", GetHash().ToString()); |
| 141 | + obj.pushKV("parentHash", hashParent.ToString()); |
| 142 | + obj.pushKV("collateralHash", collateralHash.ToString()); |
| 143 | + obj.pushKV("createdAt", time); |
| 144 | + obj.pushKV("revision", revision); |
| 145 | + UniValue data; |
| 146 | + if (!data.read(GetDataAsPlainString())) { |
| 147 | + data.clear(); |
| 148 | + data.setObject(); |
| 149 | + data.pushKV("plain", GetDataAsPlainString()); |
| 150 | + } |
| 151 | + data.pushKV("hex", GetDataAsHexString()); |
| 152 | + obj.pushKV("data", data); |
| 153 | + return obj; |
| 154 | +} |
| 155 | +} // namespace Governance |
0 commit comments