mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-06-02 15:32:34 +02:00
rpc: Run type check against RPCArgs
This commit is contained in:
parent
faf96721a6
commit
fa9f6d7bcd
@ -444,11 +444,6 @@ static RPCHelpMan getblockfrompeer()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {
|
|
||||||
UniValue::VSTR, // blockhash
|
|
||||||
UniValue::VNUM, // peer_id
|
|
||||||
});
|
|
||||||
|
|
||||||
const NodeContext& node = EnsureAnyNodeContext(request.context);
|
const NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
ChainstateManager& chainman = EnsureChainman(node);
|
ChainstateManager& chainman = EnsureChainman(node);
|
||||||
PeerManager& peerman = EnsurePeerman(node);
|
PeerManager& peerman = EnsurePeerman(node);
|
||||||
@ -654,7 +649,8 @@ static RPCHelpMan getblock()
|
|||||||
"If verbosity is 3, returns an Object with information about block <hash> and information about each transaction, including prevout information for inputs (only for unpruned blocks in the current best chain).\n",
|
"If verbosity is 3, returns an Object with information about block <hash> and information about each transaction, including prevout information for inputs (only for unpruned blocks in the current best chain).\n",
|
||||||
{
|
{
|
||||||
{"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"},
|
{"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"},
|
||||||
{"verbosity|verbose", RPCArg::Type::NUM, RPCArg::Default{1}, "0 for hex-encoded data, 1 for a JSON object, 2 for JSON object with transaction data, and 3 for JSON object with transaction data including prevout information for inputs"},
|
{"verbosity|verbose", RPCArg::Type::NUM, RPCArg::Default{1}, "0 for hex-encoded data, 1 for a JSON object, 2 for JSON object with transaction data, and 3 for JSON object with transaction data including prevout information for inputs",
|
||||||
|
RPCArgOptions{.skip_type_check = true}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
RPCResult{"for verbosity = 0",
|
RPCResult{"for verbosity = 0",
|
||||||
@ -872,7 +868,11 @@ static RPCHelpMan gettxoutsetinfo()
|
|||||||
"Note this call may take some time if you are not using coinstatsindex.\n",
|
"Note this call may take some time if you are not using coinstatsindex.\n",
|
||||||
{
|
{
|
||||||
{"hash_type", RPCArg::Type::STR, RPCArg::Default{"hash_serialized_2"}, "Which UTXO set hash should be calculated. Options: 'hash_serialized_2' (the legacy algorithm), 'muhash', 'none'."},
|
{"hash_type", RPCArg::Type::STR, RPCArg::Default{"hash_serialized_2"}, "Which UTXO set hash should be calculated. Options: 'hash_serialized_2' (the legacy algorithm), 'muhash', 'none'."},
|
||||||
{"hash_or_height", RPCArg::Type::NUM, RPCArg::DefaultHint{"the current best block"}, "The block hash or height of the target height (only available with coinstatsindex).", RPCArgOptions{.type_str={"", "string or numeric"}}},
|
{"hash_or_height", RPCArg::Type::NUM, RPCArg::DefaultHint{"the current best block"}, "The block hash or height of the target height (only available with coinstatsindex).",
|
||||||
|
RPCArgOptions{
|
||||||
|
.skip_type_check = true,
|
||||||
|
.type_str = {"", "string or numeric"},
|
||||||
|
}},
|
||||||
{"use_index", RPCArg::Type::BOOL, RPCArg::Default{true}, "Use coinstatsindex, if available."},
|
{"use_index", RPCArg::Type::BOOL, RPCArg::Default{true}, "Use coinstatsindex, if available."},
|
||||||
},
|
},
|
||||||
RPCResult{
|
RPCResult{
|
||||||
@ -1742,7 +1742,11 @@ static RPCHelpMan getblockstats()
|
|||||||
"\nCompute per block statistics for a given window. All amounts are in satoshis.\n"
|
"\nCompute per block statistics for a given window. All amounts are in satoshis.\n"
|
||||||
"It won't work for some heights with pruning.\n",
|
"It won't work for some heights with pruning.\n",
|
||||||
{
|
{
|
||||||
{"hash_or_height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The block hash or height of the target block", RPCArgOptions{.type_str={"", "string or numeric"}}},
|
{"hash_or_height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The block hash or height of the target block",
|
||||||
|
RPCArgOptions{
|
||||||
|
.skip_type_check = true,
|
||||||
|
.type_str = {"", "string or numeric"},
|
||||||
|
}},
|
||||||
{"stats", RPCArg::Type::ARR, RPCArg::DefaultHint{"all values"}, "Values to plot (see result below)",
|
{"stats", RPCArg::Type::ARR, RPCArg::DefaultHint{"all values"}, "Values to plot (see result below)",
|
||||||
{
|
{
|
||||||
{"height", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Selected statistic"},
|
{"height", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Selected statistic"},
|
||||||
@ -2144,8 +2148,6 @@ static RPCHelpMan scantxoutset()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR});
|
|
||||||
|
|
||||||
UniValue result(UniValue::VOBJ);
|
UniValue result(UniValue::VOBJ);
|
||||||
if (request.params[0].get_str() == "status") {
|
if (request.params[0].get_str() == "status") {
|
||||||
CoinsViewScanReserver reserver;
|
CoinsViewScanReserver reserver;
|
||||||
|
@ -63,8 +63,6 @@ static RPCHelpMan estimatesmartfee()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VSTR});
|
|
||||||
|
|
||||||
CBlockPolicyEstimator& fee_estimator = EnsureAnyFeeEstimator(request.context);
|
CBlockPolicyEstimator& fee_estimator = EnsureAnyFeeEstimator(request.context);
|
||||||
const NodeContext& node = EnsureAnyNodeContext(request.context);
|
const NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
const CTxMemPool& mempool = EnsureMemPool(node);
|
const CTxMemPool& mempool = EnsureMemPool(node);
|
||||||
@ -155,8 +153,6 @@ static RPCHelpMan estimaterawfee()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VNUM}, true);
|
|
||||||
|
|
||||||
CBlockPolicyEstimator& fee_estimator = EnsureAnyFeeEstimator(request.context);
|
CBlockPolicyEstimator& fee_estimator = EnsureAnyFeeEstimator(request.context);
|
||||||
|
|
||||||
unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
||||||
|
@ -61,11 +61,6 @@ static RPCHelpMan sendrawtransaction()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {
|
|
||||||
UniValue::VSTR,
|
|
||||||
UniValueType(), // VNUM or VSTR, checked inside AmountFromValue()
|
|
||||||
});
|
|
||||||
|
|
||||||
CMutableTransaction mtx;
|
CMutableTransaction mtx;
|
||||||
if (!DecodeHexTx(mtx, request.params[0].get_str())) {
|
if (!DecodeHexTx(mtx, request.params[0].get_str())) {
|
||||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input.");
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input.");
|
||||||
@ -147,10 +142,6 @@ static RPCHelpMan testmempoolaccept()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {
|
|
||||||
UniValue::VARR,
|
|
||||||
UniValueType(), // VNUM or VSTR, checked inside AmountFromValue()
|
|
||||||
});
|
|
||||||
const UniValue raw_transactions = request.params[0].get_array();
|
const UniValue raw_transactions = request.params[0].get_array();
|
||||||
if (raw_transactions.size() < 1 || raw_transactions.size() > MAX_PACKAGE_COUNT) {
|
if (raw_transactions.size() < 1 || raw_transactions.size() > MAX_PACKAGE_COUNT) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER,
|
throw JSONRPCError(RPC_INVALID_PARAMETER,
|
||||||
@ -800,9 +791,6 @@ static RPCHelpMan submitpackage()
|
|||||||
if (!Params().IsMockableChain()) {
|
if (!Params().IsMockableChain()) {
|
||||||
throw std::runtime_error("submitpackage is for regression testing (-regtest mode) only");
|
throw std::runtime_error("submitpackage is for regression testing (-regtest mode) only");
|
||||||
}
|
}
|
||||||
RPCTypeCheck(request.params, {
|
|
||||||
UniValue::VARR,
|
|
||||||
});
|
|
||||||
const UniValue raw_transactions = request.params[0].get_array();
|
const UniValue raw_transactions = request.params[0].get_array();
|
||||||
if (raw_transactions.size() < 1 || raw_transactions.size() > MAX_PACKAGE_COUNT) {
|
if (raw_transactions.size() < 1 || raw_transactions.size() > MAX_PACKAGE_COUNT) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER,
|
throw JSONRPCError(RPC_INVALID_PARAMETER,
|
||||||
|
@ -362,7 +362,6 @@ static RPCHelpMan addconnection()
|
|||||||
throw std::runtime_error("addconnection is for regression testing (-regtest mode) only.");
|
throw std::runtime_error("addconnection is for regression testing (-regtest mode) only.");
|
||||||
}
|
}
|
||||||
|
|
||||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VSTR});
|
|
||||||
const std::string address = request.params[0].get_str();
|
const std::string address = request.params[0].get_str();
|
||||||
const std::string conn_type_in{TrimString(request.params[1].get_str())};
|
const std::string conn_type_in{TrimString(request.params[1].get_str())};
|
||||||
ConnectionType conn_type{};
|
ConnectionType conn_type{};
|
||||||
|
@ -52,7 +52,6 @@ static RPCHelpMan setmocktime()
|
|||||||
// ensure all call sites of GetTime() are accessing this safely.
|
// ensure all call sites of GetTime() are accessing this safely.
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
|
||||||
RPCTypeCheck(request.params, {UniValue::VNUM});
|
|
||||||
const int64_t time{request.params[0].getInt<int64_t>()};
|
const int64_t time{request.params[0].getInt<int64_t>()};
|
||||||
if (time < 0) {
|
if (time < 0) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Mocktime cannot be negative: %s.", time));
|
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Mocktime cannot be negative: %s.", time));
|
||||||
@ -106,8 +105,6 @@ static RPCHelpMan mockscheduler()
|
|||||||
throw std::runtime_error("mockscheduler is for regression testing (-regtest mode) only");
|
throw std::runtime_error("mockscheduler is for regression testing (-regtest mode) only");
|
||||||
}
|
}
|
||||||
|
|
||||||
// check params are valid values
|
|
||||||
RPCTypeCheck(request.params, {UniValue::VNUM});
|
|
||||||
int64_t delta_seconds = request.params[0].getInt<int64_t>();
|
int64_t delta_seconds = request.params[0].getInt<int64_t>();
|
||||||
if (delta_seconds <= 0 || delta_seconds > 3600) {
|
if (delta_seconds <= 0 || delta_seconds > 3600) {
|
||||||
throw std::runtime_error("delta_time must be between 1 and 3600 seconds (1 hr)");
|
throw std::runtime_error("delta_time must be between 1 and 3600 seconds (1 hr)");
|
||||||
@ -295,18 +292,18 @@ static RPCHelpMan echo(const std::string& name)
|
|||||||
"\nIt will return an internal bug report when arg9='trigger_internal_bug' is passed.\n"
|
"\nIt will return an internal bug report when arg9='trigger_internal_bug' is passed.\n"
|
||||||
"\nThe difference between echo and echojson is that echojson has argument conversion enabled in the client-side table in "
|
"\nThe difference between echo and echojson is that echojson has argument conversion enabled in the client-side table in "
|
||||||
"bitcoin-cli and the GUI. There is no server-side difference.",
|
"bitcoin-cli and the GUI. There is no server-side difference.",
|
||||||
{
|
{
|
||||||
{"arg0", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""},
|
{"arg0", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "", RPCArgOptions{.skip_type_check = true}},
|
||||||
{"arg1", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""},
|
{"arg1", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "", RPCArgOptions{.skip_type_check = true}},
|
||||||
{"arg2", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""},
|
{"arg2", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "", RPCArgOptions{.skip_type_check = true}},
|
||||||
{"arg3", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""},
|
{"arg3", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "", RPCArgOptions{.skip_type_check = true}},
|
||||||
{"arg4", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""},
|
{"arg4", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "", RPCArgOptions{.skip_type_check = true}},
|
||||||
{"arg5", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""},
|
{"arg5", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "", RPCArgOptions{.skip_type_check = true}},
|
||||||
{"arg6", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""},
|
{"arg6", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "", RPCArgOptions{.skip_type_check = true}},
|
||||||
{"arg7", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""},
|
{"arg7", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "", RPCArgOptions{.skip_type_check = true}},
|
||||||
{"arg8", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""},
|
{"arg8", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "", RPCArgOptions{.skip_type_check = true}},
|
||||||
{"arg9", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, ""},
|
{"arg9", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "", RPCArgOptions{.skip_type_check = true}},
|
||||||
},
|
},
|
||||||
RPCResult{RPCResult::Type::ANY, "", "Returns whatever was passed in"},
|
RPCResult{RPCResult::Type::ANY, "", "Returns whatever was passed in"},
|
||||||
RPCExamples{""},
|
RPCExamples{""},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
|
@ -195,8 +195,6 @@ static RPCHelpMan getdescriptorinfo()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {UniValue::VSTR});
|
|
||||||
|
|
||||||
FlatSigningProvider provider;
|
FlatSigningProvider provider;
|
||||||
std::string error;
|
std::string error;
|
||||||
auto desc = Parse(request.params[0].get_str(), provider, error);
|
auto desc = Parse(request.params[0].get_str(), provider, error);
|
||||||
@ -247,7 +245,6 @@ static RPCHelpMan deriveaddresses()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValueType()}); // Range argument is checked later
|
|
||||||
const std::string desc_str = request.params[0].get_str();
|
const std::string desc_str = request.params[0].get_str();
|
||||||
|
|
||||||
int64_t range_begin = 0;
|
int64_t range_begin = 0;
|
||||||
|
@ -162,7 +162,7 @@ static std::vector<RPCArg> CreateTxDoc()
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
RPCArgOptions{.skip_type_check = true}},
|
||||||
{"locktime", RPCArg::Type::NUM, RPCArg::Default{0}, "Raw locktime. Non-0 value also locktime-activates inputs"},
|
{"locktime", RPCArg::Type::NUM, RPCArg::Default{0}, "Raw locktime. Non-0 value also locktime-activates inputs"},
|
||||||
{"replaceable", RPCArg::Type::BOOL, RPCArg::Default{true}, "Marks this transaction as BIP125-replaceable.\n"
|
{"replaceable", RPCArg::Type::BOOL, RPCArg::Default{true}, "Marks this transaction as BIP125-replaceable.\n"
|
||||||
"Allows this transaction to be replaced by a transaction with higher fees. If provided, it is an error if explicit sequence numbers are incompatible."},
|
"Allows this transaction to be replaced by a transaction with higher fees. If provided, it is an error if explicit sequence numbers are incompatible."},
|
||||||
@ -185,7 +185,8 @@ static RPCHelpMan getrawtransaction()
|
|||||||
"If verbosity is 2, returns a JSON Object with information about the transaction, including fee and prevout information.",
|
"If verbosity is 2, returns a JSON Object with information about the transaction, including fee and prevout information.",
|
||||||
{
|
{
|
||||||
{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
|
{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
|
||||||
{"verbosity|verbose", RPCArg::Type::NUM, RPCArg::Default{0}, "0 for hex-encoded data, 1 for a JSON object, and 2 for JSON object with fee and prevout"},
|
{"verbosity|verbose", RPCArg::Type::NUM, RPCArg::Default{0}, "0 for hex-encoded data, 1 for a JSON object, and 2 for JSON object with fee and prevout",
|
||||||
|
RPCArgOptions{.skip_type_check = true}},
|
||||||
{"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED_NAMED_ARG, "The block in which to look for the transaction"},
|
{"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED_NAMED_ARG, "The block in which to look for the transaction"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -354,14 +355,6 @@ static RPCHelpMan createrawtransaction()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {
|
|
||||||
UniValue::VARR,
|
|
||||||
UniValueType(), // ARR or OBJ, checked later
|
|
||||||
UniValue::VNUM,
|
|
||||||
UniValue::VBOOL
|
|
||||||
}, true
|
|
||||||
);
|
|
||||||
|
|
||||||
std::optional<bool> rbf;
|
std::optional<bool> rbf;
|
||||||
if (!request.params[3].isNull()) {
|
if (!request.params[3].isNull()) {
|
||||||
rbf = request.params[3].get_bool();
|
rbf = request.params[3].get_bool();
|
||||||
@ -397,8 +390,6 @@ static RPCHelpMan decoderawtransaction()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL});
|
|
||||||
|
|
||||||
CMutableTransaction mtx;
|
CMutableTransaction mtx;
|
||||||
|
|
||||||
bool try_witness = request.params[1].isNull() ? true : request.params[1].get_bool();
|
bool try_witness = request.params[1].isNull() ? true : request.params[1].get_bool();
|
||||||
@ -451,8 +442,6 @@ static RPCHelpMan decodescript()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {UniValue::VSTR});
|
|
||||||
|
|
||||||
UniValue r(UniValue::VOBJ);
|
UniValue r(UniValue::VOBJ);
|
||||||
CScript script;
|
CScript script;
|
||||||
if (request.params[0].get_str().size() > 0){
|
if (request.params[0].get_str().size() > 0){
|
||||||
@ -702,8 +691,6 @@ static RPCHelpMan signrawtransactionwithkey()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true);
|
|
||||||
|
|
||||||
CMutableTransaction mtx;
|
CMutableTransaction mtx;
|
||||||
if (!DecodeHexTx(mtx, request.params[0].get_str())) {
|
if (!DecodeHexTx(mtx, request.params[0].get_str())) {
|
||||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input.");
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input.");
|
||||||
@ -981,8 +968,6 @@ static RPCHelpMan decodepsbt()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {UniValue::VSTR});
|
|
||||||
|
|
||||||
// Unserialize the transactions
|
// Unserialize the transactions
|
||||||
PartiallySignedTransaction psbtx;
|
PartiallySignedTransaction psbtx;
|
||||||
std::string error;
|
std::string error;
|
||||||
@ -1395,8 +1380,6 @@ static RPCHelpMan combinepsbt()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {UniValue::VARR}, true);
|
|
||||||
|
|
||||||
// Unserialize the transactions
|
// Unserialize the transactions
|
||||||
std::vector<PartiallySignedTransaction> psbtxs;
|
std::vector<PartiallySignedTransaction> psbtxs;
|
||||||
UniValue txs = request.params[0].get_array();
|
UniValue txs = request.params[0].get_array();
|
||||||
@ -1450,8 +1433,6 @@ static RPCHelpMan finalizepsbt()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}, true);
|
|
||||||
|
|
||||||
// Unserialize the transactions
|
// Unserialize the transactions
|
||||||
PartiallySignedTransaction psbtx;
|
PartiallySignedTransaction psbtx;
|
||||||
std::string error;
|
std::string error;
|
||||||
@ -1499,14 +1480,6 @@ static RPCHelpMan createpsbt()
|
|||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
|
|
||||||
RPCTypeCheck(request.params, {
|
|
||||||
UniValue::VARR,
|
|
||||||
UniValueType(), // ARR or OBJ, checked later
|
|
||||||
UniValue::VNUM,
|
|
||||||
UniValue::VBOOL,
|
|
||||||
}, true
|
|
||||||
);
|
|
||||||
|
|
||||||
std::optional<bool> rbf;
|
std::optional<bool> rbf;
|
||||||
if (!request.params[3].isNull()) {
|
if (!request.params[3].isNull()) {
|
||||||
rbf = request.params[3].get_bool();
|
rbf = request.params[3].get_bool();
|
||||||
@ -1560,8 +1533,6 @@ static RPCHelpMan converttopsbt()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL, UniValue::VBOOL}, true);
|
|
||||||
|
|
||||||
// parse hex string from parameter
|
// parse hex string from parameter
|
||||||
CMutableTransaction tx;
|
CMutableTransaction tx;
|
||||||
bool permitsigdata = request.params[1].isNull() ? false : request.params[1].get_bool();
|
bool permitsigdata = request.params[1].isNull() ? false : request.params[1].get_bool();
|
||||||
@ -1623,8 +1594,6 @@ static RPCHelpMan utxoupdatepsbt()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR}, true);
|
|
||||||
|
|
||||||
// Unserialize the transactions
|
// Unserialize the transactions
|
||||||
PartiallySignedTransaction psbtx;
|
PartiallySignedTransaction psbtx;
|
||||||
std::string error;
|
std::string error;
|
||||||
@ -1714,8 +1683,6 @@ static RPCHelpMan joinpsbts()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {UniValue::VARR}, true);
|
|
||||||
|
|
||||||
// Unserialize the transactions
|
// Unserialize the transactions
|
||||||
std::vector<PartiallySignedTransaction> psbtxs;
|
std::vector<PartiallySignedTransaction> psbtxs;
|
||||||
UniValue txs = request.params[0].get_array();
|
UniValue txs = request.params[0].get_array();
|
||||||
@ -1842,8 +1809,6 @@ static RPCHelpMan analyzepsbt()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {UniValue::VSTR});
|
|
||||||
|
|
||||||
// Unserialize the transaction
|
// Unserialize the transaction
|
||||||
PartiallySignedTransaction psbtx;
|
PartiallySignedTransaction psbtx;
|
||||||
std::string error;
|
std::string error;
|
||||||
|
@ -30,23 +30,6 @@ std::string GetAllOutputTypes()
|
|||||||
return Join(ret, ", ");
|
return Join(ret, ", ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RPCTypeCheck(const UniValue& params,
|
|
||||||
const std::list<UniValueType>& typesExpected,
|
|
||||||
bool fAllowNull)
|
|
||||||
{
|
|
||||||
unsigned int i = 0;
|
|
||||||
for (const UniValueType& t : typesExpected) {
|
|
||||||
if (params.size() <= i)
|
|
||||||
break;
|
|
||||||
|
|
||||||
const UniValue& v = params[i];
|
|
||||||
if (!(fAllowNull && v.isNull())) {
|
|
||||||
RPCTypeCheckArgument(v, t);
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RPCTypeCheckArgument(const UniValue& value, const UniValueType& typeExpected)
|
void RPCTypeCheckArgument(const UniValue& value, const UniValueType& typeExpected)
|
||||||
{
|
{
|
||||||
if (!typeExpected.typeAny && value.type() != typeExpected.type) {
|
if (!typeExpected.typeAny && value.type() != typeExpected.type) {
|
||||||
@ -579,6 +562,9 @@ UniValue RPCHelpMan::HandleRequest(const JSONRPCRequest& request) const
|
|||||||
if (request.mode == JSONRPCRequest::GET_HELP || !IsValidNumArgs(request.params.size())) {
|
if (request.mode == JSONRPCRequest::GET_HELP || !IsValidNumArgs(request.params.size())) {
|
||||||
throw std::runtime_error(ToString());
|
throw std::runtime_error(ToString());
|
||||||
}
|
}
|
||||||
|
for (size_t i{0}; i < m_args.size(); ++i) {
|
||||||
|
m_args.at(i).MatchesType(request.params[i]);
|
||||||
|
}
|
||||||
UniValue ret = m_fun(*this, request);
|
UniValue ret = m_fun(*this, request);
|
||||||
if (gArgs.GetBoolArg("-rpcdoccheck", DEFAULT_RPC_DOC_CHECK)) {
|
if (gArgs.GetBoolArg("-rpcdoccheck", DEFAULT_RPC_DOC_CHECK)) {
|
||||||
CHECK_NONFATAL(std::any_of(m_results.m_results.begin(), m_results.m_results.end(), [&ret](const RPCResult& res) { return res.MatchesType(ret); }));
|
CHECK_NONFATAL(std::any_of(m_results.m_results.begin(), m_results.m_results.end(), [&ret](const RPCResult& res) { return res.MatchesType(ret); }));
|
||||||
@ -677,6 +663,44 @@ UniValue RPCHelpMan::GetArgMap() const
|
|||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RPCArg::MatchesType(const UniValue& request) const
|
||||||
|
{
|
||||||
|
if (m_opts.skip_type_check) return;
|
||||||
|
if (IsOptional() && request.isNull()) return;
|
||||||
|
switch (m_type) {
|
||||||
|
case Type::STR_HEX:
|
||||||
|
case Type::STR: {
|
||||||
|
RPCTypeCheckArgument(request, UniValue::VSTR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case Type::NUM: {
|
||||||
|
RPCTypeCheckArgument(request, UniValue::VNUM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case Type::AMOUNT: {
|
||||||
|
// VNUM or VSTR, checked inside AmountFromValue()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case Type::RANGE: {
|
||||||
|
// VNUM or VARR, checked inside ParseRange()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case Type::BOOL: {
|
||||||
|
RPCTypeCheckArgument(request, UniValue::VBOOL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case Type::OBJ:
|
||||||
|
case Type::OBJ_USER_KEYS: {
|
||||||
|
RPCTypeCheckArgument(request, UniValue::VOBJ);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case Type::ARR: {
|
||||||
|
RPCTypeCheckArgument(request, UniValue::VARR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} // no default case, so the compiler can warn about missing cases
|
||||||
|
}
|
||||||
|
|
||||||
std::string RPCArg::GetFirstName() const
|
std::string RPCArg::GetFirstName() const
|
||||||
{
|
{
|
||||||
return m_names.substr(0, m_names.find("|"));
|
return m_names.substr(0, m_names.find("|"));
|
||||||
|
@ -62,13 +62,6 @@ struct UniValueType {
|
|||||||
UniValue::VType type;
|
UniValue::VType type;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Type-check arguments; throws JSONRPCError if wrong type given. Does not check that
|
|
||||||
* the right number of arguments are passed, just that any passed are the correct type.
|
|
||||||
*/
|
|
||||||
void RPCTypeCheck(const UniValue& params,
|
|
||||||
const std::list<UniValueType>& typesExpected, bool fAllowNull=false);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type-check one argument; throws JSONRPCError if wrong type given.
|
* Type-check one argument; throws JSONRPCError if wrong type given.
|
||||||
*/
|
*/
|
||||||
@ -138,6 +131,7 @@ enum class OuterType {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct RPCArgOptions {
|
struct RPCArgOptions {
|
||||||
|
bool skip_type_check{false};
|
||||||
std::string oneline_description{}; //!< Should be empty unless it is supposed to override the auto-generated summary line
|
std::string oneline_description{}; //!< Should be empty unless it is supposed to override the auto-generated summary line
|
||||||
std::vector<std::string> type_str{}; //!< Should be empty unless it is supposed to override the auto-generated type strings. Vector length is either 0 or 2, m_opts.type_str.at(0) will override the type of the value in a key-value pair, m_opts.type_str.at(1) will override the type in the argument description.
|
std::vector<std::string> type_str{}; //!< Should be empty unless it is supposed to override the auto-generated type strings. Vector length is either 0 or 2, m_opts.type_str.at(0) will override the type of the value in a key-value pair, m_opts.type_str.at(1) will override the type in the argument description.
|
||||||
bool hidden{false}; //!< For testing only
|
bool hidden{false}; //!< For testing only
|
||||||
@ -217,6 +211,9 @@ struct RPCArg {
|
|||||||
|
|
||||||
bool IsOptional() const;
|
bool IsOptional() const;
|
||||||
|
|
||||||
|
/** Check whether the request JSON type matches. */
|
||||||
|
void MatchesType(const UniValue& request) const;
|
||||||
|
|
||||||
/** Return the first of all aliases */
|
/** Return the first of all aliases */
|
||||||
std::string GetFirstName() const;
|
std::string GetFirstName() const;
|
||||||
|
|
||||||
|
@ -1330,8 +1330,6 @@ RPCHelpMan importmulti()
|
|||||||
// the user could have gotten from another RPC command prior to now
|
// the user could have gotten from another RPC command prior to now
|
||||||
wallet.BlockUntilSyncedToCurrentChain();
|
wallet.BlockUntilSyncedToCurrentChain();
|
||||||
|
|
||||||
RPCTypeCheck(mainRequest.params, {UniValue::VARR, UniValue::VOBJ});
|
|
||||||
|
|
||||||
EnsureLegacyScriptPubKeyMan(*pwallet, true);
|
EnsureLegacyScriptPubKeyMan(*pwallet, true);
|
||||||
|
|
||||||
const UniValue& requests = mainRequest.params[0];
|
const UniValue& requests = mainRequest.params[0];
|
||||||
@ -1652,8 +1650,6 @@ RPCHelpMan importdescriptors()
|
|||||||
throw JSONRPCError(RPC_WALLET_ERROR, "importdescriptors is not available for non-descriptor wallets");
|
throw JSONRPCError(RPC_WALLET_ERROR, "importdescriptors is not available for non-descriptor wallets");
|
||||||
}
|
}
|
||||||
|
|
||||||
RPCTypeCheck(main_request.params, {UniValue::VARR, UniValue::VOBJ});
|
|
||||||
|
|
||||||
WalletRescanReserver reserver(*pwallet);
|
WalletRescanReserver reserver(*pwallet);
|
||||||
if (!reserver.reserve()) {
|
if (!reserver.reserve()) {
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
|
||||||
|
@ -317,7 +317,11 @@ RPCHelpMan sendmany()
|
|||||||
"\nSend multiple times. Amounts are double-precision floating point numbers." +
|
"\nSend multiple times. Amounts are double-precision floating point numbers." +
|
||||||
HELP_REQUIRING_PASSPHRASE,
|
HELP_REQUIRING_PASSPHRASE,
|
||||||
{
|
{
|
||||||
{"dummy", RPCArg::Type::STR, RPCArg::Optional::NO, "Must be set to \"\" for backwards compatibility.", RPCArgOptions{.oneline_description="\"\""}},
|
{"dummy", RPCArg::Type::STR, RPCArg::Optional::NO, "Must be set to \"\" for backwards compatibility.",
|
||||||
|
RPCArgOptions{
|
||||||
|
.skip_type_check = true,
|
||||||
|
.oneline_description = "\"\"",
|
||||||
|
}},
|
||||||
{"amounts", RPCArg::Type::OBJ_USER_KEYS, RPCArg::Optional::NO, "The addresses and amounts",
|
{"amounts", RPCArg::Type::OBJ_USER_KEYS, RPCArg::Optional::NO, "The addresses and amounts",
|
||||||
{
|
{
|
||||||
{"address", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The bitcoin address is the key, the numeric amount (can be string) in " + CURRENCY_UNIT + " is the value"},
|
{"address", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The bitcoin address is the key, the numeric amount (can be string) in " + CURRENCY_UNIT + " is the value"},
|
||||||
@ -778,7 +782,10 @@ RPCHelpMan fundrawtransaction()
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
FundTxDoc()),
|
FundTxDoc()),
|
||||||
RPCArgOptions{.oneline_description="options"}},
|
RPCArgOptions{
|
||||||
|
.skip_type_check = true,
|
||||||
|
.oneline_description = "options",
|
||||||
|
}},
|
||||||
{"iswitness", RPCArg::Type::BOOL, RPCArg::DefaultHint{"depends on heuristic tests"}, "Whether the transaction hex is a serialized witness transaction.\n"
|
{"iswitness", RPCArg::Type::BOOL, RPCArg::DefaultHint{"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 iswitness is not present, heuristic tests will be used in decoding.\n"
|
||||||
"If true, only witness deserialization will be tried.\n"
|
"If true, only witness deserialization will be tried.\n"
|
||||||
@ -810,8 +817,6 @@ RPCHelpMan fundrawtransaction()
|
|||||||
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
|
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
|
||||||
if (!pwallet) return UniValue::VNULL;
|
if (!pwallet) return UniValue::VNULL;
|
||||||
|
|
||||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValueType(), UniValue::VBOOL});
|
|
||||||
|
|
||||||
// parse hex string from parameter
|
// parse hex string from parameter
|
||||||
CMutableTransaction tx;
|
CMutableTransaction tx;
|
||||||
bool try_witness = request.params[2].isNull() ? true : request.params[2].get_bool();
|
bool try_witness = request.params[2].isNull() ? true : request.params[2].get_bool();
|
||||||
@ -900,8 +905,6 @@ RPCHelpMan signrawtransactionwithwallet()
|
|||||||
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
|
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
|
||||||
if (!pwallet) return UniValue::VNULL;
|
if (!pwallet) return UniValue::VNULL;
|
||||||
|
|
||||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VSTR}, true);
|
|
||||||
|
|
||||||
CMutableTransaction mtx;
|
CMutableTransaction mtx;
|
||||||
if (!DecodeHexTx(mtx, request.params[0].get_str())) {
|
if (!DecodeHexTx(mtx, request.params[0].get_str())) {
|
||||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input.");
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input.");
|
||||||
@ -1001,7 +1004,6 @@ static RPCHelpMan bumpfee_helper(std::string method_name)
|
|||||||
throw JSONRPCError(RPC_WALLET_ERROR, "bumpfee is not available with wallets that have private keys disabled. Use psbtbumpfee instead.");
|
throw JSONRPCError(RPC_WALLET_ERROR, "bumpfee is not available with wallets that have private keys disabled. Use psbtbumpfee instead.");
|
||||||
}
|
}
|
||||||
|
|
||||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VOBJ});
|
|
||||||
uint256 hash(ParseHashV(request.params[0], "txid"));
|
uint256 hash(ParseHashV(request.params[0], "txid"));
|
||||||
|
|
||||||
CCoinControl coin_control;
|
CCoinControl coin_control;
|
||||||
@ -1135,7 +1137,7 @@ RPCHelpMan send()
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
RPCArgOptions{.skip_type_check = true}},
|
||||||
{"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"},
|
{"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"},
|
||||||
{"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n"
|
{"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n"
|
||||||
"\"" + FeeModes("\"\n\"") + "\""},
|
"\"" + FeeModes("\"\n\"") + "\""},
|
||||||
@ -1205,15 +1207,6 @@ RPCHelpMan send()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {
|
|
||||||
UniValueType(), // outputs (ARR or OBJ, checked later)
|
|
||||||
UniValue::VNUM, // conf_target
|
|
||||||
UniValue::VSTR, // estimate_mode
|
|
||||||
UniValueType(), // fee_rate, will be checked by AmountFromValue() in SetFeeEstimateMode()
|
|
||||||
UniValue::VOBJ, // options
|
|
||||||
}, true
|
|
||||||
);
|
|
||||||
|
|
||||||
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
|
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
|
||||||
if (!pwallet) return UniValue::VNULL;
|
if (!pwallet) return UniValue::VNULL;
|
||||||
|
|
||||||
@ -1314,15 +1307,6 @@ RPCHelpMan sendall()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
RPCTypeCheck(request.params, {
|
|
||||||
UniValue::VARR, // recipients
|
|
||||||
UniValue::VNUM, // conf_target
|
|
||||||
UniValue::VSTR, // estimate_mode
|
|
||||||
UniValueType(), // fee_rate, will be checked by AmountFromValue() in SetFeeEstimateMode()
|
|
||||||
UniValue::VOBJ, // options
|
|
||||||
}, true
|
|
||||||
);
|
|
||||||
|
|
||||||
std::shared_ptr<CWallet> const pwallet{GetWalletForJSONRPCRequest(request)};
|
std::shared_ptr<CWallet> const pwallet{GetWalletForJSONRPCRequest(request)};
|
||||||
if (!pwallet) return UniValue::VNULL;
|
if (!pwallet) return UniValue::VNULL;
|
||||||
// Make sure the results are valid at least up to the most recent block
|
// Make sure the results are valid at least up to the most recent block
|
||||||
@ -1518,8 +1502,6 @@ RPCHelpMan walletprocesspsbt()
|
|||||||
// the user could have gotten from another RPC command prior to now
|
// the user could have gotten from another RPC command prior to now
|
||||||
wallet.BlockUntilSyncedToCurrentChain();
|
wallet.BlockUntilSyncedToCurrentChain();
|
||||||
|
|
||||||
RPCTypeCheck(request.params, {UniValue::VSTR});
|
|
||||||
|
|
||||||
// Unserialize the transaction
|
// Unserialize the transaction
|
||||||
PartiallySignedTransaction psbtx;
|
PartiallySignedTransaction psbtx;
|
||||||
std::string error;
|
std::string error;
|
||||||
@ -1594,7 +1576,7 @@ RPCHelpMan walletcreatefundedpsbt()
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
RPCArgOptions{.skip_type_check = true}},
|
||||||
{"locktime", RPCArg::Type::NUM, RPCArg::Default{0}, "Raw locktime. Non-0 value also locktime-activates inputs"},
|
{"locktime", RPCArg::Type::NUM, RPCArg::Default{0}, "Raw locktime. Non-0 value also locktime-activates inputs"},
|
||||||
{"options", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED_NAMED_ARG, "",
|
{"options", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED_NAMED_ARG, "",
|
||||||
Cat<std::vector<RPCArg>>(
|
Cat<std::vector<RPCArg>>(
|
||||||
@ -1645,15 +1627,6 @@ RPCHelpMan walletcreatefundedpsbt()
|
|||||||
// the user could have gotten from another RPC command prior to now
|
// the user could have gotten from another RPC command prior to now
|
||||||
wallet.BlockUntilSyncedToCurrentChain();
|
wallet.BlockUntilSyncedToCurrentChain();
|
||||||
|
|
||||||
RPCTypeCheck(request.params, {
|
|
||||||
UniValue::VARR,
|
|
||||||
UniValueType(), // ARR or OBJ, checked later
|
|
||||||
UniValue::VNUM,
|
|
||||||
UniValue::VOBJ,
|
|
||||||
UniValue::VBOOL
|
|
||||||
}, true
|
|
||||||
);
|
|
||||||
|
|
||||||
UniValue options{request.params[3].isNull() ? UniValue::VOBJ : request.params[3]};
|
UniValue options{request.params[3].isNull() ? UniValue::VOBJ : request.params[3]};
|
||||||
|
|
||||||
CAmount fee;
|
CAmount fee;
|
||||||
|
@ -568,8 +568,6 @@ static RPCHelpMan upgradewallet()
|
|||||||
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
|
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
|
||||||
if (!pwallet) return UniValue::VNULL;
|
if (!pwallet) return UniValue::VNULL;
|
||||||
|
|
||||||
RPCTypeCheck(request.params, {UniValue::VNUM}, true);
|
|
||||||
|
|
||||||
EnsureWalletIsUnlocked(*pwallet);
|
EnsureWalletIsUnlocked(*pwallet);
|
||||||
|
|
||||||
int version = 0;
|
int version = 0;
|
||||||
@ -637,8 +635,6 @@ RPCHelpMan simulaterawtransaction()
|
|||||||
if (!rpc_wallet) return UniValue::VNULL;
|
if (!rpc_wallet) return UniValue::VNULL;
|
||||||
const CWallet& wallet = *rpc_wallet;
|
const CWallet& wallet = *rpc_wallet;
|
||||||
|
|
||||||
RPCTypeCheck(request.params, {UniValue::VARR, UniValue::VOBJ}, true);
|
|
||||||
|
|
||||||
LOCK(wallet.cs_wallet);
|
LOCK(wallet.cs_wallet);
|
||||||
|
|
||||||
UniValue include_watchonly(UniValue::VNULL);
|
UniValue include_watchonly(UniValue::VNULL);
|
||||||
|
Loading…
Reference in New Issue
Block a user