LCOV - code coverage report
Current view: top level - src/rpc - rawtransaction.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 363 393 92.4 %
Date: 2025-02-23 09:33:43 Functions: 15 18 83.3 %

          Line data    Source code
       1             : // Copyright (c) 2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2014 The Bitcoin developers
       3             : // Copyright (c) 2014-2015 The Dash developers
       4             : // Copyright (c) 2015-2022 The PIVX Core developers
       5             : // Distributed under the MIT software license, see the accompanying
       6             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       7             : 
       8             : #include "core_io.h"
       9             : #include "evo/providertx.h"
      10             : #include "key_io.h"
      11             : #include "keystore.h"
      12             : #include "llmq/quorums_chainlocks.h"
      13             : #include "net.h"
      14             : #include "policy/policy.h"
      15             : #include "primitives/transaction.h"
      16             : #include "rpc/server.h"
      17             : #include "script/script.h"
      18             : #include "script/script_error.h"
      19             : #include "script/sign.h"
      20             : #include "script/standard.h"
      21             : #include "uint256.h"
      22             : #include "utilmoneystr.h"
      23             : #include "validationinterface.h"
      24             : #ifdef ENABLE_WALLET
      25             : #include "sapling/address.h"
      26             : #include "sapling/key_io_sapling.h"
      27             : #include "wallet/rpcwallet.h"
      28             : #include "wallet/wallet.h"
      29             : #endif
      30             : 
      31             : #include <future>
      32             : #include <stdint.h>
      33             : 
      34             : #include <univalue.h>
      35             : 
      36             : template <typename Payload>
      37          77 : static void PayloadToJSON(const CTransaction& tx, Payload& pl, UniValue& entry)
      38             : {
      39          77 :     if (GetTxPayload(tx, pl)) {
      40           0 :         UniValue payloadObj;
      41          77 :         pl.ToJson(payloadObj);
      42         154 :         entry.pushKV("payload", payloadObj);
      43             :     }
      44          77 : }
      45             : 
      46          77 : static void PayloadToJSON(const CTransaction& tx, UniValue& entry)
      47             : {
      48          77 :     switch(tx.nType) {
      49          77 :         case CTransaction::TxType::PROREG: {
      50          77 :             ProRegPL pl;
      51          77 :             PayloadToJSON(tx, pl, entry);
      52          77 :             break;
      53             :         }
      54           0 :         case CTransaction::TxType::PROUPSERV: {
      55           0 :             ProUpServPL pl;
      56           0 :             PayloadToJSON(tx, pl, entry);
      57           0 :             break;
      58             :         }
      59           0 :         case CTransaction::TxType::PROUPREG: {
      60           0 :             ProUpRegPL pl;
      61           0 :             PayloadToJSON(tx, pl, entry);
      62           0 :             break;
      63             :         }
      64           0 :         case CTransaction::TxType::PROUPREV: {
      65           0 :             ProUpRevPL pl;
      66           0 :             PayloadToJSON(tx, pl, entry);
      67           0 :             break;
      68             :         }
      69             :     }
      70          77 : }
      71             : 
      72             : extern int ComputeNextBlockAndDepth(const CBlockIndex* tip, const CBlockIndex* blockindex, const CBlockIndex*& next);
      73             : 
      74         866 : static int ComputeConfirmations(const CBlockIndex* tip, const CBlockIndex* blockindex)
      75             : {
      76         866 :     const CBlockIndex* next{nullptr};
      77         866 :     return ComputeNextBlockAndDepth(tip, blockindex, next);
      78             : }
      79             : 
      80             : // pwallet can be nullptr. If not null, the json could include information available only to the wallet.
      81        1062 : void TxToJSON(CWallet* const pwallet, const CTransaction& tx, const CBlockIndex* tip, const CBlockIndex* blockindex, UniValue& entry)
      82             : {
      83             :     // Call into TxToUniv() in bitcoin-common to decode the transaction hex.
      84             :     //
      85             :     // Blockchain contextual information (confirmations and blocktime) is not
      86             :     // available to code in bitcoin-common, so we query them here and push the
      87             :     // data into the returned UniValue.
      88        2124 :     TxToUniv(tx, uint256(), entry);
      89             : 
      90             :     // Sapling
      91        1062 :     if (pwallet && tx.IsShieldedTx()) {
      92             :         // Add information that only this wallet knows about the transaction if is possible
      93          19 :         if (pwallet->HasSaplingSPKM()) {
      94          19 :             std::vector<libzcash::SaplingPaymentAddress> addresses =
      95          38 :                     pwallet->GetSaplingScriptPubKeyMan()->FindMySaplingAddresses(tx);
      96          38 :             UniValue addrs(UniValue::VARR);
      97          28 :             for (const auto& addr : addresses) {
      98          18 :                 addrs.push_back(KeyIO::EncodePaymentAddress(addr));
      99             :             }
     100          38 :             entry.pushKV("shielded_addresses", addrs);
     101             :         }
     102             :     }
     103             : 
     104             :     // Special txes
     105        1062 :     if (tx.IsSpecialTx()) {
     106          77 :         PayloadToJSON(tx, entry);
     107             :     }
     108             : 
     109        1062 :     bool chainLock = false;
     110        1062 :     if (blockindex && tip) {
     111        1732 :         entry.pushKV("blockhash", blockindex->GetBlockHash().ToString());
     112         866 :         int confirmations = ComputeConfirmations(tip, blockindex);
     113         866 :         if (confirmations != -1) {
     114         865 :             entry.pushKV("confirmations", confirmations);
     115         865 :             entry.pushKV("time", blockindex->GetBlockTime());
     116         865 :             entry.pushKV("blocktime", blockindex->GetBlockTime());
     117         865 :             chainLock = llmq::chainLocksHandler->HasChainLock(blockindex->nHeight, blockindex->GetBlockHash());
     118             :         } else {
     119           2 :             entry.pushKV("confirmations", 0);
     120             :         }
     121             :     }
     122        1062 :     entry.pushKV("chainlock", chainLock);
     123        1062 : }
     124             : 
     125           3 : std::string GetSaplingTxHelpInfo()
     126             : {
     127           3 :     return "  \"valueBalance\": n,          (numeric) The net value of spend transfers minus output transfers\n"
     128             :            "  \"valueBalanceSat\": n,       (numeric) `valueBalance` in sats\n"
     129             :            "  \"vShieldSpend\": [               (array of json objects)\n"
     130             :            "     {\n"
     131             :            "       \"cv\": \"hex\",         (string) A value commitment to the value of the input note\n"
     132             :            "       \"anchor\": hex,         (string) A Merkle root of the Sapling note commitment tree at some block height in the past\n"
     133             :            "       \"nullifier\": hex,       (string) The nullifier of the input note\n"
     134             :            "       \"rk\": hex,              (string) The randomized public key for spendAuthSig\n"
     135             :            "       \"proof\": hex,           (string) A zero-knowledge proof using the spend circuit\n"
     136             :            "       \"spendAuthSig\": hex,    (string) A signature authorizing this spend\n"
     137             :            "     }\n"
     138             :            "     ,...\n"
     139             :            "  ],\n"
     140             :            "  \"vShieldOutput\": [             (array of json objects)\n"
     141             :            "     {\n"
     142             :            "       \"cv\": hex,                  (string) A value commitment to the value of the output note\n"
     143             :            "       \"cmu\": hex,                 (string) The u-coordinate of the note commitment for the output note\n"
     144             :            "       \"ephemeralKey\": hex,         (string) A Jubjub public key\n"
     145             :            "       \"encCiphertext\": hex,       (string) A ciphertext component for the encrypted output note\n"
     146             :            "       \"outCiphertext\": hex,       (string) A ciphertext component for the encrypted output note\n"
     147             :            "       \"proof\": hex,               (string) A zero-knowledge proof using the output circuit\n"
     148             :            "     }\n"
     149             :            "     ,...\n"
     150             :            "  ],\n"
     151           3 :            "  \"bindingSig\": hex,       (string) Prove consistency of valueBalance with the value commitments in spend descriptions and output descriptions, and proves knowledge of the randomness used for the spend and output value commitments\n";
     152             : }
     153             : 
     154         975 : UniValue getrawtransaction(const JSONRPCRequest& request)
     155             : {
     156         975 :     if (request.fHelp || request.params.size() < 1 || request.params.size() > 3)
     157           1 :         throw std::runtime_error(
     158             :             "getrawtransaction \"txid\" ( verbose \"blockhash\" )\n"
     159             : 
     160             :             "\nNOTE: By default this function only works for mempool transactions. If the -txindex option is\n"
     161             :             "enabled, it also works for blockchain transactions. If the block which contains the transaction\n"
     162             :             "is known, its hash can be provided even for nodes without -txindex. Note that if a blockhash is\n"
     163             :             "provided, only that block will be searched and if the transaction is in the mempool or other\n"
     164             :             "blocks, or if this node does not have the given block available, the transaction will not be found.\n"
     165             :             "DEPRECATED: for now, it also works for transactions with unspent outputs.\n"
     166             : 
     167             :             "\nReturn the raw transaction data.\n"
     168             :             "\nIf verbose is 'true', returns an Object with information about 'txid'.\n"
     169             :             "If verbose is 'false' or omitted, returns a string that is serialized, hex-encoded data for 'txid'.\n"
     170             : 
     171             :             "\nArguments:\n"
     172             :             "1. \"txid\"      (string, required) The transaction id\n"
     173             :             "2. verbose     (bool, optional, default=false) If false, return a string, otherwise return a json object\n"
     174             :             "3. \"blockhash\" (string, optional) The block in which to look for the transaction\n"
     175             : 
     176             :             "\nResult (if verbose is not set or set to false):\n"
     177             :             "\"data\"      (string) The serialized, hex-encoded data for 'txid'\n"
     178             : 
     179             :             "\nResult (if verbose is set to true):\n"
     180             :             "{\n"
     181             :             "  \"in_active_chain\": b,   (bool) Whether specified block is in the active chain or not (only present with explicit \"blockhash\" argument)\n"
     182             :             "  \"hex\" : \"data\",       (string) The serialized, hex-encoded data for 'txid'\n"
     183             :             "  \"txid\" : \"id\",        (string) The transaction id (same as provided)\n"
     184             :             "  \"size\" : n,             (numeric) The serialized transaction size\n"
     185             :             "  \"version\" : n,          (numeric) The version\n"
     186             :             "  \"type\" : n,             (numeric) The type\n"
     187             :             "  \"locktime\" : ttt,       (numeric) The lock time\n"
     188             :             "  \"vin\" : [               (array of json objects)\n"
     189             :             "     {\n"
     190             :             "       \"txid\": \"id\",    (string) The transaction id\n"
     191             :             "       \"vout\": n,         (numeric) \n"
     192             :             "       \"scriptSig\": {     (json object) The script\n"
     193             :             "         \"asm\": \"asm\",  (string) asm\n"
     194             :             "         \"hex\": \"hex\"   (string) hex\n"
     195             :             "       },\n"
     196             :             "       \"sequence\": n      (numeric) The script sequence number\n"
     197             :             "     }\n"
     198             :             "     ,...\n"
     199             :             "  ],\n"
     200             :             "  \"vout\" : [              (array of json objects)\n"
     201             :             "     {\n"
     202             :             "       \"value\" : x.xxx,            (numeric) The value in PIV\n"
     203             :             "       \"n\" : n,                    (numeric) index\n"
     204             :             "       \"scriptPubKey\" : {          (json object)\n"
     205             :             "         \"asm\" : \"asm\",          (string) the asm\n"
     206             :             "         \"hex\" : \"hex\",          (string) the hex\n"
     207             :             "         \"reqSigs\" : n,            (numeric) The required sigs\n"
     208             :             "         \"type\" : \"pubkeyhash\",  (string) The type, eg 'pubkeyhash'\n"
     209             :             "         \"addresses\" : [           (json array of string)\n"
     210             :             "           \"pivxaddress\"        (string) pivx address\n"
     211             :             "           ,...\n"
     212             :             "         ]\n"
     213             :             "       }\n"
     214             :             "     }\n"
     215             :             "     ,...\n"
     216             :             "  ],\n"
     217           2 :             + GetSaplingTxHelpInfo() +
     218             :             "  \"shielded_addresses\"      (json array of string) the shielded addresses involved in this transaction if possible (only for shielded transactions and the tx owner/viewer)\n"
     219             :             "  \"extraPayloadSize\" : n    (numeric) Size of extra payload. Only present if it's a special TX\n"
     220             :             "  \"extraPayload\" : \"hex\"  (string) Hex encoded extra payload data. Only present if it's a special TX\n"
     221             :             "  \"blockhash\" : \"hash\",   (string) the block hash\n"
     222             :             "  \"confirmations\" : n,      (numeric) The confirmations\n"
     223             :             "  \"time\" : ttt,             (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT)\n"
     224             :             "  \"blocktime\" : ttt         (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
     225             :             "}\n"
     226             : 
     227             :             "\nExamples:\n"
     228           5 :             + HelpExampleCli("getrawtransaction", "\"mytxid\"")
     229           5 :             + HelpExampleCli("getrawtransaction", "\"mytxid\" true")
     230           5 :             + HelpExampleRpc("getrawtransaction", "\"mytxid\", true")
     231           6 :             + HelpExampleCli("getrawtransaction", "\"mytxid\" false \"myblockhash\"")
     232           5 :             + HelpExampleCli("getrawtransaction", "\"mytxid\" true \"myblockhash\"")
     233           3 :         );
     234             : 
     235        1940 :     LOCK(cs_main);
     236             : 
     237         974 :     bool in_active_chain = true;
     238         975 :     uint256 hash = ParseHashV(request.params[0], "parameter 1");
     239         973 :     CBlockIndex* blockindex = nullptr;
     240             : 
     241         973 :     bool fVerbose = false;
     242         973 :     if (!request.params[1].isNull()) {
     243         969 :         fVerbose = request.params[1].isNum() ? (request.params[1].get_int() != 0) : request.params[1].get_bool();
     244             :     }
     245             : 
     246         973 :     if (!request.params[2].isNull()) {
     247          12 :         uint256 blockhash = ParseHashV(request.params[2], "parameter 3");
     248           4 :         blockindex = LookupBlockIndex(blockhash);
     249           4 :         if (!blockindex) {
     250           2 :             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block hash not found");
     251             :         }
     252           6 :         in_active_chain = chainActive.Contains(blockindex);
     253             :     }
     254             : 
     255         968 :     CTransactionRef tx;
     256         968 :     uint256 hash_block;
     257         968 :     if (!GetTransaction(hash, tx, hash_block, true, blockindex)) {
     258           4 :         std::string errmsg;
     259           2 :         if (blockindex) {
     260           1 :             if (!(blockindex->nStatus & BLOCK_HAVE_DATA)) {
     261           0 :                 throw JSONRPCError(RPC_MISC_ERROR, "Block not available");
     262             :             }
     263           1 :             errmsg = "No such transaction found in the provided block";
     264             :         } else {
     265           1 :             errmsg = fTxIndex
     266             :               ? "No such mempool or blockchain transaction"
     267           1 :               : "No such mempool transaction. Use -txindex to enable blockchain transaction queries";
     268             :         }
     269           4 :         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, errmsg + ". Use gettransaction for wallet transactions.");
     270             :     }
     271             : 
     272         966 :     if (!fVerbose) {
     273          14 :         return EncodeHexTx(*tx);
     274             :     }
     275             : 
     276        1920 :     UniValue result(UniValue::VOBJ);
     277         962 :     if (blockindex) result.pushKV("in_active_chain", in_active_chain);
     278         958 :     else blockindex = LookupBlockIndex(hash_block);
     279         960 :     CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
     280        1920 :     TxToJSON(pwallet, *tx, chainActive.Tip(), blockindex, result);
     281         960 :     return result;
     282             : }
     283             : 
     284        2641 : UniValue createrawtransaction(const JSONRPCRequest& request)
     285             : {
     286        2641 :     if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
     287           4 :         throw std::runtime_error(
     288             :             "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,...} ( locktime )\n"
     289             :             "\nCreate a transaction spending the given inputs and sending to the given addresses.\n"
     290             :             "Returns hex-encoded raw transaction.\n"
     291             :             "Note that the transaction's inputs are not signed, and\n"
     292             :             "it is not stored in the wallet or transmitted to the network.\n"
     293             : 
     294             :             "\nArguments:\n"
     295             :             "1. \"inputs\"        (string, required) A json array of json objects\n"
     296             :             "     [\n"
     297             :             "       {\n"
     298             :             "         \"txid\":\"id\",  (string, required) The transaction id\n"
     299             :             "         \"vout\":n,       (numeric, required) The output number\n"
     300             :             "         \"sequence\":n    (numeric, optional) The sequence number\n"
     301             :             "       }\n"
     302             :             "       ,...\n"
     303             :             "     ]\n"
     304             :             "2. \"outputs\"           (string, required) a json object with addresses as keys and amounts as values\n"
     305             :             "    {\n"
     306             :             "      \"address\": x.xxx   (numeric, required) The key is the pivx address, the value is the pivx amount\n"
     307             :             "      ,...\n"
     308             :             "    }\n"
     309             :             "3. locktime                (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n"
     310             : 
     311             :             "\nResult:\n"
     312             :             "\"transaction\"            (string) hex string of the transaction\n"
     313             : 
     314           8 :             "\nExamples\n" +
     315          36 :             HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"") + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\""));
     316             : 
     317        2637 :     LOCK(cs_main);
     318        2658 :     RPCTypeCheck(request.params, {UniValue::VARR, UniValue::VOBJ, UniValue::VNUM});
     319        2631 :     if (request.params[0].isNull() || request.params[1].isNull())
     320           0 :         throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, arguments 1 and 2 must be non-null");
     321             : 
     322        5262 :     UniValue inputs = request.params[0].get_array();
     323        5262 :     UniValue sendTo = request.params[1].get_obj();
     324             : 
     325        2631 :     CMutableTransaction rawTx;
     326             : 
     327        2631 :     if (request.params.size() > 2 && !request.params[2].isNull()) {
     328           3 :         int64_t nLockTime = request.params[2].get_int64();
     329           3 :         if (nLockTime < 0 || nLockTime > std::numeric_limits<uint32_t>::max())
     330           4 :             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, locktime out of range");
     331           1 :         rawTx.nLockTime = nLockTime;
     332             :     }
     333             : 
     334        5314 :     for (unsigned int idx = 0; idx < inputs.size(); idx++) {
     335        2695 :         const UniValue& input = inputs[idx];
     336        2695 :         const UniValue& o = input.get_obj();
     337             : 
     338        2697 :         uint256 txid = ParseHashO(o, "txid");
     339             : 
     340        2691 :         const UniValue& vout_v = find_value(o, "vout");
     341        2691 :         if (!vout_v.isNum())
     342           4 :             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
     343        2689 :         int nOutput = vout_v.get_int();
     344        2689 :         if (nOutput < 0)
     345           2 :             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
     346             : 
     347        2688 :         uint32_t nSequence = (rawTx.nLockTime ? CTxIn::SEQUENCE_FINAL - 1 : CTxIn::SEQUENCE_FINAL);
     348             : 
     349             :         // set the sequence number if passed in the parameters object
     350        2688 :         const UniValue& sequenceObj = find_value(o, "sequence");
     351        2688 :         if (sequenceObj.isNum()) {
     352           6 :             int64_t seqNr64 = sequenceObj.get_int64();
     353           6 :             if (seqNr64 < 0 || seqNr64 > CTxIn::SEQUENCE_FINAL)
     354           6 :                 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, sequence number is out of range");
     355             :             else
     356           3 :                 nSequence = (uint32_t)seqNr64;
     357             :         }
     358             : 
     359        5385 :         CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
     360             : 
     361        2685 :         rawTx.vin.push_back(in);
     362             :     }
     363             : 
     364        5238 :     std::set<CTxDestination> setAddress;
     365        5235 :     std::vector<std::string> addrList = sendTo.getKeys();
     366        8931 :     for (const std::string& name_ : addrList) {
     367       12630 :         CTxDestination address = DecodeDestination(name_);
     368        6315 :         if (!IsValidDestination(address))
     369           2 :             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid PIVX address: ")+name_);
     370             : 
     371        6314 :         if (setAddress.count(address))
     372           2 :             throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ")+name_);
     373        6313 :         setAddress.insert(address);
     374             : 
     375       12626 :         CScript scriptPubKey = GetScriptForDestination(address);
     376        6313 :         CAmount nAmount = AmountFromValue(sendTo[name_]);
     377             : 
     378       12625 :         CTxOut out(nAmount, scriptPubKey);
     379        6312 :         rawTx.vout.push_back(out);
     380             :     }
     381             : 
     382        7851 :     return EncodeHexTx(rawTx);
     383             : }
     384             : 
     385          96 : UniValue decoderawtransaction(const JSONRPCRequest& request)
     386             : {
     387          96 :     if (request.fHelp || request.params.size() != 1)
     388           2 :         throw std::runtime_error(
     389             :             "decoderawtransaction \"hexstring\"\n"
     390             :             "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n"
     391             : 
     392             :             "\nArguments:\n"
     393             :             "1. \"hexstring\"      (string, required) The transaction hex string\n"
     394             : 
     395             :             "\nResult:\n"
     396             :             "{\n"
     397             :             "  \"txid\" : \"id\",        (string) The transaction id\n"
     398             :             "  \"size\" : n,             (numeric) The transaction size\n"
     399             :             "  \"version\" : n,          (numeric) The version\n"
     400             :             "  \"type\" : n,             (numeric) The type\n"
     401             :             "  \"locktime\" : ttt,       (numeric) The lock time\n"
     402             :             "  \"vin\" : [               (array of json objects)\n"
     403             :             "     {\n"
     404             :             "       \"txid\": \"id\",    (string) The transaction id\n"
     405             :             "       \"vout\": n,         (numeric) The output number\n"
     406             :             "       \"scriptSig\": {     (json object) The script\n"
     407             :             "         \"asm\": \"asm\",  (string) asm\n"
     408             :             "         \"hex\": \"hex\"   (string) hex\n"
     409             :             "       },\n"
     410             :             "       \"sequence\": n     (numeric) The script sequence number\n"
     411             :             "     }\n"
     412             :             "     ,...\n"
     413             :             "  ],\n"
     414             :             "  \"vout\" : [             (array of json objects)\n"
     415             :             "     {\n"
     416             :             "       \"value\" : x.xxx,            (numeric) The value in PIV\n"
     417             :             "       \"n\" : n,                    (numeric) index\n"
     418             :             "       \"scriptPubKey\" : {          (json object)\n"
     419             :             "         \"asm\" : \"asm\",          (string) the asm\n"
     420             :             "         \"hex\" : \"hex\",          (string) the hex\n"
     421             :             "         \"reqSigs\" : n,            (numeric) The required sigs\n"
     422             :             "         \"type\" : \"pubkeyhash\",  (string) The type, eg 'pubkeyhash'\n"
     423             :             "         \"addresses\" : [           (json array of string)\n"
     424             :             "           \"12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\"   (string) pivx address\n"
     425             :             "           ,...\n"
     426             :             "         ]\n"
     427             :             "       }\n"
     428             :             "     }\n"
     429             :             "     ,...\n"
     430             :             "  ],\n"
     431           4 :             + GetSaplingTxHelpInfo() +
     432             :             "  \"extraPayloadSize\" : n    (numeric) Size of extra payload. Only present if it's a special TX\n"
     433             :             "  \"extraPayload\" : \"hex\"  (string) Hex encoded extra payload data. Only present if it's a special TX\n"
     434             :             "}\n"
     435             : 
     436           4 :             "\nExamples:\n" +
     437          14 :             HelpExampleCli("decoderawtransaction", "\"hexstring\"") + HelpExampleRpc("decoderawtransaction", "\"hexstring\""));
     438             : 
     439          94 :     LOCK(cs_main);
     440          96 :     RPCTypeCheck(request.params, {UniValue::VSTR});
     441             : 
     442         188 :     CMutableTransaction mtx;
     443             : 
     444          94 :     if (!DecodeHexTx(mtx, request.params[0].get_str()))
     445           4 :         throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
     446             : 
     447          92 :     UniValue result(UniValue::VOBJ);
     448          92 :     CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
     449          92 :     TxToJSON(pwallet, CTransaction(std::move(mtx)), nullptr, nullptr, result);
     450             : 
     451         184 :     return result;
     452             : }
     453             : 
     454          10 : UniValue decodescript(const JSONRPCRequest& request)
     455             : {
     456          10 :     if (request.fHelp || request.params.size() != 1)
     457           0 :         throw std::runtime_error(
     458             :             "decodescript \"hexstring\"\n"
     459             :             "\nDecode a hex-encoded script.\n"
     460             : 
     461             :             "\nArguments:\n"
     462             :             "1. \"hexstring\"     (string) the hex encoded script\n"
     463             : 
     464             :             "\nResult:\n"
     465             :             "{\n"
     466             :             "  \"asm\":\"asm\",   (string) Script public key\n"
     467             :             "  \"hex\":\"hex\",   (string) hex encoded public key\n"
     468             :             "  \"type\":\"type\", (string) The output type\n"
     469             :             "  \"reqSigs\": n,    (numeric) The required signatures\n"
     470             :             "  \"addresses\": [   (json array of string)\n"
     471             :             "     \"address\"     (string) pivx address\n"
     472             :             "     ,...\n"
     473             :             "  ],\n"
     474             :             "  \"p2sh\",\"address\" (string) script address\n"
     475             :             "}\n"
     476             : 
     477           0 :             "\nExamples:\n" +
     478           0 :             HelpExampleCli("decodescript", "\"hexstring\"") + HelpExampleRpc("decodescript", "\"hexstring\""));
     479             : 
     480          10 :     LOCK(cs_main);
     481          10 :     RPCTypeCheck(request.params, {UniValue::VSTR});
     482             : 
     483          10 :     UniValue r(UniValue::VOBJ);
     484          20 :     CScript script;
     485          10 :     if (request.params[0].get_str().size() > 0) {
     486          20 :         std::vector<unsigned char> scriptData(ParseHexV(request.params[0], "argument"));
     487          10 :         script = CScript(scriptData.begin(), scriptData.end());
     488             :     } else {
     489             :         // Empty scripts are valid
     490             :     }
     491          10 :     ScriptPubKeyToUniv(script, r, false);
     492             : 
     493          30 :     r.pushKV("p2sh", EncodeDestination(CScriptID(script)));
     494          20 :     return r;
     495             : }
     496             : 
     497             : /** Pushes a JSON object for script verification or signing errors to vErrorsRet. */
     498          13 : static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::string& strMessage)
     499             : {
     500          26 :     UniValue entry(UniValue::VOBJ);
     501          26 :     entry.pushKV("txid", txin.prevout.hash.ToString());
     502          13 :     entry.pushKV("vout", (uint64_t)txin.prevout.n);
     503          39 :     entry.pushKV("scriptSig", HexStr(txin.scriptSig));
     504          13 :     entry.pushKV("sequence", (uint64_t)txin.nSequence);
     505          13 :     entry.pushKV("error", strMessage);
     506          13 :     vErrorsRet.push_back(entry);
     507          13 : }
     508             : 
     509      102778 : UniValue signrawtransaction(const JSONRPCRequest& request)
     510             : {
     511      102778 :     CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
     512             : 
     513      102778 :     if (request.fHelp || request.params.size() < 1 || request.params.size() > 4)
     514           1 :         throw std::runtime_error(
     515             :             "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
     516             :             "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
     517             :             "The second optional argument (may be null) is an array of previous transaction outputs that\n"
     518             :             "this transaction depends on but may not yet be in the block chain.\n"
     519             :             "The third optional argument (may be null) is an array of base58-encoded private\n"
     520             :             "keys that, if given, will be the only keys used to sign the transaction.\n"
     521             : #ifdef ENABLE_WALLET
     522           2 :             + HelpRequiringPassphrase(pwallet) + "\n"
     523             : #endif
     524             : 
     525             :             "\nArguments:\n"
     526             :             "1. \"hexstring\"     (string, required) The transaction hex string\n"
     527             :             "2. \"prevtxs\"       (string, optional) An json array of previous dependent transaction outputs\n"
     528             :             "     [               (json array of json objects, or 'null' if none provided)\n"
     529             :             "       {\n"
     530             :             "         \"txid\":\"id\",             (string, required) The transaction id\n"
     531             :             "         \"vout\":n,                  (numeric, required) The output number\n"
     532             :             "         \"scriptPubKey\": \"hex\",   (string, required) script key\n"
     533             :             "         \"redeemScript\": \"hex\"    (string, required for P2SH) redeem script\n"
     534             :             "         \"amount\": value            (numeric, required) The amount spent\n"
     535             :             "       }\n"
     536             :             "       ,...\n"
     537             :             "    ]\n"
     538             :             "3. \"privkeys\"     (string, optional) A json array of base58-encoded private keys for signing\n"
     539             :             "    [                  (json array of strings, or 'null' if none provided)\n"
     540             :             "      \"privatekey\"   (string) private key in base58-encoding\n"
     541             :             "      ,...\n"
     542             :             "    ]\n"
     543             :             "4. \"sighashtype\"     (string, optional, default=ALL) The signature hash type. Must be one of\n"
     544             :             "       \"ALL\"\n"
     545             :             "       \"NONE\"\n"
     546             :             "       \"SINGLE\"\n"
     547             :             "       \"ALL|ANYONECANPAY\"\n"
     548             :             "       \"NONE|ANYONECANPAY\"\n"
     549             :             "       \"SINGLE|ANYONECANPAY\"\n"
     550             : 
     551             :             "\nResult:\n"
     552             :             "{\n"
     553             :             "  \"hex\" : \"value\",           (string) The hex-encoded raw transaction with signature(s)\n"
     554             :             "  \"complete\" : true|false,   (boolean) If the transaction has a complete set of signatures\n"
     555             :             "  \"errors\" : [                 (json array of objects) Script verification errors (if there are any)\n"
     556             :             "    {\n"
     557             :             "      \"txid\" : \"hash\",           (string) The hash of the referenced, previous transaction\n"
     558             :             "      \"vout\" : n,                (numeric) The index of the output to spent and used as input\n"
     559             :             "      \"scriptSig\" : \"hex\",       (string) The hex-encoded signature script\n"
     560             :             "      \"sequence\" : n,            (numeric) Script sequence number\n"
     561             :             "      \"error\" : \"text\"           (string) Verification or signing error related to the input\n"
     562             :             "    }\n"
     563             :             "    ,...\n"
     564             :             "  ]\n"
     565             :             "}\n"
     566             : 
     567           2 :             "\nExamples:\n" +
     568           7 :             HelpExampleCli("signrawtransaction", "\"myhex\"") + HelpExampleRpc("signrawtransaction", "\"myhex\""));
     569             : 
     570             : #ifdef ENABLE_WALLET
     571      205554 :     LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : nullptr);
     572             : #else
     573             :     LOCK(cs_main);
     574             : #endif
     575      102783 :     RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true);
     576             : 
     577      205554 :     std::vector<unsigned char> txData(ParseHexV(request.params[0], "argument 1"));
     578      205552 :     CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
     579      205552 :     std::vector<CMutableTransaction> txVariants;
     580      205551 :     while (!ssData.empty()) {
     581      102776 :         try {
     582      205552 :             CMutableTransaction tx;
     583      102776 :             ssData >> tx;
     584      102775 :             txVariants.push_back(tx);
     585           2 :         } catch (const std::exception&) {
     586           2 :             throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
     587             :         }
     588             :     }
     589             : 
     590      102775 :     if (txVariants.empty())
     591           0 :         throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction");
     592             : 
     593             :     // mergedTx will end up with all the signatures; it
     594             :     // starts as a clone of the rawtx:
     595      102779 :     CMutableTransaction mergedTx(txVariants[0]);
     596             : 
     597             :     // Fetch previous transactions (inputs):
     598      205550 :     std::map<COutPoint, std::pair<CScript, CAmount>> mapPrevOut; // todo: check why do we have this for regtest..
     599      102775 :     if (Params().IsRegTestNet()) {
     600      305657 :         for (const CTxIn &txbase : mergedTx.vin)
     601             :         {
     602      202888 :             CTransactionRef tempTx;
     603      202888 :             uint256 hashBlock;
     604      202888 :             if (GetTransaction(txbase.prevout.hash, tempTx, hashBlock, true)) {
     605             :                 // Copy results into mapPrevOut:
     606      202878 :                 mapPrevOut[txbase.prevout] = std::make_pair(tempTx->vout[txbase.prevout.n].scriptPubKey, tempTx->vout[txbase.prevout.n].nValue);
     607             :             }
     608             :         }
     609             :     }
     610      102771 :     CCoinsView viewDummy;
     611      205550 :     CCoinsViewCache view(&viewDummy);
     612      102775 :     {
     613      102775 :         LOCK(mempool.cs);
     614      102775 :         CCoinsViewCache& viewChain = *pcoinsTip;
     615      205550 :         CCoinsViewMemPool viewMempool(&viewChain, mempool);
     616      102775 :         view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
     617             : 
     618      305669 :         for (const CTxIn& txin : mergedTx.vin) {
     619      202894 :             view.AccessCoin(txin.prevout); // Load entries from viewChain into view; can fail.
     620             :         }
     621             : 
     622      102775 :         view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
     623             :     }
     624             : 
     625      102775 :     bool fGivenKeys = false;
     626      205550 :     CBasicKeyStore tempKeystore;
     627      102775 :     if (request.params.size() > 2 && !request.params[2].isNull()) {
     628           5 :         fGivenKeys = true;
     629          10 :         UniValue keys = request.params[2].get_array();
     630           9 :         for (unsigned int idx = 0; idx < keys.size(); idx++) {
     631           4 :             UniValue k = keys[idx];
     632           8 :             CKey key = KeyIO::DecodeSecret(k.get_str());
     633           4 :             if (!key.IsValid())
     634           0 :                 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
     635           4 :             tempKeystore.AddKey(key);
     636             :         }
     637             :     }
     638             : #ifdef ENABLE_WALLET
     639      102770 :     else if (pwallet)
     640      102767 :         EnsureWalletIsUnlocked(pwallet);
     641             : #endif
     642             : 
     643             :     // Add previous txouts given in the RPC call:
     644      102775 :     if (request.params.size() > 1 && !request.params[1].isNull()) {
     645          30 :         UniValue prevTxs = request.params[1].get_array();
     646          27 :         for (unsigned int idx = 0; idx < prevTxs.size(); idx++) {
     647          15 :             const UniValue& p = prevTxs[idx];
     648          15 :             if (!p.isObject())
     649           0 :                 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
     650             : 
     651          15 :             UniValue prevOut = p.get_obj();
     652             : 
     653          75 :             RPCTypeCheckObj(prevOut,
     654             :                 {
     655          15 :                     {"txid", UniValueType(UniValue::VSTR)},
     656          15 :                     {"vout", UniValueType(UniValue::VNUM)},
     657          18 :                     {"scriptPubKey", UniValueType(UniValue::VSTR)},
     658          60 :                 });
     659             : 
     660          12 :             uint256 txid = ParseHashO(prevOut, "txid");
     661             : 
     662          12 :             int nOut = find_value(prevOut, "vout").get_int();
     663          12 :             if (nOut < 0)
     664           0 :                 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
     665             : 
     666          12 :             COutPoint out(txid, nOut);
     667          24 :             std::vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey"));
     668          24 :             CScript scriptPubKey(pkData.begin(), pkData.end());
     669             : 
     670          12 :             {
     671          12 :                 const Coin& coin = view.AccessCoin(out);
     672          12 :                 if (!coin.IsSpent() && coin.out.scriptPubKey != scriptPubKey) {
     673           0 :                     std::string err("Previous output scriptPubKey mismatch:\n");
     674           0 :                     err = err + ScriptToAsmStr(coin.out.scriptPubKey) + "\nvs:\n"+
     675           0 :                         ScriptToAsmStr(scriptPubKey);
     676           0 :                     throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
     677             :                 }
     678             : 
     679          12 :                 Coin newcoin;
     680          12 :                 newcoin.out.scriptPubKey = scriptPubKey;
     681          12 :                 newcoin.out.nValue = 0;
     682          12 :                 newcoin.nHeight = 1;
     683          24 :                 if (prevOut.exists("amount")) {
     684           4 :                     newcoin.out.nValue = AmountFromValue(find_value(prevOut, "amount"));
     685             :                 }
     686          12 :                 view.AddCoin(out, std::move(newcoin), true);
     687             :             }
     688             : 
     689             :             // if redeemScript given and not using the local wallet (private keys
     690             :             // given), add redeemScript to the tempKeystore so it can be signed:
     691          12 :             if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) {
     692          12 :                 RPCTypeCheckObj(prevOut,
     693             :                     {
     694           2 :                         {"txid", UniValueType(UniValue::VSTR)},
     695           2 :                         {"vout", UniValueType(UniValue::VNUM)},
     696           2 :                         {"scriptPubKey", UniValueType(UniValue::VSTR)},
     697           2 :                         {"redeemScript", UniValueType(UniValue::VSTR)},
     698          10 :                     });
     699           4 :                 UniValue v = find_value(prevOut, "redeemScript");
     700           2 :                 if (!v.isNull()) {
     701           4 :                     std::vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
     702           4 :                     CScript redeemScript(rsData.begin(), rsData.end());
     703           2 :                     tempKeystore.AddCScript(redeemScript);
     704             :                 }
     705             :             }
     706             :         }
     707             :     }
     708             : 
     709             : #ifdef ENABLE_WALLET
     710      102772 :     const CKeyStore& keystore = ((fGivenKeys || !pwallet) ? tempKeystore : *pwallet);
     711             : #else
     712             :     const CKeyStore& keystore = tempKeystore;
     713             : #endif
     714             : 
     715      102772 :     int nHashType = SIGHASH_ALL;
     716      102772 :     if (request.params.size() > 3 && !request.params[3].isNull()) {
     717           4 :         static std::map<std::string, int> mapSigHashValues = {
     718           4 :             {std::string("ALL"), int(SIGHASH_ALL)},
     719           4 :             {std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)},
     720           4 :             {std::string("NONE"), int(SIGHASH_NONE)},
     721           4 :             {std::string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)},
     722           4 :             {std::string("SINGLE"), int(SIGHASH_SINGLE)},
     723           4 :             {std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)},
     724          28 :         };
     725           8 :         std::string strHashType = request.params[3].get_str();
     726           4 :         if (mapSigHashValues.count(strHashType))
     727           3 :             nHashType = mapSigHashValues[strHashType];
     728             :         else
     729           2 :             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
     730             :     }
     731             : 
     732      102771 :     bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
     733             : 
     734             :     // Script verification errors
     735      205542 :     UniValue vErrors(UniValue::VARR);
     736             : 
     737             :     // Use CTransaction for the constant parts of the
     738             :     // transaction to avoid rehashing.
     739      102771 :     const CTransaction txConst(mergedTx);
     740             :     // Sign what we can:
     741      305661 :     for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
     742      202890 :         CTxIn& txin = mergedTx.vin[i];
     743      202890 :         const Coin& coin = view.AccessCoin(txin.prevout);
     744      202890 :         if (Params().IsRegTestNet()) {
     745      405770 :             if (mapPrevOut.count(txin.prevout) == 0 && coin.IsSpent())
     746             :             {
     747           2 :                 TxInErrorToJSON(txin, vErrors, "Input not found");
     748           5 :                 continue;
     749             :             }
     750             :         } else {
     751           5 :             if (coin.IsSpent()) {
     752           3 :                 TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
     753           3 :                 continue;
     754             :             }
     755             :         }
     756             : 
     757      405768 :         const CScript& prevPubKey = (Params().IsRegTestNet() && mapPrevOut.count(txin.prevout) != 0 ? mapPrevOut[txin.prevout].first : coin.out.scriptPubKey);
     758      405768 :         const CAmount& amount = (Params().IsRegTestNet() && mapPrevOut.count(txin.prevout) != 0 ? mapPrevOut[txin.prevout].second : coin.out.nValue);
     759             : 
     760      202885 :         txin.scriptSig.clear();
     761             : 
     762             :         // if this is a P2CS script, select which key to use
     763      202885 :         bool fColdStake = false;
     764      202885 :         if (prevPubKey.IsPayToColdStaking()) {
     765             :             // if we have both keys, sign with the spender key
     766          25 :             fColdStake = !bool(IsMine(keystore, prevPubKey) & ISMINE_SPENDABLE_DELEGATED);
     767             :         }
     768             : 
     769      405770 :         SignatureData sigdata;
     770      202885 :         SigVersion sigversion = mergedTx.GetRequiredSigVersion();
     771             :         // Only sign SIGHASH_SINGLE if there's a corresponding output:
     772      202885 :         if (!fHashSingle || (i < mergedTx.vout.size()))
     773      608655 :             ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType),
     774             :                     prevPubKey, sigdata, sigversion, fColdStake);
     775             : 
     776             :         // ... and merge in other signatures:
     777      405770 :         for (const CMutableTransaction& txv : txVariants) {
     778      405768 :             sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i));
     779             :         }
     780             : 
     781      202885 :         UpdateTransaction(mergedTx, i, sigdata);
     782             : 
     783      202885 :         ScriptError serror = SCRIPT_ERR_OK;
     784      202885 :         if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS,
     785      202885 :                 TransactionSignatureChecker(&txConst, i, amount), sigversion, &serror)) {
     786          16 :             TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
     787             :         }
     788             :     }
     789      102771 :     bool fComplete = vErrors.empty();
     790             : 
     791      102771 :     UniValue result(UniValue::VOBJ);
     792      308313 :     result.pushKV("hex", EncodeHexTx(mergedTx));
     793      102771 :     result.pushKV("complete", fComplete);
     794      102771 :     if (!vErrors.empty()) {
     795          24 :         result.pushKV("errors", vErrors);
     796             :     }
     797             : 
     798      205542 :     return result;
     799             : }
     800             : 
     801      108627 : void TryATMP(const CMutableTransaction& mtx, bool fOverrideFees)
     802             : {
     803      108627 :     const uint256& hashTx = mtx.GetHash();
     804      108627 :     std::promise<void> promise;
     805      108627 :     bool fLimitFree = true;
     806             : 
     807      108627 :     { // cs_main scope
     808      108646 :         LOCK(cs_main);
     809      108627 :         CCoinsViewCache& view = *pcoinsTip;
     810      108627 :         bool fHaveChain = false;
     811      426907 :         for (size_t o = 0; !fHaveChain && o < mtx.vout.size(); o++) {
     812      318299 :             const Coin& existingCoin = view.AccessCoin(COutPoint(hashTx, o));
     813      318280 :             fHaveChain = !existingCoin.IsSpent();
     814             :         }
     815      108627 :         bool fHaveMempool = mempool.exists(hashTx);
     816      108627 :         if (!fHaveMempool && !fHaveChain) {
     817      108627 :             CValidationState state;
     818      108627 :             bool fMissingInputs;
     819      217254 :             if (!AcceptToMemoryPool(mempool, state, MakeTransactionRef(std::move(mtx)), fLimitFree, &fMissingInputs, false, !fOverrideFees)) {
     820          19 :                 if (state.IsInvalid()) {
     821          78 :                     throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%s: %s", state.GetRejectReason(), state.GetDebugMessage()));
     822             :                 } else {
     823           2 :                     if (fMissingInputs) {
     824           4 :                         throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
     825             :                     }
     826           0 :                     throw JSONRPCError(RPC_TRANSACTION_ERROR, strprintf("%s: %s", state.GetRejectReason(), state.GetDebugMessage()));
     827             :                 }
     828             :             } else {
     829             :                 // If wallet is enabled, ensure that the wallet has been made aware
     830             :                 // of the new transaction prior to returning. This prevents a race
     831             :                 // where a user might call sendrawtransaction with a transaction
     832             :                 // to/from their wallet, immediately call some wallet RPC, and get
     833             :                 // a stale result because callbacks have not yet been processed.
     834      217235 :                 CallFunctionInValidationInterfaceQueue([&promise] {
     835      108608 :                     promise.set_value();
     836             :                 });
     837             :             }
     838           0 :         } else if (fHaveChain) {
     839           0 :             throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
     840             :         }
     841             : 
     842             :     } // cs_main
     843             : 
     844      325843 :     promise.get_future().wait();
     845      108608 : }
     846             : 
     847      108608 : void RelayTx(const uint256& hashTx)
     848             : {
     849      108608 :     if(!g_connman)
     850           0 :         throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
     851             : 
     852      108608 :     CInv inv(MSG_TX, hashTx);
     853      108608 :     g_connman->ForEachNode([&inv](CNode* pnode)
     854             :     {
     855        8495 :         pnode->PushInventory(inv);
     856        8495 :     });
     857      108608 : }
     858             : 
     859      108542 : UniValue sendrawtransaction(const JSONRPCRequest& request)
     860             : {
     861      108542 :     if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
     862           1 :         throw std::runtime_error(
     863             :             "sendrawtransaction \"hexstring\" ( allowhighfees )\n"
     864             :             "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
     865             :             "\nAlso see createrawtransaction and signrawtransaction calls.\n"
     866             : 
     867             :             "\nArguments:\n"
     868             :             "1. \"hexstring\"    (string, required) The hex string of the raw transaction)\n"
     869             :             "2. allowhighfees    (boolean, optional, default=false) Allow high fees\n"
     870             : 
     871             :             "\nResult:\n"
     872             :             "\"hex\"             (string) The transaction hash in hex\n"
     873             : 
     874             :             "\nExamples:\n"
     875           2 :             "\nCreate a transaction\n" +
     876           6 :             HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
     877           5 :             "Sign the transaction, and get back the hex\n" + HelpExampleCli("signrawtransaction", "\"myhex\"") +
     878           5 :             "\nSend the transaction (signed hex)\n" + HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
     879           5 :             "\nAs a json rpc call\n" + HelpExampleRpc("sendrawtransaction", "\"signedhex\""));
     880             : 
     881      108541 :     RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL});
     882             : 
     883             :     // parse hex string from parameter
     884      108541 :     CMutableTransaction mtx;
     885      108541 :     if (!DecodeHexTx(mtx, request.params[0].get_str()))
     886           4 :         throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
     887      108539 :     const uint256& hashTx = mtx.GetHash();
     888             : 
     889      108539 :     bool fOverrideFees = false;
     890      108539 :     if (request.params.size() > 1)
     891        5926 :         fOverrideFees = request.params[1].get_bool();
     892             : 
     893      108539 :     TryATMP(mtx, fOverrideFees);
     894      108525 :     RelayTx(hashTx);
     895             : 
     896      217066 :     return hashTx.GetHex();
     897             : }
     898             : 
     899             : // clang-format off
     900             : static const CRPCCommand commands[] =
     901             : { //  category              name                      actor (function)         okSafe argNames
     902             :   //  --------------------- ------------------------  -----------------------  ------ --------
     903             :     { "rawtransactions",    "createrawtransaction",   &createrawtransaction,   true,  {"inputs","outputs","locktime"} },
     904             :     { "rawtransactions",    "decoderawtransaction",   &decoderawtransaction,   true,  {"hexstring"}  },
     905             :     { "rawtransactions",    "decodescript",           &decodescript,           true,  {"hexstring"} },
     906             :     { "rawtransactions",    "getrawtransaction",      &getrawtransaction,      true,  {"txid","verbose","blockhash"} },
     907             :     { "rawtransactions",    "sendrawtransaction",     &sendrawtransaction,     false, {"hexstring","allowhighfees"} },
     908             :     { "rawtransactions",    "signrawtransaction",     &signrawtransaction,     false, {"hexstring","prevtxs","privkeys","sighashtype"} }, /* uses wallet if enabled */
     909             : };
     910             : // clang-format on
     911             : 
     912         494 : void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC)
     913             : {
     914        3458 :     for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
     915        2964 :         tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
     916         494 : }

Generated by: LCOV version 1.14