diff options
author | Andrew Chow <github@achow101.com> | 2023-05-22 11:18:41 -0400 |
---|---|---|
committer | Andrew Chow <github@achow101.com> | 2023-05-22 11:28:11 -0400 |
commit | 22139f6e83a2bedd2dad9f280567d2c76c54252f (patch) | |
tree | eb41a79eecb3d3c9d6508f4cae7c57958ad9e0c9 /test/functional/rpc_psbt.py | |
parent | 456701420b157f4c02592a2aea6fc32b1620c56a (diff) | |
parent | 1bce12acd3e271a7c88d9400b4e3a5645bc8a911 (diff) | |
download | bitcoin-22139f6e83a2bedd2dad9f280567d2c76c54252f.tar.xz |
Merge bitcoin/bitcoin#25796: rpc: add `descriptorprocesspsbt` rpc
1bce12acd3e271a7c88d9400b4e3a5645bc8a911 test: add test for `descriptorprocesspsbt` RPC (ishaanam)
fb2a3a70e860aa87fb7a21f6554ed9f3ce901e2d rpc: add descriptorprocesspsbt rpc (ishaanam)
Pull request description:
This PR implements an RPC called `descriptorprocesspsbt`. This RPC is based off of `walletprocesspsbt`, but instead of interacting with the wallet to update, sign and finalize a psbt, it instead accepts an array of output descriptors and uses that information along with information from the mempool, txindex, and the utxo set to do so. `utxoupdatepsbt` also updates a psbt in this manner, but doesn't sign or finalize it. Because of this overlap, a helper function that is added in this PR is called by both `utxoupdatepsbt` and `descriptorprocesspsbt`. Whether or not the helper function signs a psbt is dictated by if the HidingSigningProvider passed to it contains any private information. There is also a test added in this PR for this new RPC that uses p2wsh, p2wpkh, and legacy outputs.
Edit: see https://github.com/bitcoin/bitcoin/pull/25796#issuecomment-1228830963
ACKs for top commit:
achow101:
re-ACK 1bce12acd3e271a7c88d9400b4e3a5645bc8a911
instagibbs:
reACK https://github.com/bitcoin/bitcoin/pull/25796/commits/1bce12acd3e271a7c88d9400b4e3a5645bc8a911
Tree-SHA512: e1d0334739943e71f2ee68b4db7637ebe725da62e7aa4be071f71c7196d2a5970a31ece96d91e372d34454cde8509e95ab0eebd2c8edb94f7d5a781a84f8fc5d
Diffstat (limited to 'test/functional/rpc_psbt.py')
-rwxr-xr-x | test/functional/rpc_psbt.py | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py index 49cdfd0e66..7c653cc315 100755 --- a/test/functional/rpc_psbt.py +++ b/test/functional/rpc_psbt.py @@ -42,7 +42,10 @@ from test_framework.util import ( find_vout_for_address, random_bytes, ) -from test_framework.wallet_util import bytes_to_wif +from test_framework.wallet_util import ( + bytes_to_wif, + get_generate_key +) import json import os @@ -942,6 +945,48 @@ class PSBTTest(BitcoinTestFramework): self.log.info("Test we don't crash when making a 0-value funded transaction at 0 fee without forcing an input selection") assert_raises_rpc_error(-4, "Transaction requires one destination of non-0 value, a non-0 feerate, or a pre-selected input", self.nodes[0].walletcreatefundedpsbt, [], [{"data": "deadbeef"}], 0, {"fee_rate": "0"}) + self.log.info("Test descriptorprocesspsbt updates and signs a psbt with descriptors") + + self.generate(self.nodes[2], 1) + + # Disable the wallet for node 2 since `descriptorprocesspsbt` does not use the wallet + self.restart_node(2, extra_args=["-disablewallet"]) + self.connect_nodes(0, 2) + self.connect_nodes(1, 2) + + key_info = get_generate_key() + key = key_info.privkey + address = key_info.p2wpkh_addr + + descriptor = descsum_create(f"wpkh({key})") + + txid = self.nodes[0].sendtoaddress(address, 1) + self.sync_all() + vout = find_output(self.nodes[0], txid, 1) + + psbt = self.nodes[2].createpsbt([{"txid": txid, "vout": vout}], {self.nodes[0].getnewaddress(): 0.99999}) + decoded = self.nodes[2].decodepsbt(psbt) + test_psbt_input_keys(decoded['inputs'][0], []) + + # Test that even if the wrong descriptor is given, `witness_utxo` and `non_witness_utxo` + # are still added to the psbt + alt_descriptor = descsum_create(f"wpkh({get_generate_key().privkey})") + alt_psbt = self.nodes[2].descriptorprocesspsbt(psbt=psbt, descriptors=[alt_descriptor], sighashtype="ALL")["psbt"] + decoded = self.nodes[2].decodepsbt(alt_psbt) + test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo', 'non_witness_utxo']) + + # Test that the psbt is not finalized and does not have bip32_derivs unless specified + psbt = self.nodes[2].descriptorprocesspsbt(psbt=psbt, descriptors=[descriptor], sighashtype="ALL", bip32derivs=True, finalize=False)["psbt"] + decoded = self.nodes[2].decodepsbt(psbt) + test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo', 'non_witness_utxo', 'partial_signatures', 'bip32_derivs']) + + psbt = self.nodes[2].descriptorprocesspsbt(psbt=psbt, descriptors=[descriptor], sighashtype="ALL", bip32derivs=False, finalize=True)["psbt"] + decoded = self.nodes[2].decodepsbt(psbt) + test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo', 'non_witness_utxo', 'final_scriptwitness']) + + # Broadcast transaction + rawtx = self.nodes[2].finalizepsbt(psbt)["hex"] + self.nodes[2].sendrawtransaction(rawtx) if __name__ == '__main__': PSBTTest().main() |