Tests for the sign + send psbt RPCs
(node_factory, bitcoind, chainparams)
| 730 | |
| 731 | |
| 732 | def test_sign_and_send_psbt(node_factory, bitcoind, chainparams): |
| 733 | """ |
| 734 | Tests for the sign + send psbt RPCs |
| 735 | """ |
| 736 | amount = 1000000 |
| 737 | total_outs = 12 |
| 738 | coin_mvt_plugin = os.path.join(os.getcwd(), 'tests/plugins/coin_movements.py') |
| 739 | l1 = node_factory.get_node(options={'plugin': coin_mvt_plugin}, |
| 740 | feerates=(7500, 7500, 7500, 7500)) |
| 741 | l2 = node_factory.get_node() |
| 742 | addr = chainparams['example_addr'] |
| 743 | out_total = Millisatoshi(amount * 3 * 1000) |
| 744 | |
| 745 | # Add a medley of funds to withdraw later, bech32 + p2sh-p2wpkh |
| 746 | for i in range(total_outs // 2): |
| 747 | bitcoind.rpc.sendtoaddress(l1.rpc.newaddr()['bech32'], |
| 748 | amount / 10**8) |
| 749 | bitcoind.rpc.sendtoaddress(l1.rpc.newaddr('p2sh-segwit')['p2sh-segwit'], |
| 750 | amount / 10**8) |
| 751 | bitcoind.generate_block(1) |
| 752 | wait_for(lambda: len(l1.rpc.listfunds()['outputs']) == total_outs) |
| 753 | |
| 754 | # Make a PSBT out of our inputs |
| 755 | funding = l1.rpc.fundpsbt(satoshi=out_total, |
| 756 | feerate=7500, |
| 757 | startweight=42) |
| 758 | assert len([x for x in l1.rpc.listfunds()['outputs'] if x['reserved']]) == 4 |
| 759 | psbt = bitcoind.rpc.decodepsbt(funding['psbt']) |
| 760 | saved_input = psbt['tx']['vin'][0] |
| 761 | |
| 762 | # Go ahead and unreserve the UTXOs, we'll use a smaller |
| 763 | # set of them to create a second PSBT that we'll attempt to sign |
| 764 | # and broadcast (to disastrous results) |
| 765 | l1.rpc.unreserveinputs(funding['psbt']) |
| 766 | |
| 767 | # Re-reserve one of the utxos we just unreserved |
| 768 | psbt = bitcoind.rpc.createpsbt([{'txid': saved_input['txid'], |
| 769 | 'vout': saved_input['vout']}], []) |
| 770 | l1.rpc.reserveinputs(psbt) |
| 771 | |
| 772 | # We require the utxos be reserved before signing them |
| 773 | with pytest.raises(RpcError, match=r"Aborting PSBT signing. UTXO .* is not reserved"): |
| 774 | l1.rpc.signpsbt(funding['psbt'])['signed_psbt'] |
| 775 | |
| 776 | # Now we unreserve the singleton, so we can reserve it again |
| 777 | l1.rpc.unreserveinputs(psbt) |
| 778 | |
| 779 | # Now add an output. Note, we add the 'excess msat' to the output so |
| 780 | # that our feerate is 'correct'. This is of particular importance to elementsd, |
| 781 | # who requires that every satoshi be accounted for in a tx. |
| 782 | out_1_ms = Millisatoshi(funding['excess_msat']) |
| 783 | output_psbt = bitcoind.rpc.createpsbt([], |
| 784 | [{addr: float((out_total + out_1_ms).to_btc())}]) |
| 785 | fullpsbt = bitcoind.rpc.joinpsbts([funding['psbt'], output_psbt]) |
| 786 | |
| 787 | # We re-reserve the first set... |
| 788 | l1.rpc.reserveinputs(fullpsbt) |
| 789 |
nothing calls this directly
no test coverage detected