mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 06:58:57 +01:00
Merge bitcoin/bitcoin#26039: refactor: Run type check against RPCArgs (1/2)
fa9f6d7bcdrpc: Run type check against RPCArgs (MarcoFalke)faf96721a6test: Fix wrong types passed to RPCs (MarcoFalke) Pull request description: It seems brittle to require `RPCTypeCheck` being called inside the code logic. Without compile-time enforcement this will lead to places where it is forgotten and thus to inconsistencies and bugs. Fix this by removing the calls to `RPCTypeCheck` and doing the check internally. The changes should be reviewed as refactoring changes. However, if they change behavior, it will be a bugfix. For example the changes here happen to also detect/fix bugs like the one fixed in commit3b5fb6e77a. ACKs for top commit: ajtowns: ACKfa9f6d7bcdTree-SHA512: fb2c0981fe6e24da3ca7dbc06898730779ea4e02ea485458505a281cf421015e44dad0221a04023fc547ea2c660d94657909843fc85d92b847611ec097532439
This commit is contained in:
@@ -317,7 +317,11 @@ RPCHelpMan sendmany()
|
||||
"\nSend multiple times. Amounts are double-precision floating point numbers." +
|
||||
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",
|
||||
{
|
||||
{"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"},
|
||||
@@ -798,7 +802,10 @@ RPCHelpMan fundrawtransaction()
|
||||
},
|
||||
},
|
||||
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"
|
||||
"If iswitness is not present, heuristic tests will be used in decoding.\n"
|
||||
"If true, only witness deserialization will be tried.\n"
|
||||
@@ -830,8 +837,6 @@ RPCHelpMan fundrawtransaction()
|
||||
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
|
||||
if (!pwallet) return UniValue::VNULL;
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValueType(), UniValue::VBOOL});
|
||||
|
||||
// parse hex string from parameter
|
||||
CMutableTransaction tx;
|
||||
bool try_witness = request.params[2].isNull() ? true : request.params[2].get_bool();
|
||||
@@ -920,8 +925,6 @@ RPCHelpMan signrawtransactionwithwallet()
|
||||
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
|
||||
if (!pwallet) return UniValue::VNULL;
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VSTR}, true);
|
||||
|
||||
CMutableTransaction mtx;
|
||||
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.");
|
||||
@@ -1021,7 +1024,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.");
|
||||
}
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VOBJ});
|
||||
uint256 hash(ParseHashV(request.params[0], "txid"));
|
||||
|
||||
CCoinControl coin_control;
|
||||
@@ -1155,7 +1157,7 @@ RPCHelpMan send()
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RPCArgOptions{.skip_type_check = true}},
|
||||
{"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"
|
||||
"\"" + FeeModes("\"\n\"") + "\""},
|
||||
@@ -1227,15 +1229,6 @@ RPCHelpMan send()
|
||||
},
|
||||
[&](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);
|
||||
if (!pwallet) return UniValue::VNULL;
|
||||
|
||||
@@ -1338,15 +1331,6 @@ RPCHelpMan sendall()
|
||||
},
|
||||
[&](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)};
|
||||
if (!pwallet) return UniValue::VNULL;
|
||||
// Make sure the results are valid at least up to the most recent block
|
||||
@@ -1561,8 +1545,6 @@ RPCHelpMan walletprocesspsbt()
|
||||
// the user could have gotten from another RPC command prior to now
|
||||
wallet.BlockUntilSyncedToCurrentChain();
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VSTR});
|
||||
|
||||
// Unserialize the transaction
|
||||
PartiallySignedTransaction psbtx;
|
||||
std::string error;
|
||||
@@ -1637,7 +1619,7 @@ RPCHelpMan walletcreatefundedpsbt()
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RPCArgOptions{.skip_type_check = true}},
|
||||
{"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, "",
|
||||
Cat<std::vector<RPCArg>>(
|
||||
@@ -1690,15 +1672,6 @@ RPCHelpMan walletcreatefundedpsbt()
|
||||
// the user could have gotten from another RPC command prior to now
|
||||
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]};
|
||||
|
||||
CAmount fee;
|
||||
|
||||
Reference in New Issue
Block a user