mirror of https://github.com/bitcoin/bitcoin
RPC/Wallet: Convert walletprocesspsbt to use options parameter
This commit is contained in:
parent
c2612273ef
commit
f43f992b73
|
@ -162,7 +162,10 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
|||
{ "walletcreatefundedpsbt", 3, "replaceable"},
|
||||
{ "walletcreatefundedpsbt", 3, "solving_data"},
|
||||
{ "walletcreatefundedpsbt", 4, "bip32derivs" },
|
||||
{ "walletprocesspsbt", 1, "options" },
|
||||
{ "walletprocesspsbt", 1, "sign" },
|
||||
{ "walletprocesspsbt", 1, "bip32derivs" },
|
||||
{ "walletprocesspsbt", 1, "finalize" },
|
||||
{ "walletprocesspsbt", 3, "bip32derivs" },
|
||||
{ "walletprocesspsbt", 4, "finalize" },
|
||||
{ "descriptorprocesspsbt", 1, "descriptors"},
|
||||
|
|
|
@ -1552,17 +1552,25 @@ RPCHelpMan walletprocesspsbt()
|
|||
HELP_REQUIRING_PASSPHRASE,
|
||||
{
|
||||
{"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction base64 string"},
|
||||
{"sign", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also sign the transaction when updating (requires wallet to be unlocked)"},
|
||||
{"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT for Taproot, ALL otherwise"}, "The signature hash type to sign with if not specified by the PSBT. Must be one of\n"
|
||||
" \"DEFAULT\"\n"
|
||||
" \"ALL\"\n"
|
||||
" \"NONE\"\n"
|
||||
" \"SINGLE\"\n"
|
||||
" \"ALL|ANYONECANPAY\"\n"
|
||||
" \"NONE|ANYONECANPAY\"\n"
|
||||
" \"SINGLE|ANYONECANPAY\""},
|
||||
{"bip32derivs", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include BIP 32 derivation paths for public keys if we know them"},
|
||||
{"finalize", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also finalize inputs if possible"},
|
||||
{"options|sign", {RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Type::BOOL}, RPCArg::Optional::OMITTED, "",
|
||||
{
|
||||
{"sign", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also sign the transaction when updating (requires wallet to be unlocked)", RPCArgOptions{.also_positional = true}},
|
||||
{"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT for Taproot, ALL otherwise"}, "The signature hash type to sign with if not specified by the PSBT. Must be one of\n"
|
||||
" \"DEFAULT\"\n"
|
||||
" \"ALL\"\n"
|
||||
" \"NONE\"\n"
|
||||
" \"SINGLE\"\n"
|
||||
" \"ALL|ANYONECANPAY\"\n"
|
||||
" \"NONE|ANYONECANPAY\"\n"
|
||||
" \"SINGLE|ANYONECANPAY\"",
|
||||
RPCArgOptions{.also_positional = true}},
|
||||
{"bip32derivs", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include BIP 32 derivation paths for public keys if we know them", RPCArgOptions{.also_positional = true}},
|
||||
{"finalize", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also finalize inputs if possible", RPCArgOptions{.also_positional = true}},
|
||||
},
|
||||
RPCArgOptions{.oneline_description="options"}},
|
||||
{"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT"}, "for backwards compatibility", RPCArgOptions{.hidden=true}},
|
||||
{"bip32derivs", RPCArg::Type::BOOL, RPCArg::Default{true}, "for backwards compatibility", RPCArgOptions{.hidden=true}},
|
||||
{"finalize", RPCArg::Type::BOOL, RPCArg::Default{true}, "for backwards compatibility", RPCArgOptions{.hidden=true}},
|
||||
},
|
||||
RPCResult{
|
||||
RPCResult::Type::OBJ, "", "",
|
||||
|
@ -1592,13 +1600,47 @@ RPCHelpMan walletprocesspsbt()
|
|||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
|
||||
}
|
||||
|
||||
// Get the sighash type
|
||||
int nHashType = ParseSighashString(request.params[2]);
|
||||
// Get options
|
||||
bool sign = true;
|
||||
bool bip32derivs = true;
|
||||
bool finalize = true;
|
||||
int nHashType = ParseSighashString(NullUniValue); // Use ParseSighashString default
|
||||
if (request.params[1].isBool() || request.params[1].isNull()) {
|
||||
// Old style positional parameters
|
||||
sign = request.params[1].isNull() ? true : request.params[1].get_bool();
|
||||
nHashType = ParseSighashString(request.params[2]);
|
||||
bip32derivs = request.params[3].isNull() ? true : request.params[3].get_bool();
|
||||
finalize = request.params[4].isNull() ? true : request.params[4].get_bool();
|
||||
} else {
|
||||
// New style options are in an object
|
||||
UniValue options = request.params[1];
|
||||
RPCTypeCheckObj(options,
|
||||
{
|
||||
{"sign", UniValueType(UniValue::VBOOL)},
|
||||
{"bip32derivs", UniValueType(UniValue::VBOOL)},
|
||||
{"finalize", UniValueType(UniValue::VBOOL)},
|
||||
{"sighashtype", UniValueType(UniValue::VSTR)},
|
||||
},
|
||||
true, true);
|
||||
if (options.exists("sign")) {
|
||||
sign = options["sign"].get_bool();
|
||||
}
|
||||
if (options.exists("bip32derivs")) {
|
||||
bip32derivs = options["bip32derivs"].get_bool();
|
||||
}
|
||||
if (options.exists("finalize")) {
|
||||
finalize = options["finalize"].get_bool();
|
||||
}
|
||||
if (options.exists("sighashtype")) {
|
||||
nHashType = ParseSighashString(options["sighashtype"]);
|
||||
}
|
||||
if (request.params.size() > 2) {
|
||||
// Same behaviour as too many args passed normally
|
||||
throw std::runtime_error(self.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
// Fill transaction with our data and also sign
|
||||
bool sign = request.params[1].isNull() ? true : request.params[1].get_bool();
|
||||
bool bip32derivs = request.params[3].isNull() ? true : request.params[3].get_bool();
|
||||
bool finalize = request.params[4].isNull() ? true : request.params[4].get_bool();
|
||||
bool complete = true;
|
||||
|
||||
if (sign) EnsureWalletIsUnlocked(*pwallet);
|
||||
|
|
|
@ -65,7 +65,7 @@ class HelpRpcTest(BitcoinTestFramework):
|
|||
|
||||
mapping_server = self.nodes[0].help("dump_all_command_conversions")
|
||||
# Filter all RPCs whether they need conversion
|
||||
mapping_server_conversion = [tuple(m[:3]) for m in mapping_server if not m[3]]
|
||||
mapping_server_conversion = set(tuple(m[:3]) for m in mapping_server if not m[3])
|
||||
|
||||
# Only check if all RPC methods have been compiled (i.e. wallet is enabled)
|
||||
if self.is_wallet_compiled() and sorted(mapping_client) != sorted(mapping_server_conversion):
|
||||
|
|
|
@ -216,6 +216,7 @@ class PSBTTest(BitcoinTestFramework):
|
|||
|
||||
# Sign the transaction but don't finalize
|
||||
processed_psbt = self.nodes[0].walletprocesspsbt(psbt=psbtx, finalize=False)
|
||||
assert_equal(processed_psbt, self.nodes[0].walletprocesspsbt(psbtx, {"finalize": False}))
|
||||
assert "hex" not in processed_psbt
|
||||
signed_psbt = processed_psbt['psbt']
|
||||
|
||||
|
@ -225,6 +226,7 @@ class PSBTTest(BitcoinTestFramework):
|
|||
|
||||
# Alternative method: sign AND finalize in one command
|
||||
processed_finalized_psbt = self.nodes[0].walletprocesspsbt(psbt=psbtx, finalize=True)
|
||||
assert_equal(processed_finalized_psbt, self.nodes[0].walletprocesspsbt(psbtx, {"finalize": True}))
|
||||
finalized_psbt = processed_finalized_psbt['psbt']
|
||||
finalized_psbt_hex = processed_finalized_psbt['hex']
|
||||
assert signed_psbt != finalized_psbt
|
||||
|
@ -430,11 +432,13 @@ class PSBTTest(BitcoinTestFramework):
|
|||
|
||||
# Update psbts, should only have data for one input and not the other
|
||||
psbt1 = self.nodes[1].walletprocesspsbt(psbt_orig, False, "ALL")['psbt']
|
||||
assert_equal(psbt1, self.nodes[1].walletprocesspsbt(psbt_orig, {"sign": False, "sighashtype": "ALL"})["psbt"])
|
||||
psbt1_decoded = self.nodes[0].decodepsbt(psbt1)
|
||||
assert psbt1_decoded['inputs'][0] and not psbt1_decoded['inputs'][1]
|
||||
# Check that BIP32 path was added
|
||||
assert "bip32_derivs" in psbt1_decoded['inputs'][0]
|
||||
psbt2 = self.nodes[2].walletprocesspsbt(psbt_orig, False, "ALL", False)['psbt']
|
||||
assert_equal(psbt2, self.nodes[2].walletprocesspsbt(psbt_orig, {"sign": False, "sighashtype": "ALL", "bip32derivs": False})["psbt"])
|
||||
psbt2_decoded = self.nodes[0].decodepsbt(psbt2)
|
||||
assert not psbt2_decoded['inputs'][0] and psbt2_decoded['inputs'][1]
|
||||
# Check that BIP32 paths were not added
|
||||
|
@ -679,6 +683,7 @@ class PSBTTest(BitcoinTestFramework):
|
|||
|
||||
# After update with wallet, only needs signing
|
||||
updated = self.nodes[1].walletprocesspsbt(psbt, False, 'ALL', True)['psbt']
|
||||
assert_equal(updated, self.nodes[1].walletprocesspsbt(psbt, {"sign": False, "sighashtype": 'ALL', "bip32derivs": True})["psbt"])
|
||||
analyzed = self.nodes[0].analyzepsbt(updated)
|
||||
assert analyzed['inputs'][0]['has_utxo'] and not analyzed['inputs'][0]['is_final'] and analyzed['inputs'][0]['next'] == 'signer' and analyzed['next'] == 'signer' and analyzed['inputs'][0]['missing']['signatures'][0] == addrinfo['embedded']['witness_program']
|
||||
|
||||
|
|
Loading…
Reference in New Issue