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