aboutsummaryrefslogtreecommitdiff
path: root/src/rpc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc')
-rw-r--r--src/rpc/blockchain.cpp20
-rw-r--r--src/rpc/client.cpp4
-rw-r--r--src/rpc/mining.cpp5
-rw-r--r--src/rpc/misc.cpp14
-rw-r--r--src/rpc/net.cpp4
-rw-r--r--src/rpc/protocol.cpp1
-rw-r--r--src/rpc/rawtransaction.cpp57
-rw-r--r--src/rpc/rawtransaction_util.cpp1
-rw-r--r--src/rpc/server.cpp2
-rw-r--r--src/rpc/util.cpp24
-rw-r--r--src/rpc/util.h3
11 files changed, 75 insertions, 60 deletions
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 01c3265656..9f3748cb65 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -6,7 +6,6 @@
#include <rpc/blockchain.h>
#include <amount.h>
-#include <base58.h>
#include <blockfilter.h>
#include <chain.h>
#include <chainparams.h>
@@ -15,7 +14,6 @@
#include <core_io.h>
#include <hash.h>
#include <index/blockfilterindex.h>
-#include <index/txindex.h>
#include <key_io.h>
#include <policy/feerate.h>
#include <policy/policy.h>
@@ -486,7 +484,10 @@ UniValue MempoolToJSON(const CTxMemPool& pool, bool verbose)
const uint256& hash = e.GetTx().GetHash();
UniValue info(UniValue::VOBJ);
entryToJSON(pool, info, e);
- o.pushKV(hash.ToString(), info);
+ // Mempool has unique entries so there is no advantage in using
+ // UniValue::pushKV, which checks if the key already exists in O(N).
+ // UniValue::__pushKV is used instead which currently is O(1).
+ o.__pushKV(hash.ToString(), info);
}
return o;
} else {
@@ -1060,7 +1061,12 @@ static UniValue pruneblockchain(const JSONRPCRequest& request)
}
PruneBlockFilesManual(height);
- return uint64_t(height);
+ const CBlockIndex* block = ::ChainActive().Tip();
+ assert(block);
+ while (block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) {
+ block = block->pprev;
+ }
+ return uint64_t(block->nHeight);
}
static UniValue gettxoutsetinfo(const JSONRPCRequest& request)
@@ -1092,7 +1098,7 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request)
UniValue ret(UniValue::VOBJ);
CCoinsStats stats;
- FlushStateToDisk();
+ ::ChainstateActive().ForceFlushStateToDisk();
if (GetUTXOStats(pcoinsdbview.get(), stats)) {
ret.pushKV("height", (int64_t)stats.nHeight);
ret.pushKV("bestblock", stats.hashBlock.GetHex());
@@ -1357,7 +1363,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
obj.pushKV("difficulty", (double)GetDifficulty(tip));
obj.pushKV("mediantime", (int64_t)tip->GetMedianTimePast());
obj.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), tip));
- obj.pushKV("initialblockdownload", IsInitialBlockDownload());
+ obj.pushKV("initialblockdownload", ::ChainstateActive().IsInitialBlockDownload());
obj.pushKV("chainwork", tip->nChainWork.GetHex());
obj.pushKV("size_on_disk", CalculateCurrentUsage());
obj.pushKV("pruned", fPruneMode);
@@ -2260,7 +2266,7 @@ UniValue scantxoutset(const JSONRPCRequest& request)
std::unique_ptr<CCoinsViewCursor> pcursor;
{
LOCK(cs_main);
- FlushStateToDisk();
+ ::ChainstateActive().ForceFlushStateToDisk();
pcursor = std::unique_ptr<CCoinsViewCursor>(pcoinsdbview->Cursor());
assert(pcursor);
}
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
index 4144a17bc3..8f6bdc21aa 100644
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -36,6 +36,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "sendtoaddress", 4, "subtractfeefromamount" },
{ "sendtoaddress", 5 , "replaceable" },
{ "sendtoaddress", 6 , "conf_target" },
+ { "sendtoaddress", 8, "avoid_reuse" },
{ "settxfee", 0, "amount" },
{ "sethdseed", 0, "newkeypool" },
{ "getreceivedbyaddress", 1, "minconf" },
@@ -48,6 +49,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "listreceivedbylabel", 2, "include_watchonly" },
{ "getbalance", 1, "minconf" },
{ "getbalance", 2, "include_watchonly" },
+ { "getbalance", 3, "avoid_reuse" },
{ "getblockhash", 0, "height" },
{ "waitforblockheight", 0, "height" },
{ "waitforblockheight", 1, "timeout" },
@@ -141,6 +143,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "setban", 2, "bantime" },
{ "setban", 3, "absolute" },
{ "setnetworkactive", 0, "state" },
+ { "setwalletflag", 1, "value" },
{ "getmempoolancestors", 1, "verbose" },
{ "getmempooldescendants", 1, "verbose" },
{ "bumpfee", 1, "options" },
@@ -162,6 +165,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "rescanblockchain", 1, "stop_height"},
{ "createwallet", 1, "disable_private_keys"},
{ "createwallet", 2, "blank"},
+ { "createwallet", 4, "avoid_reuse"},
{ "getnodeaddresses", 0, "count"},
{ "stop", 0, "wait" },
};
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index 1831562100..86b0845738 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -442,7 +442,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0)
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, PACKAGE_NAME " is not connected!");
- if (IsInitialBlockDownload())
+ if (::ChainstateActive().IsInitialBlockDownload())
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, PACKAGE_NAME " is in initial sync and waiting for blocks...");
static unsigned int nTransactionsUpdatedLast;
@@ -469,7 +469,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
nTransactionsUpdatedLastLP = nTransactionsUpdatedLast;
}
- // Release the wallet and main lock while waiting
+ // Release lock while waiting
LEAVE_CRITICAL_SECTION(cs_main);
{
checktxtime = std::chrono::steady_clock::now() + std::chrono::minutes(1);
@@ -480,6 +480,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
if (g_best_block_cv.wait_until(lock, checktxtime) == std::cv_status::timeout)
{
// Timeout: Check transactions for update
+ // without holding ::mempool.cs to avoid deadlocks
if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP)
break;
checktxtime += std::chrono::seconds(10);
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp
index 7008a83143..7a1bdec7b9 100644
--- a/src/rpc/misc.cpp
+++ b/src/rpc/misc.cpp
@@ -3,25 +3,17 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <chain.h>
-#include <clientversion.h>
-#include <core_io.h>
#include <crypto/ripemd160.h>
#include <key_io.h>
-#include <validation.h>
#include <httpserver.h>
-#include <net.h>
-#include <netbase.h>
#include <outputtype.h>
#include <rpc/blockchain.h>
#include <rpc/server.h>
#include <rpc/util.h>
#include <script/descriptor.h>
-#include <timedata.h>
#include <util/system.h>
#include <util/strencodings.h>
#include <util/validation.h>
-#include <warnings.h>
#include <stdint.h>
#include <tuple>
@@ -130,9 +122,9 @@ static UniValue createmultisig(const JSONRPCRequest& request)
}
// Construct using pay-to-script-hash:
- const CScript inner = CreateMultisigRedeemscript(required, pubkeys);
CBasicKeyStore keystore;
- const CTxDestination dest = AddAndGetDestinationForScript(keystore, inner, output_type);
+ CScript inner;
+ const CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, output_type, keystore, inner);
UniValue result(UniValue::VOBJ);
result.pushKV("address", EncodeDestination(dest));
@@ -204,7 +196,7 @@ UniValue deriveaddresses(const JSONRPCRequest& request)
},
RPCExamples{
"First three native segwit receive addresses\n" +
- HelpExampleCli("deriveaddresses", "\"wpkh([d34db33f/84h/0h/0h]xpub6DJ2dNUysrn5Vt36jH2KLBT2i1auw1tTSSomg8PhqNiUtx8QX2SvC9nrHu81fT41fvDUnhMjEzQgXnQjKEu3oaqMSzhSrHMxyyoEAmUHQbY/0/*)#trd0mf0l\" \"[0,2]\"")
+ HelpExampleCli("deriveaddresses", "\"wpkh([d34db33f/84h/0h/0h]xpub6DJ2dNUysrn5Vt36jH2KLBT2i1auw1tTSSomg8PhqNiUtx8QX2SvC9nrHu81fT41fvDUnhMjEzQgXnQjKEu3oaqMSzhSrHMxyyoEAmUHQbY/0/*)#cjjspncu\" \"[0,2]\"")
}}.ToString()
);
}
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index e8cdce623c..d993a88458 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -5,7 +5,6 @@
#include <rpc/server.h>
#include <banman.h>
-#include <chainparams.h>
#include <clientversion.h>
#include <core_io.h>
#include <net.h>
@@ -17,7 +16,6 @@
#include <rpc/util.h>
#include <sync.h>
#include <timedata.h>
-#include <ui_interface.h>
#include <util/strencodings.h>
#include <util/system.h>
#include <validation.h>
@@ -496,7 +494,7 @@ static UniValue getnetworkinfo(const JSONRPCRequest& request)
obj.pushKV("protocolversion",PROTOCOL_VERSION);
if(g_connman)
obj.pushKV("localservices", strprintf("%016x", g_connman->GetLocalServices()));
- obj.pushKV("localrelay", fRelayTxes);
+ obj.pushKV("localrelay", g_relay_txes);
obj.pushKV("timeoffset", GetTimeOffset());
if (g_connman) {
obj.pushKV("networkactive", g_connman->GetNetworkActive());
diff --git a/src/rpc/protocol.cpp b/src/rpc/protocol.cpp
index 23999b305a..33b0130a94 100644
--- a/src/rpc/protocol.cpp
+++ b/src/rpc/protocol.cpp
@@ -10,7 +10,6 @@
#include <util/system.h>
#include <util/strencodings.h>
#include <util/time.h>
-#include <version.h>
/**
* JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility,
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index eabf89bdba..966ff3fedc 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -6,21 +6,16 @@
#include <chain.h>
#include <coins.h>
#include <compat/byteswap.h>
-#include <consensus/tx_verify.h>
#include <consensus/validation.h>
#include <core_io.h>
#include <index/txindex.h>
-#include <init.h>
-#include <interfaces/chain.h>
#include <key_io.h>
#include <keystore.h>
#include <merkleblock.h>
#include <node/coin.h>
#include <node/psbt.h>
#include <node/transaction.h>
-#include <policy/policy.h>
#include <policy/rbf.h>
-#include <policy/settings.h>
#include <primitives/transaction.h>
#include <psbt.h>
#include <rpc/rawtransaction_util.h>
@@ -31,7 +26,6 @@
#include <script/sign.h>
#include <script/standard.h>
#include <uint256.h>
-#include <util/bip32.h>
#include <util/moneystr.h>
#include <util/strencodings.h>
#include <validation.h>
@@ -45,7 +39,7 @@
/** High fee for sendrawtransaction and testmempoolaccept.
* By default, transaction with a fee higher than this will be rejected by the
- * RPCs. This can be overriden with the maxfeerate argument.
+ * RPCs. This can be overridden with the maxfeerate argument.
*/
constexpr static CAmount DEFAULT_MAX_RAW_TX_FEE{COIN / 10};
@@ -202,7 +196,7 @@ static UniValue getrawtransaction(const JSONRPCRequest& request)
}
errmsg = "No such transaction found in the provided block";
} else if (!g_txindex) {
- errmsg = "No such mempool transaction. Use -txindex to enable blockchain transaction queries";
+ errmsg = "No such mempool transaction. Use -txindex or provide a block hash to enable blockchain transaction queries";
} else if (!f_txindex_ready) {
errmsg = "No such mempool transaction. Blockchain transactions are still in the process of being indexed";
} else {
@@ -432,14 +426,17 @@ static UniValue createrawtransaction(const JSONRPCRequest& request)
static UniValue decoderawtransaction(const JSONRPCRequest& request)
{
- if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
- throw std::runtime_error(
- RPCHelpMan{"decoderawtransaction",
+ const RPCHelpMan help{"decoderawtransaction",
"\nReturn a JSON object representing the serialized, hex-encoded transaction.\n",
{
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction hex string"},
- {"iswitness", RPCArg::Type::BOOL, /* default */ "depends on heuristic tests", "Whether the transaction hex is a serialized witness transaction\n"
- " If iswitness is not present, heuristic tests will be used in decoding"},
+ {"iswitness", RPCArg::Type::BOOL, /* default */ "depends on heuristic tests", "Whether the transaction hex is a serialized witness transaction.\n"
+ "If iswitness is not present, heuristic tests will be used in decoding.\n"
+ "If true, only witness deserialization will be tried.\n"
+ "If false, only non-witness deserialization will be tried.\n"
+ "This boolean should reflect whether the transaction has inputs\n"
+ "(e.g. fully valid, or on-chain transactions), if known by the caller."
+ },
},
RPCResult{
"{\n"
@@ -486,7 +483,11 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request)
HelpExampleCli("decoderawtransaction", "\"hexstring\"")
+ HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
},
- }.ToString());
+ };
+
+ if (request.fHelp || !help.IsValidNumArgs(request.params.size())) {
+ throw std::runtime_error(help.ToString());
+ }
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL});
@@ -748,8 +749,8 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
"}\n"
},
RPCExamples{
- HelpExampleCli("signrawtransactionwithkey", "\"myhex\"")
- + HelpExampleRpc("signrawtransactionwithkey", "\"myhex\"")
+ HelpExampleCli("signrawtransactionwithkey", "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"")
+ + HelpExampleRpc("signrawtransactionwithkey", "\"myhex\", \"[\\\"key1\\\",\\\"key2\\\"]\"")
},
}.ToString());
@@ -1423,19 +1424,20 @@ UniValue createpsbt(const JSONRPCRequest& request)
UniValue converttopsbt(const JSONRPCRequest& request)
{
- if (request.fHelp || request.params.size() < 1 || request.params.size() > 3)
- throw std::runtime_error(
- RPCHelpMan{"converttopsbt",
+ const RPCHelpMan help{"converttopsbt",
"\nConverts a network serialized transaction to a PSBT. This should be used only with createrawtransaction and fundrawtransaction\n"
"createpsbt and walletcreatefundedpsbt should be used for new applications.\n",
{
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of a raw transaction"},
- {"permitsigdata", RPCArg::Type::BOOL, /* default */ "false", "If true, any signatures in the input will be discarded and conversion.\n"
+ {"permitsigdata", RPCArg::Type::BOOL, /* default */ "false", "If true, any signatures in the input will be discarded and conversion\n"
" will continue. If false, RPC will fail if any signatures are present."},
{"iswitness", RPCArg::Type::BOOL, /* default */ "depends on heuristic tests", "Whether the transaction hex is a serialized witness transaction.\n"
- " If iswitness is not present, heuristic tests will be used in decoding. If true, only witness deserializaion\n"
- " will be tried. If false, only non-witness deserialization will be tried. Only has an effect if\n"
- " permitsigdata is true."},
+ "If iswitness is not present, heuristic tests will be used in decoding.\n"
+ "If true, only witness deserialization will be tried.\n"
+ "If false, only non-witness deserialization will be tried.\n"
+ "This boolean should reflect whether the transaction has inputs\n"
+ "(e.g. fully valid, or on-chain transactions), if known by the caller."
+ },
},
RPCResult{
" \"psbt\" (string) The resulting raw transaction (base64-encoded string)\n"
@@ -1446,8 +1448,11 @@ UniValue converttopsbt(const JSONRPCRequest& request)
"\nConvert the transaction to a PSBT\n"
+ HelpExampleCli("converttopsbt", "\"rawtransaction\"")
},
- }.ToString());
+ };
+ if (request.fHelp || !help.IsValidNumArgs(request.params.size())) {
+ throw std::runtime_error(help.ToString());
+ }
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL, UniValue::VBOOL}, true);
@@ -1456,8 +1461,8 @@ UniValue converttopsbt(const JSONRPCRequest& request)
bool permitsigdata = request.params[1].isNull() ? false : request.params[1].get_bool();
bool witness_specified = !request.params[2].isNull();
bool iswitness = witness_specified ? request.params[2].get_bool() : false;
- bool try_witness = permitsigdata ? (witness_specified ? iswitness : true) : false;
- bool try_no_witness = permitsigdata ? (witness_specified ? !iswitness : true) : true;
+ const bool try_witness = witness_specified ? iswitness : true;
+ const bool try_no_witness = witness_specified ? !iswitness : true;
if (!DecodeHexTx(tx, request.params[0].get_str(), try_no_witness, try_witness)) {
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
}
diff --git a/src/rpc/rawtransaction_util.cpp b/src/rpc/rawtransaction_util.cpp
index 8af491977c..9c4cdc3a90 100644
--- a/src/rpc/rawtransaction_util.cpp
+++ b/src/rpc/rawtransaction_util.cpp
@@ -7,7 +7,6 @@
#include <coins.h>
#include <core_io.h>
-#include <interfaces/chain.h>
#include <key_io.h>
#include <keystore.h>
#include <policy/policy.h>
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index 9df4070cbb..ca17d379bc 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -7,11 +7,9 @@
#include <fs.h>
#include <key_io.h>
-#include <random.h>
#include <rpc/util.h>
#include <shutdown.h>
#include <sync.h>
-#include <ui_interface.h>
#include <util/strencodings.h>
#include <util/system.h>
diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp
index 7a9312aa03..67ccb225b5 100644
--- a/src/rpc/util.cpp
+++ b/src/rpc/util.cpp
@@ -4,6 +4,7 @@
#include <key_io.h>
#include <keystore.h>
+#include <outputtype.h>
#include <rpc/util.h>
#include <script/descriptor.h>
#include <tinyformat.h>
@@ -151,8 +152,8 @@ CPubKey AddrToPubKey(CKeyStore* const keystore, const std::string& addr_in)
return vchPubKey;
}
-// Creates a multisig redeemscript from a given list of public keys and number required.
-CScript CreateMultisigRedeemscript(const int required, const std::vector<CPubKey>& pubkeys)
+// Creates a multisig address from a given list of public keys, number of signatures required, and the address type
+CTxDestination AddAndGetMultisigDestination(const int required, const std::vector<CPubKey>& pubkeys, OutputType type, CKeyStore& keystore, CScript& script_out)
{
// Gather public keys
if (required < 1) {
@@ -165,13 +166,24 @@ CScript CreateMultisigRedeemscript(const int required, const std::vector<CPubKey
throw JSONRPCError(RPC_INVALID_PARAMETER, "Number of keys involved in the multisignature address creation > 16\nReduce the number");
}
- CScript result = GetScriptForMultisig(required, pubkeys);
+ script_out = GetScriptForMultisig(required, pubkeys);
- if (result.size() > MAX_SCRIPT_ELEMENT_SIZE) {
- throw JSONRPCError(RPC_INVALID_PARAMETER, (strprintf("redeemScript exceeds size limit: %d > %d", result.size(), MAX_SCRIPT_ELEMENT_SIZE)));
+ if (script_out.size() > MAX_SCRIPT_ELEMENT_SIZE) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, (strprintf("redeemScript exceeds size limit: %d > %d", script_out.size(), MAX_SCRIPT_ELEMENT_SIZE)));
}
- return result;
+ // Check if any keys are uncompressed. If so, the type is legacy
+ for (const CPubKey& pk : pubkeys) {
+ if (!pk.IsCompressed()) {
+ type = OutputType::LEGACY;
+ break;
+ }
+ }
+
+ // Make the address
+ CTxDestination dest = AddAndGetDestinationForScript(keystore, script_out, type);
+
+ return dest;
}
class DescribeAddressVisitor : public boost::static_visitor<UniValue>
diff --git a/src/rpc/util.h b/src/rpc/util.h
index ce485a2095..8762281d73 100644
--- a/src/rpc/util.h
+++ b/src/rpc/util.h
@@ -6,6 +6,7 @@
#define BITCOIN_RPC_UTIL_H
#include <node/transaction.h>
+#include <outputtype.h>
#include <pubkey.h>
#include <rpc/protocol.h>
#include <script/script.h>
@@ -72,7 +73,7 @@ extern std::string HelpExampleRpc(const std::string& methodname, const std::stri
CPubKey HexToPubKey(const std::string& hex_in);
CPubKey AddrToPubKey(CKeyStore* const keystore, const std::string& addr_in);
-CScript CreateMultisigRedeemscript(const int required, const std::vector<CPubKey>& pubkeys);
+CTxDestination AddAndGetMultisigDestination(const int required, const std::vector<CPubKey>& pubkeys, OutputType type, CKeyStore& keystore, CScript& script_out);
UniValue DescribeAddress(const CTxDestination& dest);