PIVX Core  5.6.99
P2P Digital Currency
rpcevo.cpp
Go to the documentation of this file.
1 // Copyright (c) 2018-2021 The Dash Core developers
2 // Copyright (c) 2021-2022 The PIVX Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "activemasternode.h"
7 #include "bls/key_io.h"
8 #include "bls/bls_wrapper.h"
9 #include "core_io.h"
10 #include "destination_io.h"
11 #include "evo/deterministicmns.h"
13 #include "evo/providertx.h"
14 #include "key_io.h"
15 #include "masternode.h"
16 #include "messagesigner.h"
17 #include "netbase.h"
18 #include "operationresult.h"
19 #include "policy/policy.h"
20 #include "pubkey.h" // COMPACT_SIGNATURE_SIZE
21 #include "rpc/server.h"
22 #include "script/sign.h"
24 #include "util/validation.h"
25 #include "utilmoneystr.h"
26 
27 #ifdef ENABLE_WALLET
28 #include "coincontrol.h"
29 #include "wallet/wallet.h"
30 #include "wallet/rpcwallet.h"
31 
32 extern void TryATMP(const CMutableTransaction& mtx, bool fOverrideFees);
33 extern void RelayTx(const uint256& hashTx);
34 #endif//ENABLE_WALLET
35 
56 };
57 
58 static const std::map<ProRegParam, std::string> mapParamHelp = {
60  "%d. \"collateralAddress\" (string, required) The PIVX address to send the collateral to.\n"
61  },
63  "%d. \"collateralHash\" (string, required) The collateral transaction hash.\n"
64  },
66  "%d. collateralIndex (numeric, required) The collateral transaction output index.\n"
67  },
69  "%d. \"ipAndPort\" (string, required) IP and port in the form \"IP:PORT\".\n"
70  " Must be unique on the network. Can be set to 0, which will require a ProUpServTx afterwards.\n"
71  },
73  "%d. \"ipAndPort\" (string, required) IP and port in the form \"IP:PORT\".\n"
74  " If set to an empty string, the currently active ip is reused.\n"
75  },
77  "%d. \"operatorPubKey\" (string, required) The operator BLS public key. The BLS private key does not have to be known.\n"
78  " It has to match the BLS private key which is later used when operating the masternode.\n"
79  },
81  "%d. \"operatorPubKey\" (string, required) The operator BLS public key. The BLS private key does not have to be known.\n"
82  " It has to match the BLS private key which is later used when operating the masternode.\n"
83  " If set to an empty string, the currently active operator BLS public key is reused.\n"
84  },
85  {operatorKey,
86  "%d. \"operatorKey\" (string, optional) The operator BLS private key associated with the\n"
87  " registered operator public key. If not specified, or set to an empty string, then this command must\n"
88  " be performed on the active masternode with the corresponding operator key.\n"
89  },
91  "%d. \"operatorPayoutAddress\" (string, optional) The address used for operator reward payments.\n"
92  " Only allowed when the ProRegTx had a non-zero operatorReward value.\n"
93  " If set to an empty string, the operatorPubKey is used.\n"
94  },
96  "%d. \"operatorPayoutAddress\" (string, optional) The address used for operator reward payments.\n"
97  " Only allowed when the ProRegTx had a non-zero operatorReward value.\n"
98  " If set to an empty string, the currently active one is reused.\n"
99  },
101  "%d. \"operatorReward\" (numeric, optional) The fraction in %% to share with the operator. The value must be\n"
102  " between 0.00 and 100.00. If not set, it takes the default value of 0.0\n"
103  },
104  {ownerAddress,
105  "%d. \"ownerAddress\" (string, required) The PIVX address to use for payee updates and proposal voting.\n"
106  " The private key belonging to this address must be known in your wallet, in order to send updates.\n"
107  " The address must not be already registered, and must differ from the collateralAddress\n"
108  },
109  {ownerKey,
110  "%d. \"ownerKey\" (string, optional) The owner key associated with the operator address of the masternode.\n"
111  " If not specified, or set to an empty string, then the mn key must be known by your wallet, in order to sign the tx.\n"
112  },
114  "%d. \"payoutAddress\" (string, required) The PIVX address to use for masternode reward payments.\n"
115  },
117  "%d. \"payoutAddress\" (string, required) The PIVX address to use for masternode reward payments.\n"
118  " If set to an empty string, the currently active payout address is reused.\n"
119  },
120  {proTxHash,
121  "%d. \"proTxHash\" (string, required) The hash of the initial ProRegTx.\n"
122  },
124  "%d. reason (numeric, optional) The reason for masternode service revocation. Default: 0.\n"
125  " 0=not_specified, 1=service_termination, 2=compromised_keys, 3=keys_change.\n"
126  },
128  "%d. \"votingAddress\" (string, required) The voting key address. The private key does not have to be known by your wallet.\n"
129  " It has to match the private key which is later used when voting on proposals.\n"
130  " If set to an empty string, ownerAddress will be used.\n"
131  },
133  "%d. \"votingAddress\" (string, required) The voting key address. The private key does not have to be known by your wallet.\n"
134  " It has to match the private key which is later used when voting on proposals.\n"
135  " If set to an empty string, the currently active voting key address is reused.\n"
136  },
137  };
138 
139 std::string GetHelpString(int nParamNum, ProRegParam p)
140 {
141  auto it = mapParamHelp.find(p);
142  if (it == mapParamHelp.end())
143  throw std::runtime_error(strprintf("FIXME: WRONG PARAM: %d!", (int)p));
144 
145  return strprintf(it->second, nParamNum);
146 }
147 
148 #ifdef ENABLE_WALLET
149 static CKey GetKeyFromWallet(CWallet* pwallet, const CKeyID& keyID)
150 {
151  assert(pwallet);
152  CKey key;
153  if (!pwallet->GetKey(keyID, key)) {
155  strprintf("key for address %s not in wallet", EncodeDestination(keyID)));
156  }
157  return key;
158 }
159 #endif
160 
161 static void CheckEvoUpgradeEnforcement()
162 {
163  const int nHeight = WITH_LOCK(cs_main, return chainActive.Height(); );
164  if (!Params().GetConsensus().NetworkUpgradeActive(nHeight, Consensus::UPGRADE_V6_0)) {
165  throw JSONRPCError(RPC_MISC_ERROR, "Evo upgrade is not active yet");
166  }
167 }
168 
169 // Allows to specify PIVX address or priv key (as strings). In case of PIVX address, the priv key is taken from the wallet
170 static CKey ParsePrivKey(CWallet* pwallet, const std::string &strKeyOrAddress, bool allowAddresses = true) {
171  bool isStaking{false}, isShield{false}, isExchange{false};
172  const CWDestination& cwdest = Standard::DecodeDestination(strKeyOrAddress, isStaking, isExchange, isShield);
173  if (isStaking) {
174  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "cold staking addresses not supported");
175  }
176  if (isShield) {
177  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "shield addresses not supported");
178  }
180  if (allowAddresses && IsValidDestination(*dest)) {
181 #ifdef ENABLE_WALLET
182  if (!pwallet) {
183  throw std::runtime_error("addresses not supported when wallet is disabled");
184  }
185  EnsureWalletIsUnlocked(pwallet);
186  const CKeyID* keyID = boost::get<CKeyID>(dest);
187  assert (keyID != nullptr); // we just checked IsValidDestination
188  return GetKeyFromWallet(pwallet, *keyID);
189 #else // ENABLE_WALLET
190  throw std::runtime_error("addresses not supported in no-wallet builds");
191 #endif // ENABLE_WALLET
192  }
193 
194  CKey key = KeyIO::DecodeSecret(strKeyOrAddress);
195  if (!key.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding");
196  return key;
197 }
198 
199 static CKeyID ParsePubKeyIDFromAddress(const std::string& strAddress)
200 {
201  bool isStaking{false}, isShield{false}, isExchange{false};
202  const CWDestination& cwdest = Standard::DecodeDestination(strAddress, isStaking, isExchange, isShield);
203  if (isStaking) {
204  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "cold staking addresses not supported");
205  }
206  if (isShield) {
207  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "shield addresses not supported");
208  }
209  const CKeyID* keyID = boost::get<CKeyID>(Standard::GetTransparentDestination(cwdest));
210  if (!keyID) {
211  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("invalid PIVX address %s", strAddress));
212  }
213  return *keyID;
214 }
215 
216 static CBLSPublicKey ParseBLSPubKey(const CChainParams& params, const std::string& strKey)
217 {
218  auto opKey = bls::DecodePublic(params, strKey);
219  if (!opKey) {
220  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("invalid BLS public key: %s", strKey));
221  }
222  return *opKey;
223 }
224 
225 static CBLSSecretKey ParseBLSSecretKey(const CChainParams& params, const std::string& strKey)
226 {
227  auto opKey = bls::DecodeSecret(params, strKey);
228  if (!opKey) {
229  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("invalid BLS secret key: %s", strKey));
230  }
231  return *opKey;
232 }
233 
234 static CBLSSecretKey GetBLSSecretKey(const CChainParams& params, const std::string& hexKey)
235 {
236  if (!hexKey.empty()) {
237  return ParseBLSSecretKey(params, hexKey);
238  }
239  // If empty, get the active masternode key
240  CBLSSecretKey sk; CTxIn vin;
241  if (!GetActiveDMNKeys(sk, vin)) {
242  throw JSONRPCError(RPC_INVALID_PARAMETER, "Active masternode key not found. Insert DMN operator private key.");
243  }
244  return sk;
245 }
246 
247 static UniValue DmnToJson(const CDeterministicMNCPtr dmn)
248 {
250  dmn->ToJson(ret);
251  Coin coin;
252  if (!WITH_LOCK(cs_main, return pcoinsTip->GetUTXOCoin(dmn->collateralOutpoint, coin); )) {
253  return ret;
254  }
255  CTxDestination dest;
256  if (!ExtractDestination(coin.out.scriptPubKey, dest)) {
257  return ret;
258  }
259  ret.pushKV("collateralAddress", EncodeDestination(dest));
260  return ret;
261 }
262 
263 #ifdef ENABLE_WALLET
264 
265 template<typename SpecialTxPayload>
266 static void FundSpecialTx(CWallet* pwallet, CMutableTransaction& tx, SpecialTxPayload& payload)
267 {
268  SetTxPayload(tx, payload);
269 
270  static CTxOut dummyTxOut(0, CScript() << OP_RETURN);
271  std::vector<CRecipient> vecSend;
272  bool dummyTxOutAdded = false;
273 
274  if (tx.vout.empty()) {
275  // add dummy txout as CreateTransaction requires at least one recipient
276  tx.vout.emplace_back(dummyTxOut);
277  dummyTxOutAdded = true;
278  }
279 
280  CAmount nFee;
281  CFeeRate feeRate = CFeeRate(0);
282  int nChangePos = -1;
283  std::string strFailReason;
284  std::set<int> setSubtractFeeFromOutputs;
285  if (!pwallet->FundTransaction(tx, nFee, false, feeRate, nChangePos, strFailReason, false, false, {}))
286  throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason);
287 
288  if (dummyTxOutAdded && tx.vout.size() > 1) {
289  // FundTransaction added a change output, so we don't need the dummy txout anymore
290  // Removing it results in slight overpayment of fees, but we ignore this for now (as it's a very low amount)
291  auto it = std::find(tx.vout.begin(), tx.vout.end(), dummyTxOut);
292  assert(it != tx.vout.end());
293  tx.vout.erase(it);
294  }
295 
296  UpdateSpecialTxInputsHash(tx, payload);
297 }
298 
299 #endif
300 
301 template<typename SpecialTxPayload>
302 static void UpdateSpecialTxInputsHash(const CMutableTransaction& tx, SpecialTxPayload& payload)
303 {
304  payload.inputsHash = CalcTxInputsHash(tx);
305 }
306 
307 template<typename SpecialTxPayload>
308 static void SignSpecialTxPayloadByHash(const CMutableTransaction& tx, SpecialTxPayload& payload, const CKey& key)
309 {
310  payload.vchSig.clear();
311 
312  uint256 hash = ::SerializeHash(payload);
313  if (!CHashSigner::SignHash(hash, key, payload.vchSig)) {
314  throw JSONRPCError(RPC_INTERNAL_ERROR, "failed to sign special tx payload");
315  }
316 }
317 
318 template<typename SpecialTxPayload>
319 static void SignSpecialTxPayloadByHash(const CMutableTransaction& tx, SpecialTxPayload& payload, const CBLSSecretKey& key)
320 {
321  payload.sig = key.Sign(::SerializeHash(payload));
322  if (!payload.sig.IsValid()) {
323  throw JSONRPCError(RPC_INTERNAL_ERROR, "failed to sign special tx payload");
324  }
325 }
326 
327 template<typename SpecialTxPayload>
328 static void SignSpecialTxPayloadByString(SpecialTxPayload& payload, const CKey& key)
329 {
330  payload.vchSig.clear();
331 
332  std::string m = payload.MakeSignString();
333  if (!CMessageSigner::SignMessage(m, payload.vchSig, key)) {
334  throw JSONRPCError(RPC_INTERNAL_ERROR, "failed to sign special tx payload");
335  }
336 }
337 
338 static std::string TxInErrorToString(int i, const CTxIn& txin, const std::string& strError)
339 {
340  return strprintf("Input %d (%s): %s", i, txin.prevout.ToStringShort(), strError);
341 }
342 
343 #ifdef ENABLE_WALLET
344 
345 static OperationResult SignTransaction(CWallet* const pwallet, CMutableTransaction& tx)
346 {
347  LOCK2(cs_main, pwallet->cs_wallet);
348  const CTransaction txConst(tx);
349  for (unsigned int i = 0; i < tx.vin.size(); i++) {
350  CTxIn& txin = tx.vin[i];
351  const Coin& coin = pcoinsTip->AccessCoin(txin.prevout);
352  if (coin.IsSpent()) {
353  return errorOut(TxInErrorToString(i, txin, "not found or already spent"));
354  }
356  txin.scriptSig.clear();
357  SignatureData sigdata;
359  coin.out.scriptPubKey, sigdata, sv, false)) {
360  return errorOut(TxInErrorToString(i, txin, "signature failed"));
361  }
362  UpdateTransaction(tx, i, sigdata);
363  }
364  return OperationResult(true);
365 }
366 
367 template<typename SpecialTxPayload>
368 static std::string SignAndSendSpecialTx(CWallet* const pwallet, CMutableTransaction& tx, const SpecialTxPayload& pl)
369 {
370  SetTxPayload(tx, pl);
371 
372  CValidationState state;
373  CCoinsViewCache view(pcoinsTip.get());
374  if (!WITH_LOCK(cs_main, return CheckSpecialTx(tx, GetChainTip(), &view, state); )) {
376  }
377 
378  const OperationResult& sigRes = SignTransaction(pwallet, tx);
379  if (!sigRes) {
380  throw JSONRPCError(RPC_INTERNAL_ERROR, sigRes.getError());
381  }
382 
383  TryATMP(tx, false);
384  const uint256& hashTx = tx.GetHash();
385  RelayTx(hashTx);
386  return hashTx.GetHex();
387 }
388 
389 // Parses inputs (starting from index paramIdx) and returns ProReg payload
390 static ProRegPL ParseProRegPLParams(const UniValue& params, unsigned int paramIdx)
391 {
392  assert(params.size() > paramIdx + 4);
393  assert(params.size() < paramIdx + 8);
394  const auto& chainparams = Params();
395  ProRegPL pl;
396 
397  // ip and port
398  const std::string& strIpPort = params[paramIdx].get_str();
399  if (!strIpPort.empty()) {
400  if (!Lookup(strIpPort, pl.addr, chainparams.GetDefaultPort(), false)) {
401  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("invalid network address %s", strIpPort));
402  }
403  }
404 
405  // addresses/keys
406  const std::string& strAddOwner = params[paramIdx + 1].get_str();
407  const std::string& strPubKeyOperator = params[paramIdx + 2].get_str();
408  const std::string& strAddVoting = params[paramIdx + 3].get_str();
409  pl.keyIDOwner = ParsePubKeyIDFromAddress(strAddOwner);
410  pl.pubKeyOperator = ParseBLSPubKey(chainparams, strPubKeyOperator);
411  pl.keyIDVoting = pl.keyIDOwner;
412  if (!strAddVoting.empty()) {
413  pl.keyIDVoting = ParsePubKeyIDFromAddress(strAddVoting);
414  }
415 
416  // payout script (!TODO: add support for P2CS)
417  const std::string& strAddPayee = params[paramIdx + 4].get_str();
418  pl.scriptPayout = GetScriptForDestination(CTxDestination(ParsePubKeyIDFromAddress(strAddPayee)));
419 
420  // operator reward
421  pl.nOperatorReward = 0;
422  if (params.size() > paramIdx + 5) {
423  int64_t operReward = 0;
424  if (!ParseFixedPoint(params[paramIdx + 5].getValStr(), 2, &operReward)) {
425  throw JSONRPCError(RPC_INVALID_PARAMETER, "operatorReward must be a number");
426  }
427  if (operReward < 0 || operReward > 10000) {
428  throw JSONRPCError(RPC_INVALID_PARAMETER, "operatorReward must be between 0.00 and 100.00");
429  }
430  pl.nOperatorReward = (uint16_t)operReward;
431  if (params.size() > paramIdx + 6) {
432  // operator reward payout script
433  const std::string& strAddOpPayee = params[paramIdx + 6].get_str();
434  if (pl.nOperatorReward > 0 && !strAddOpPayee.empty()) {
435  pl.scriptOperatorPayout = GetScriptForDestination(CTxDestination(ParsePubKeyIDFromAddress(strAddOpPayee)));
436  } else if (!strAddOpPayee.empty()) {
437  throw JSONRPCError(RPC_INVALID_PARAMETER, "operatorPayoutAddress must be empty when operatorReward is 0");
438  }
439  }
440  }
441  return pl;
442 }
443 
444 // handles protx_register, and protx_register_prepare
445 static UniValue ProTxRegister(const JSONRPCRequest& request, bool fSignAndSend)
446 {
447  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
448 
449  if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
450  return NullUniValue;
451 
452  if (request.fHelp || request.params.size() < 7 || request.params.size() > 9) {
453  throw std::runtime_error(
454  (fSignAndSend ?
455  "protx_register \"collateralHash\" collateralIndex \"ipAndPort\" \"ownerAddress\" \"operatorPubKey\" \"votingAddress\" \"payoutAddress\" (operatorReward \"operatorPayoutAddress\")\n"
456  "The collateral is specified through \"collateralHash\" and \"collateralIndex\" and must be an unspent\n"
457  "transaction output spendable by this wallet. It must also not be used by any other masternode.\n"
458  :
459  "protx_register_prepare \"collateralHash\" collateralIndex \"ipAndPort\" \"ownerAddress\" \"operatorPubKey\" \"votingAddress\" \"payoutAddress\" (operatorReward \"operatorPayoutAddress\")\n"
460  "\nCreates an unsigned ProTx and returns it. The ProTx must be signed externally with the collateral\n"
461  "key and then passed to \"protx_register_submit\".\n"
462  "The collateral is specified through \"collateralHash\" and \"collateralIndex\" and must be an unspent transaction output.\n"
463  )
464  + HelpRequiringPassphrase(pwallet) + "\n"
465  "\nArguments:\n"
475  "\nResult:\n" +
476  (fSignAndSend ? (
477  "\"txid\" (string) The transaction id.\n"
478  "\nExamples:\n"
479  + HelpExampleCli("protx_register", "\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\" 0 \"168.192.1.100:51472\" \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\" \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\" \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\" \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\"")
480  ) : (
481  "{ (json object)\n"
482  " \"tx\" : (string) The serialized ProTx in hex format.\n"
483  " \"collateralAddress\" : (string) The collateral address.\n"
484  " \"signMessage\" : (string) The string message that needs to be signed with the collateral key\n"
485  "}\n"
486  "\nExamples:\n"
487  + HelpExampleCli("protx_register_prepare", "\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\" 0 \"168.192.1.100:51472\" \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\" \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\" \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\" \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\"")
488  )
489  )
490  );
491  }
492  if (fSignAndSend) CheckEvoUpgradeEnforcement();
493 
494  EnsureWalletIsUnlocked(pwallet);
495  // Make sure the results are valid at least up to the most recent block
496  // the user could have gotten from another RPC command prior to now
498 
499  const uint256& collateralHash = ParseHashV(request.params[0], "collateralHash");
500  const int32_t collateralIndex = request.params[1].get_int();
501  if (collateralIndex < 0) {
502  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("invalid collateral index (negative): %d", collateralIndex));
503  }
504 
505  ProRegPL pl = ParseProRegPLParams(request.params, 2);
508 
511  tx.nType = CTransaction::TxType::PROREG;
512 
513  // referencing unspent collateral outpoint
514  Coin coin;
515  if (!WITH_LOCK(cs_main, return pcoinsTip->GetUTXOCoin(pl.collateralOutpoint, coin); )) {
516  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("collateral not found: %s-%d", collateralHash.ToString(), collateralIndex));
517  }
518  if (coin.out.nValue != Params().GetConsensus().nMNCollateralAmt) {
519  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("collateral %s-%d with invalid value %d", collateralHash.ToString(), collateralIndex, coin.out.nValue));
520  }
521  CTxDestination txDest;
522  ExtractDestination(coin.out.scriptPubKey, txDest);
523  const CKeyID* keyID = boost::get<CKeyID>(&txDest);
524  if (!keyID) {
525  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("collateral type not supported: %s-%d", collateralHash.ToString(), collateralIndex));
526  }
527  CKey keyCollateral;
528  if (fSignAndSend && !pwallet->GetKey(*keyID, keyCollateral)) {
529  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("collateral key not in wallet: %s", EncodeDestination(txDest)));
530  }
531 
532  // make sure fee calculation works
534 
535  FundSpecialTx(pwallet, tx, pl);
536 
537  if (fSignAndSend) {
538  SignSpecialTxPayloadByString(pl, keyCollateral); // prove we own the collateral
539  // check the payload, add the tx inputs sigs, and send the tx.
540  return SignAndSendSpecialTx(pwallet, tx, pl);
541  }
542  // external signing with collateral key
543  pl.vchSig.clear();
544  SetTxPayload(tx, pl);
546  ret.pushKV("tx", EncodeHexTx(tx));
547  ret.pushKV("collateralAddress", EncodeDestination(txDest));
548  ret.pushKV("signMessage", pl.MakeSignString());
549  return ret;
550 }
551 
552 UniValue protx_register(const JSONRPCRequest& request)
553 {
554  return ProTxRegister(request, true);
555 }
556 
557 UniValue protx_register_prepare(const JSONRPCRequest& request)
558 {
559  return ProTxRegister(request, false);
560 }
561 
562 UniValue protx_register_submit(const JSONRPCRequest& request)
563 {
564  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
565 
566  if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
567  return NullUniValue;
568 
569  if (request.fHelp || request.params.size() != 2) {
570  throw std::runtime_error(
571  "protx_register_submit \"tx\" \"sig\"\n"
572  "\nSubmits the specified ProTx to the network. This command will also sign the inputs of the transaction\n"
573  "which were previously added by \"protx_register_prepare\" to cover transaction fees\n"
574  + HelpRequiringPassphrase(pwallet) + "\n"
575  "\nArguments:\n"
576  "1. \"tx\" (string, required) The serialized transaction previously returned by \"protx_register_prepare\"\n"
577  "2. \"sig\" (string, required) The signature signed with the collateral key. Must be in base64 format.\n"
578  "\nResult:\n"
579  "\"txid\" (string) The transaction id.\n"
580  "\nExamples:\n"
581  + HelpExampleCli("protx_register_submit", "\"tx\" \"sig\"")
582  );
583  }
584  CheckEvoUpgradeEnforcement();
585 
586  EnsureWalletIsUnlocked(pwallet);
587  // Make sure the results are valid at least up to the most recent block
588  // the user could have gotten from another RPC command prior to now
590 
592  if (!DecodeHexTx(tx, request.params[0].get_str())) {
593  throw JSONRPCError(RPC_INVALID_PARAMETER, "transaction not deserializable");
594  }
595  if (tx.nType != CTransaction::TxType::PROREG) {
596  throw JSONRPCError(RPC_INVALID_PARAMETER, "transaction not a ProRegTx");
597  }
598  ProRegPL pl;
599  if (!GetTxPayload(tx, pl)) {
600  throw JSONRPCError(RPC_INVALID_PARAMETER, "transaction payload not deserializable");
601  }
602  if (!pl.vchSig.empty()) {
603  throw JSONRPCError(RPC_INVALID_PARAMETER, "payload signature not empty");
604  }
605 
606  pl.vchSig = DecodeBase64(request.params[1].get_str().c_str());
607 
608  // check the payload, add the tx inputs sigs, and send the tx.
609  return SignAndSendSpecialTx(pwallet, tx, pl);
610 }
611 
612 UniValue protx_register_fund(const JSONRPCRequest& request)
613 {
614  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
615 
616  if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
617  return NullUniValue;
618 
619  if (request.fHelp || request.params.size() < 6 || request.params.size() > 8) {
620  throw std::runtime_error(
621  "protx_register_fund \"collateralAddress\" \"ipAndPort\" \"ownerAddress\" \"operatorPubKey\" \"votingAddress\" \"payoutAddress\" (operatorReward \"operatorPayoutAddress\")\n"
622  "\nCreates, funds and sends a ProTx to the network. The resulting transaction will move 10000 PIV\n"
623  "to the address specified by collateralAddress and will then function as masternode collateral.\n"
624  + HelpRequiringPassphrase(pwallet) + "\n"
625  "\nArguments:\n"
634  "\nResult:\n"
635  "\"txid\" (string) The transaction id.\n"
636  "\nExamples:\n"
637  + HelpExampleCli("protx_register_fund", "\"DKHHBsuU9zfxxxVaqqqQqK4MxZg6vzpf8\" \"168.192.1.100:51472\" \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\" \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\" \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\" \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\"")
638  );
639  }
640  CheckEvoUpgradeEnforcement();
641 
642  EnsureWalletIsUnlocked(pwallet);
643  // Make sure the results are valid at least up to the most recent block
644  // the user could have gotten from another RPC command prior to now
646 
647  const CTxDestination& collateralDest(ParsePubKeyIDFromAddress(request.params[0].get_str()));
648  const CScript& collateralScript = GetScriptForDestination(collateralDest);
649  const CAmount collAmt = Params().GetConsensus().nMNCollateralAmt;
650 
651  ProRegPL pl = ParseProRegPLParams(request.params, 1);
653 
656  tx.nType = CTransaction::TxType::PROREG;
657  tx.vout.emplace_back(collAmt, collateralScript);
658 
659  FundSpecialTx(pwallet, tx, pl);
660 
661  for (uint32_t i = 0; i < tx.vout.size(); i++) {
662  if (tx.vout[i].nValue == collAmt && tx.vout[i].scriptPubKey == collateralScript) {
663  pl.collateralOutpoint.n = i;
664  break;
665  }
666  }
667  assert(pl.collateralOutpoint.n != (uint32_t) -1);
668  // update payload on tx (with final collateral outpoint)
669  pl.vchSig.clear();
670  // check the payload, add the tx inputs sigs, and send the tx.
671  return SignAndSendSpecialTx(pwallet, tx, pl);
672 }
673 
674 #endif //ENABLE_WALLET
675 
676 static bool CheckWalletOwnsScript(CWallet* pwallet, const CScript& script)
677 {
678 #ifdef ENABLE_WALLET
679  if (!pwallet)
680  return false;
681  AssertLockHeld(pwallet->cs_wallet);
682  CTxDestination dest;
683  if (ExtractDestination(script, dest)) {
684  const CKeyID* keyID = boost::get<CKeyID>(&dest);
685  if (keyID && pwallet->HaveKey(*keyID))
686  return true;
687  const CScriptID* scriptID = boost::get<CScriptID>(&dest);
688  if (scriptID && pwallet->HaveCScript(*scriptID))
689  return true;
690  }
691  return false;
692 #else
693  return false;
694 #endif
695 }
696 
697 static UniValue ToJson(const CMasternodeMetaInfoPtr& info)
698 {
700  auto now = GetAdjustedTime();
701  auto lastAttempt = info->GetLastOutboundAttempt();
702  auto lastSuccess = info->GetLastOutboundSuccess();
703  ret.pushKV("last_outbound_attempt", lastAttempt);
704  ret.pushKV("last_outbound_attempt_elapsed", now - lastAttempt);
705  ret.pushKV("last_outbound_success", lastSuccess);
706  ret.pushKV("last_outbound_success_elapsed", now - lastSuccess);
707  return ret;
708 }
709 
710 static void AddDMNEntryToList(UniValue& ret, CWallet* pwallet, const CDeterministicMNCPtr& dmn, bool fVerbose, bool fFromWallet)
711 {
712  assert(!fFromWallet || pwallet);
713  assert(ret.isArray());
714 
715  bool hasOwnerKey{false};
716  bool hasVotingKey{false};
717  bool ownsCollateral{false};
718  bool ownsPayeeScript{false};
719 
720  // No need to check wallet if not wallet_only and not verbose
721  bool skipWalletCheck = !fFromWallet && !fVerbose;
722 
723  if (pwallet && !skipWalletCheck) {
724  LOCK(pwallet->cs_wallet);
725  hasOwnerKey = pwallet->HaveKey(dmn->pdmnState->keyIDOwner);
726  hasVotingKey = pwallet->HaveKey(dmn->pdmnState->keyIDVoting);
727  ownsPayeeScript = CheckWalletOwnsScript(pwallet, dmn->pdmnState->scriptPayout);
728  CTransactionRef collTx;
729  uint256 hashBlock;
730  if (GetTransaction(dmn->collateralOutpoint.hash, collTx, hashBlock, true)) {
731  ownsCollateral = CheckWalletOwnsScript(pwallet, collTx->vout[dmn->collateralOutpoint.n].scriptPubKey);
732  }
733  }
734 
735  if (fFromWallet && !hasOwnerKey && !hasVotingKey && !ownsCollateral && !ownsPayeeScript) {
736  // not one of ours
737  return;
738  }
739 
740  if (fVerbose) {
741  UniValue o = DmnToJson(dmn);
742  int confs = WITH_LOCK(cs_main, return pcoinsTip->GetCoinDepthAtHeight(dmn->collateralOutpoint, chainActive.Height()); );
743  o.pushKV("confirmations", confs);
744  o.pushKV("has_owner_key", hasOwnerKey);
745  o.pushKV("has_voting_key", hasVotingKey);
746  o.pushKV("owns_collateral", ownsCollateral);
747  o.pushKV("owns_payee_script", ownsPayeeScript);
748  // net info
749  auto metaInfo = g_mmetaman.GetMetaInfo(dmn->proTxHash);
750  if (metaInfo) o.pushKV("metaInfo", ToJson(metaInfo));
751  ret.push_back(o);
752  } else {
753  ret.push_back(dmn->proTxHash.ToString());
754  }
755 }
756 
758 {
759  if (request.fHelp || request.params.size() > 4) {
760  throw std::runtime_error(
761  "protx_list (detailed wallet_only valid_only height)\n"
762  "\nLists all ProTxs.\n"
763  "\nArguments:\n"
764  "1. \"detailed\" (bool, optional, default=true) Return detailed information about each protx.\n"
765  " If set to false, return only the list of txids.\n"
766  "2. \"wallet_only\" (bool, optional, default=false) If set to true, return only protx which involves\n"
767  " keys from this wallet (collateral, owner, operator, voting, or payout addresses).\n"
768  "3. \"valid_only\" (bool, optional, default=false) If set to true, return only ProTx which are active/valid\n"
769  " at the height specified.\n"
770  "4. \"height\" (numeric, optional) If height is not specified, it defaults to the current chain-tip.\n"
771  "\nResult:\n"
772  "[...] (list) List of protx txids or, if detailed=true, list of json objects.\n"
773  "\nExamples:\n"
774  + HelpExampleCli("protx_list", "")
775  + HelpExampleCli("protx_list", "true false false 200000")
776  );
777  }
778 
779  CheckEvoUpgradeEnforcement();
780 
781 #ifdef ENABLE_WALLET
782  CWallet* const pwallet = GetWalletForJSONRPCRequest(request);
783 #else
784  CWallet* const pwallet = nullptr;
785 #endif
786 
787  const bool fVerbose = (request.params.size() == 0 || request.params[0].get_bool());
788  const bool fFromWallet = (request.params.size() > 1 && request.params[1].get_bool());
789  const bool fValidOnly = (request.params.size() > 2 && request.params[2].get_bool());
790 
791  if (fFromWallet && !pwallet) {
792  throw JSONRPCError(RPC_INVALID_PARAMETER, "wallet_only not supported when wallet is disabled");
793  }
794 
795  // Get a reference to the block index at the specified height (or at the chain tip)
796  const CBlockIndex* pindex;
797  {
798  LOCK(cs_main);
799  const CBlockIndex* pindexTip = chainActive.Tip();
800  if (request.params.size() > 3) {
801  const int height = request.params[3].get_int();
802  if (height <= 0 || height > pindexTip->nHeight) {
803  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("height must be between 1 and %d", pindexTip->nHeight));
804  }
805  pindexTip = chainActive[height];
806  }
807  pindex = mapBlockIndex.at(pindexTip->GetBlockHash());
808  }
809 
810  // Get the deterministic mn list at the index
811  CDeterministicMNList mnList = deterministicMNManager->GetListForBlock(pindex);
812 
813  // Build/filter the list
815  mnList.ForEachMN(fValidOnly, [&](const CDeterministicMNCPtr& dmn) {
816  AddDMNEntryToList(ret, pwallet, dmn, fVerbose, fFromWallet);
817  });
818  return ret;
819 }
820 
821 #ifdef ENABLE_WALLET
822 UniValue protx_update_service(const JSONRPCRequest& request)
823 {
824  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
825 
826  if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
827  return NullUniValue;
828 
829  if (request.fHelp || request.params.size() < 2 || request.params.size() > 4) {
830  throw std::runtime_error(
831  "protx_update_service \"proTxHash\" \"ipAndPort\" (\"operatorPayoutAddress\" \"operatorKey\")\n"
832  "\nCreates and sends a ProUpServTx to the network. This will update the IP address\n"
833  "of a masternode, and/or the operator payout address.\n"
834  "If the IP is changed for a masternode that got PoSe-banned, the ProUpServTx will also revive this masternode.\n"
835  + HelpRequiringPassphrase(pwallet) + "\n"
836  "\nArguments:\n"
840  + GetHelpString(4, operatorKey) +
841  "\nResult:\n"
842  "\"txid\" (string) The transaction id.\n"
843  "\nExamples:\n"
844  + HelpExampleCli("protx_update_service", "\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\" \"168.192.1.100:51472\"")
845  );
846  }
847  CheckEvoUpgradeEnforcement();
848 
849  EnsureWalletIsUnlocked(pwallet);
850  // Make sure the results are valid at least up to the most recent block
851  // the user could have gotten from another RPC command prior to now
853 
854  ProUpServPL pl;
856  pl.proTxHash = ParseHashV(request.params[0], "proTxHash");
857 
858  auto dmn = deterministicMNManager->GetListAtChainTip().GetMN(pl.proTxHash);
859  if (!dmn) {
860  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("masternode with hash %s not found", pl.proTxHash.ToString()));
861  }
862  const auto& chainparams = Params();
863  const std::string& addrStr = request.params[1].get_str();
864  if (!addrStr.empty()) {
865  if (!Lookup(addrStr.c_str(), pl.addr, chainparams.GetDefaultPort(), false)) {
866  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("invalid network address %s", addrStr));
867  }
868  } else {
869  pl.addr = dmn->pdmnState->addr;
870  }
871  pl.scriptOperatorPayout = dmn->pdmnState->scriptOperatorPayout;
872  if (request.params.size() > 2) {
873  const std::string& strAddOpPayee = request.params[2].get_str();
874  if (!strAddOpPayee.empty()) {
875  if (dmn->nOperatorReward > 0) {
876  pl.scriptOperatorPayout = GetScriptForDestination(CTxDestination(ParsePubKeyIDFromAddress(strAddOpPayee)));
877  } else {
878  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Operator reward is 0. Cannot set operator payout address"));
879  }
880  }
881  }
882 
883  const std::string& strOpKey = request.params.size() > 3 ? request.params[3].get_str() : "";
884  const CBLSSecretKey& operatorKey = GetBLSSecretKey(chainparams, strOpKey);
885 
888  tx.nType = CTransaction::TxType::PROUPSERV;
889 
890  FundSpecialTx(pwallet, tx, pl);
891  SignSpecialTxPayloadByHash(tx, pl, operatorKey);
892 
893  return SignAndSendSpecialTx(pwallet, tx, pl);
894 }
895 
896 UniValue protx_update_registrar(const JSONRPCRequest& request)
897 {
898  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
899 
900  if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
901  return NullUniValue;
902 
903  if (request.fHelp || request.params.size() < 4 || request.params.size() > 5) {
904  throw std::runtime_error(
905  "protx update_registrar \"proTxHash\" \"operatorPubKey\" \"votingAddress\" \"payoutAddress\" (\"ownerKey\")\n"
906  "\nCreates and sends a ProUpRegTx to the network. This will update the operator key, voting key and payout\n"
907  "address of the masternode specified by \"proTxHash\".\n"
908  "The owner key of this masternode must be known to your wallet.\n"
909  + HelpRequiringPassphrase(pwallet) + "\n"
910  "\nArguments:\n"
915  + GetHelpString(5, ownerKey) +
916  "\nResult:\n"
917  "\"txid\" (string) The transaction id.\n"
918  "\nExamples:\n"
919  + HelpExampleCli("protx_update_registrar", "\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\" \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\" \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\" \"DMJRSsuU9zfyrvxVaAEFQqK4MxZg6vgeS6\"")
920  );
921  }
922  CheckEvoUpgradeEnforcement();
923 
924  if (!deterministicMNManager->LegacyMNObsolete()) {
925  throw JSONRPCError(RPC_MISC_ERROR, "Legacy masternode system still active. ProUpReg transactions are not accepted yet.");
926  }
927 
928  EnsureWalletIsUnlocked(pwallet);
929  // Make sure the results are valid at least up to the most recent block
930  // the user could have gotten from another RPC command prior to now
932  const auto& chainparams = Params();
933 
934  ProUpRegPL pl;
936  pl.proTxHash = ParseHashV(request.params[0], "proTxHash");
937 
938  auto dmn = deterministicMNManager->GetListAtChainTip().GetMN(pl.proTxHash);
939  if (!dmn) {
940  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("masternode with hash %s not found", pl.proTxHash.ToString()));
941  }
942  const std::string& strPubKeyOperator = request.params[1].get_str();
943  pl.pubKeyOperator = strPubKeyOperator.empty() ? dmn->pdmnState->pubKeyOperator.Get()
944  : ParseBLSPubKey(chainparams, strPubKeyOperator);
945 
946  const std::string& strVotingAddress = request.params[2].get_str();
947  pl.keyIDVoting = strVotingAddress.empty() ? dmn->pdmnState->keyIDVoting
948  : ParsePubKeyIDFromAddress(strVotingAddress);
949 
950  const std::string& strPayee = request.params[3].get_str();
951  pl.scriptPayout = strPayee.empty() ? pl.scriptPayout = dmn->pdmnState->scriptPayout
952  : GetScriptForDestination(CTxDestination(ParsePubKeyIDFromAddress(strPayee)));
953 
954  const std::string& strOwnKey = request.params.size() > 4 ? request.params[4].get_str() : "";
955  const CKey& ownerKey = strOwnKey.empty() ? GetKeyFromWallet(pwallet, dmn->pdmnState->keyIDOwner)
956  : ParsePrivKey(pwallet, strOwnKey, false);
957 
960  tx.nType = CTransaction::TxType::PROUPREG;
961 
962  // make sure fee calculation works
964  FundSpecialTx(pwallet, tx, pl);
965  SignSpecialTxPayloadByHash(tx, pl, ownerKey);
966 
967  return SignAndSendSpecialTx(pwallet, tx, pl);
968 }
969 
970 UniValue protx_revoke(const JSONRPCRequest& request)
971 {
972  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
973 
974  if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
975  return NullUniValue;
976 
977  if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) {
978  throw std::runtime_error(
979  "protx_update_revoke \"proTxHash\" (\"operatorKey\" reason)\n"
980  "\nCreates and sends a ProUpRevTx to the network. This will revoke the operator key of the masternode and\n"
981  "put it into the PoSe-banned state. It will also set the service field of the masternode\n"
982  "to zero. Use this in case your operator key got compromised or you want to stop providing your service\n"
983  "to the masternode owner.\n"
984  + HelpRequiringPassphrase(pwallet) + "\n"
985  "\nArguments:\n"
989  "\nResult:\n"
990  "\"txid\" (string) The transaction id.\n"
991  "\nExamples:\n"
992  + HelpExampleCli("protx_revoke", "\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"")
993  + HelpExampleCli("protx_revoke", "\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\" \"\" 2")
994  );
995  }
996  CheckEvoUpgradeEnforcement();
997 
998  EnsureWalletIsUnlocked(pwallet);
999  // Make sure the results are valid at least up to the most recent block
1000  // the user could have gotten from another RPC command prior to now
1001  pwallet->BlockUntilSyncedToCurrentChain();
1002  const auto& chainparams = Params();
1003 
1004  ProUpRevPL pl;
1006  pl.proTxHash = ParseHashV(request.params[0], "proTxHash");
1007 
1008  auto dmn = deterministicMNManager->GetListAtChainTip().GetMN(pl.proTxHash);
1009  if (!dmn) {
1010  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("masternode with hash %s not found", pl.proTxHash.ToString()));
1011  }
1012 
1013  const std::string& strOpKey = request.params.size() > 1 ? request.params[1].get_str() : "";
1014  const CBLSSecretKey& operatorKey = GetBLSSecretKey(chainparams, strOpKey);
1015 
1016  pl.nReason = ProUpRevPL::RevocationReason::REASON_NOT_SPECIFIED;
1017  if (request.params.size() > 2) {
1018  int nReason = request.params[2].get_int();
1019  if (nReason < 0 || nReason > ProUpRevPL::RevocationReason::REASON_LAST) {
1020  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("invalid reason %d, must be between 0 and %d",
1021  nReason, ProUpRevPL::RevocationReason::REASON_LAST));
1022  }
1023  pl.nReason = (uint16_t)nReason;
1024  }
1025 
1028  tx.nType = CTransaction::TxType::PROUPREV;
1029 
1030  FundSpecialTx(pwallet, tx, pl);
1031  SignSpecialTxPayloadByHash(tx, pl, operatorKey);
1032 
1033  return SignAndSendSpecialTx(pwallet, tx, pl);
1034 }
1035 #endif
1036 
1038 {
1039  if (request.fHelp || !request.params.empty()) {
1040  throw std::runtime_error(
1041  "generateblskeypair\n"
1042  "\nReturns a BLS secret/public key pair.\n"
1043  "\nResult:\n"
1044  "{\n"
1045  " \"secret\": \"xxxx\", (string) BLS secret key\n"
1046  " \"public\": \"xxxx\", (string) BLS public key\n"
1047  "}\n"
1048  "\nExamples:\n"
1049  + HelpExampleCli("generateblskeypair", "")
1050  + HelpExampleRpc("generateblskeypair", "")
1051  );
1052  }
1053 
1054  const auto& params = Params();
1055  CBLSSecretKey sk;
1056  sk.MakeNewKey();
1057  UniValue ret(UniValue::VOBJ);
1058  ret.pushKV("secret", bls::EncodeSecret(params, sk));
1059  ret.pushKV("public", bls::EncodePublic(params, sk.GetPublicKey()));
1060  return ret;
1061 }
1062 
1063 // clang-format off
1064 static const CRPCCommand commands[] =
1065 { // category name actor (function) okSafe argNames
1066  // -------------- --------------------------------- ------------------------ ------ --------
1067  { "evo", "generateblskeypair", &generateblskeypair, true, {} },
1068  { "evo", "protx_list", &protx_list, true, {"detailed","wallet_only","valid_only","height"} },
1069 #ifdef ENABLE_WALLET
1070  { "evo", "protx_register", &protx_register, true, {"collateralHash","collateralIndex","ipAndPort","ownerAddress","operatorPubKey","votingAddress","payoutAddress","operatorReward","operatorPayoutAddress"} },
1071  { "evo", "protx_register_fund", &protx_register_fund, true, {"collateralAddress","ipAndPort","ownerAddress","operatorPubKey","votingAddress","payoutAddress","operatorReward","operatorPayoutAddress"} },
1072  { "evo", "protx_register_prepare", &protx_register_prepare, true, {"collateralHash","collateralIndex","ipAndPort","ownerAddress","operatorPubKey","votingAddress","payoutAddress","operatorReward","operatorPayoutAddress"} },
1073  { "evo", "protx_register_submit", &protx_register_submit, true, {"tx","sig"} },
1074  { "evo", "protx_revoke", &protx_revoke, true, {"proTxHash","operatorKey","reason"} },
1075  { "evo", "protx_update_registrar", &protx_update_registrar, true, {"proTxHash","operatorPubKey","votingAddress","payoutAddress","ownerKey"} },
1076  { "evo", "protx_update_service", &protx_update_service, true, {"proTxHash","ipAndPort","operatorPayoutAddress","operatorKey"} },
1077 #endif //ENABLE_WALLET
1078 };
1079 // clang-format on
1080 
1082 {
1083  for (const auto& command : commands) {
1084  _tableRPC.appendCommand(command.name, &command);
1085  }
1086 }
bool GetActiveDMNKeys(CBLSSecretKey &key, CTxIn &vin)
int64_t CAmount
Amount in PIV (Can be negative)
Definition: amount.h:13
false
Definition: bls_dkg.cpp:151
const CChainParams & Params()
Return the currently selected parameters.
std::string ToStringShort() const
Definition: transaction.cpp:13
uint32_t n
Definition: transaction.h:36
void MakeNewKey()
Definition: bls_wrapper.cpp:54
CBLSPublicKey GetPublicKey() const
Definition: bls_wrapper.cpp:99
CBLSSignature Sign(const uint256 &hash) const
virtual bool HaveCScript(const CScriptID &hash) const
Definition: keystore.cpp:51
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:139
uint256 GetBlockHash() const
Definition: chain.h:215
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:151
CBlockIndex * Tip(bool fProofOfStake=false) const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:405
int Height() const
Return the maximal height in the chain.
Definition: chain.h:450
CChainParams defines various tweakable parameters of a given instance of the PIVX system.
Definition: chainparams.h:43
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:72
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:283
bool GetKey(const CKeyID &address, CKey &keyOut) const override
Definition: crypter.cpp:199
bool HaveKey(const CKeyID &address) const override
Check whether a key corresponding to a given address is present in the store.
Definition: crypter.cpp:179
void ForEachMN(bool onlyValid, Callback &&cb) const
Fee rate in PIV per kilobyte: CAmount / kB.
Definition: feerate.h:20
static bool SignHash(const uint256 &hash, const CKey &key, std::vector< unsigned char > &vchSigRet)
Sign the hash, returns true if successful.
An encapsulated private key.
Definition: key.h:30
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:95
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:21
CMasternodeMetaInfoPtr GetMetaInfo(const uint256 &proTxHash, bool fCreate=true)
static bool SignMessage(const std::string &strMessage, std::vector< unsigned char > &vchSigRet, const CKey &key)
Sign the message, returns true if successful.
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:72
static constexpr unsigned int COMPACT_SIGNATURE_SIZE
Definition: pubkey.h:52
PIVX RPC command dispatcher.
Definition: server.h:147
bool appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:314
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:381
void clear()
Definition: script.h:659
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: standard.h:24
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:244
An input of a transaction.
Definition: transaction.h:94
CScript scriptSig
Definition: transaction.h:97
COutPoint prevout
Definition: transaction.h:96
An output of a transaction.
Definition: transaction.h:137
CScript scriptPubKey
Definition: transaction.h:140
CAmount nValue
Definition: transaction.h:139
Capture information about block/transaction validation.
Definition: validation.h:24
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,...
Definition: wallet.h:577
RecursiveMutex cs_wallet
Definition: wallet.h:720
A UTXO entry.
Definition: coins.h:32
CTxOut out
unspent transaction output
Definition: coins.h:41
bool IsSpent() const
Definition: coins.h:86
UniValue params
Definition: server.h:47
bool fHelp
Definition: server.h:48
std::string getError() const
static const uint16_t CURRENT_VERSION
Definition: providertx.h:22
CScript scriptOperatorPayout
Definition: providertx.h:36
CKeyID keyIDVoting
Definition: providertx.h:33
COutPoint collateralOutpoint
Definition: providertx.h:29
uint16_t nVersion
Definition: providertx.h:26
uint16_t nOperatorReward
Definition: providertx.h:35
CScript scriptPayout
Definition: providertx.h:34
CBLSPublicKey pubKeyOperator
Definition: providertx.h:32
std::vector< unsigned char > vchSig
Definition: providertx.h:38
std::string MakeSignString() const
Definition: providertx.cpp:11
CKeyID keyIDOwner
Definition: providertx.h:31
CService addr
Definition: providertx.h:30
CKeyID keyIDVoting
Definition: providertx.h:113
CScript scriptPayout
Definition: providertx.h:114
uint16_t nVersion
Definition: providertx.h:109
uint256 proTxHash
Definition: providertx.h:110
std::vector< unsigned char > vchSig
Definition: providertx.h:116
CBLSPublicKey pubKeyOperator
Definition: providertx.h:112
uint16_t nReason
Definition: providertx.h:152
uint256 proTxHash
Definition: providertx.h:151
uint16_t nVersion
Definition: providertx.h:150
uint16_t nVersion
Definition: providertx.h:79
CService addr
Definition: providertx.h:81
static const uint16_t CURRENT_VERSION
Definition: providertx.h:75
uint256 proTxHash
Definition: providertx.h:80
CScript scriptOperatorPayout
Definition: providertx.h:82
const std::string & get_str() const
bool isArray() const
Definition: univalue.h:83
@ VOBJ
Definition: univalue.h:21
@ VARR
Definition: univalue.h:21
size_t size() const
Definition: univalue.h:68
bool empty() const
Definition: univalue.h:66
bool push_back(const UniValue &val)
Definition: univalue.cpp:108
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:133
bool get_bool() const
int get_int() const
std::string ToString() const
Definition: uint256.cpp:65
std::string GetHex() const
Definition: uint256.cpp:21
bool empty() const
Definition: prevector.h:281
256-bit opaque blob.
Definition: uint256.h:138
std::string EncodeHexTx(const CTransaction &tx)
Definition: core_write.cpp:116
bool DecodeHexTx(CMutableTransaction &tx, const std::string &strHexTx)
Definition: core_read.cpp:77
boost::variant< CTxDestination, libzcash::SaplingPaymentAddress > CWDestination
std::unique_ptr< CDeterministicMNManager > deterministicMNManager
std::shared_ptr< const CDeterministicMN > CDeterministicMNCPtr
bool FundTransaction(CMutableTransaction &tx, CAmount &nFeeRet, bool overrideEstimatedFeeRate, const CFeeRate &specificFeeRate, int &nChangePosInOut, std::string &strFailReason, bool includeWatching, bool lockUnspents, const std::set< int > &setSubtractFeeFromOutputs, const CTxDestination &destChange=CNoDestination())
Definition: wallet.cpp:2965
void BlockUntilSyncedToCurrentChain()
Blocks until the wallet state is up-to-date to /at least/ the current chain at the time this function...
Definition: wallet.cpp:1383
uint256 SerializeHash(const T &obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
Compute the 256-bit hash of an object's serialization.
Definition: hash.h:289
@ SIGHASH_ALL
Definition: interpreter.h:24
@ LOCK
Definition: lockunlock.h:16
CMasternodeMetaMan g_mmetaman
std::shared_ptr< CMasternodeMetaInfo > CMasternodeMetaInfoPtr
@ SAPLING
Definition: logging.h:63
@ UPGRADE_V6_0
Definition: params.h:41
CKey DecodeSecret(const std::string &str)
Definition: key_io.cpp:127
const CTxDestination * GetTransparentDestination(const CWDestination &dest)
bool IsValidDestination(const CWDestination &address)
std::string EncodeDestination(const CWDestination &address, const CChainParams::Base58Type addrType)
CWDestination DecodeDestination(const std::string &strAddress)
Optional< CBLSSecretKey > DecodeSecret(const CChainParams &params, const std::string &keyStr)
Definition: key_io.cpp:63
std::string EncodeSecret(const CChainParams &params, const CBLSSecretKey &key)
Definition: key_io.cpp:50
Optional< CBLSPublicKey > DecodePublic(const CChainParams &params, const std::string &keyStr)
Definition: key_io.cpp:68
std::string EncodePublic(const CChainParams &params, const CBLSPublicKey &pk)
Definition: key_io.cpp:55
RecursiveMutex cs_main
Global state.
Definition: validation.cpp:80
bool Lookup(const std::string &name, std::vector< CService > &vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
Definition: netbase.cpp:177
OperationResult errorOut(const std::string &errorStr)
void TryATMP(const CMutableTransaction &mtx, bool fOverrideFees)
void RelayTx(const uint256 &hashTx)
UniValue JSONRPCError(int code, const std::string &message)
Definition: protocol.cpp:53
@ RPC_MISC_ERROR
General application defined errors.
Definition: protocol.h:41
@ RPC_INVALID_PARAMETER
Ran out of memory during operation.
Definition: protocol.h:46
@ RPC_INTERNAL_ERROR
Definition: protocol.h:37
@ RPC_INVALID_ADDRESS_OR_KEY
Unexpected type was passed as parameter.
Definition: protocol.h:44
UniValue generateblskeypair(const JSONRPCRequest &request)
Definition: rpcevo.cpp:1037
ProRegParam
Definition: rpcevo.cpp:36
@ ownerAddress
Definition: rpcevo.cpp:48
@ operatorKey
Definition: rpcevo.cpp:47
@ payoutAddress_register
Definition: rpcevo.cpp:51
@ revocationReason
Definition: rpcevo.cpp:53
@ collateralAddress
Definition: rpcevo.cpp:37
@ operatorPayoutAddress_update
Definition: rpcevo.cpp:45
@ payoutAddress_update
Definition: rpcevo.cpp:52
@ collateralIndex
Definition: rpcevo.cpp:39
@ operatorPayoutAddress_register
Definition: rpcevo.cpp:44
@ votingAddress_update
Definition: rpcevo.cpp:55
@ operatorPubKey_register
Definition: rpcevo.cpp:42
@ collateralHash
Definition: rpcevo.cpp:38
@ votingAddress_register
Definition: rpcevo.cpp:54
@ operatorReward
Definition: rpcevo.cpp:46
@ ipAndPort_register
Definition: rpcevo.cpp:40
@ operatorPubKey_update
Definition: rpcevo.cpp:43
@ proTxHash
Definition: rpcevo.cpp:50
@ ownerKey
Definition: rpcevo.cpp:49
@ ipAndPort_update
Definition: rpcevo.cpp:41
void RegisterEvoRPCCommands(CRPCTable &_tableRPC)
Register Evo RPC commands.
Definition: rpcevo.cpp:1081
UniValue protx_list(const JSONRPCRequest &request)
Definition: rpcevo.cpp:757
std::string GetHelpString(int nParamNum, ProRegParam p)
Definition: rpcevo.cpp:139
CWallet * GetWalletForJSONRPCRequest(const JSONRPCRequest &request)
Figures out what wallet, if any, to use for a JSONRPCRequest.
Definition: rpcwallet.cpp:39
std::string HelpRequiringPassphrase(CWallet *const pwallet)
Definition: rpcwallet.cpp:54
void EnsureWalletIsUnlocked(CWallet *const pwallet, bool fAllowAnonOnly)
Definition: rpcwallet.cpp:71
bool EnsureWalletIsAvailable(CWallet *const pwallet, bool avoidException)
Definition: rpcwallet.cpp:59
@ OP_RETURN
Definition: script.h:87
std::string HelpExampleCli(std::string methodname, std::string args)
Definition: server.cpp:527
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded Values (throws error if not hex).
Definition: server.cpp:138
std::string HelpExampleRpc(std::string methodname, std::string args)
Definition: server.cpp:532
void UpdateTransaction(CMutableTransaction &tx, unsigned int nIn, const SignatureData &data)
Definition: sign.cpp:186
bool ProduceSignature(const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata, SigVersion sigversion, bool fColdStake, ScriptError *serror)
Produce a script signature using a generic signature creator.
Definition: sign.cpp:153
bool CheckSpecialTx(const CTransaction &tx, const CBlockIndex *pindexPrev, const CCoinsViewCache *view, CValidationState &state)
Payload validity checks (including duplicate unique properties against list at pindexPrev)
uint256 CalcTxInputsHash(const CTransaction &tx)
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a PIVX scriptPubKey for the given CTxDestination.
Definition: standard.cpp:278
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet, bool fColdStake)
Parse a standard scriptPubKey for the destination address.
Definition: standard.cpp:162
boost::variant< CNoDestination, CKeyID, CScriptID, CExchangeKeyID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:72
A mutable version of CTransaction.
Definition: transaction.h:409
uint256 GetHash() const
Compute the hash of this CMutableTransaction.
Definition: transaction.cpp:96
SigVersion GetRequiredSigVersion() const
Definition: transaction.h:450
std::vector< CTxOut > vout
Definition: transaction.h:411
std::vector< CTxIn > vin
Definition: transaction.h:410
CAmount nMNCollateralAmt
Definition: params.h:184
#define LOCK2(cs1, cs2)
Definition: sync.h:221
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:247
#define AssertLockHeld(cs)
Definition: sync.h:75
int64_t GetAdjustedTime()
Definition: timedata.cpp:36
#define strprintf
Definition: tinyformat.h:1056
void SetTxPayload(CMutableTransaction &tx, const T &payload)
Definition: transaction.h:486
SigVersion
Definition: transaction.h:26
bool GetTxPayload(const std::vector< unsigned char > &payload, T &obj)
Definition: transaction.h:464
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:456
const UniValue NullUniValue
Definition: univalue.cpp:13
bool NetworkUpgradeActive(int nHeight, const Consensus::Params &params, Consensus::UpgradeIndex idx)
Returns true if the given network upgrade is active as of the given block height.
Definition: upgrades.cpp:107
std::string FormatStateMessage(const CValidationState &state)
Convert CValidationState to a human-readable message for logging.
Definition: validation.cpp:13
std::vector< unsigned char > DecodeBase64(const char *p, bool *pfInvalid)
bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)
Parse number as fixed point according to JSON number syntax.
bool GetTransaction(const uint256 &hash, CTransactionRef &txOut, uint256 &hashBlock, bool fAllowSlow, CBlockIndex *blockIndex)
Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock.
Definition: validation.cpp:671
std::unique_ptr< CCoinsViewCache > pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
Definition: validation.cpp:206
BlockMap mapBlockIndex
Definition: validation.cpp:82
CBlockIndex * GetChainTip()
Return a reliable pointer (in mapBlockIndex) to the chain's tip index.
Definition: validation.cpp:194
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:84