(node_factory, bitcoind, chainparams, addrtype)
| 558 | @pytest.mark.parametrize("addrtype", ["bech32", "p2tr"]) |
| 559 | @unittest.skipIf(TEST_NETWORK != 'regtest', "FIXME: Elements fees are not quite right") |
| 560 | def test_fundpsbt_feerates(node_factory, bitcoind, chainparams, addrtype): |
| 561 | l1 = node_factory.get_node(options={'dev-warn-on-overgrind': None}, |
| 562 | broken_log='overgrind: short signature length') |
| 563 | |
| 564 | # Add some funds to withdraw later |
| 565 | for i in range(20): |
| 566 | bitcoind.rpc.sendtoaddress(l1.rpc.newaddr(addrtype)[addrtype], |
| 567 | 5000 / 10**8) |
| 568 | |
| 569 | # See utxo_spend_weight() |
| 570 | if addrtype == 'bech32': |
| 571 | witness_weight = 1 + 71 + 1 + 33 |
| 572 | elif addrtype == 'p2tr': |
| 573 | witness_weight = 1 + 64 |
| 574 | else: |
| 575 | assert False |
| 576 | |
| 577 | input_weight = 1 + witness_weight + (32 + 4 + 4 + 1) * 4 |
| 578 | if chainparams['elements']: |
| 579 | input_weight += 6 |
| 580 | |
| 581 | bitcoind.generate_block(1) |
| 582 | wait_for(lambda: len(l1.rpc.listfunds()['outputs']) == 20) |
| 583 | |
| 584 | # version, input count, output count, locktime, segwit marker, flag |
| 585 | base_weight = (4 + 1 + 1 + 4) * 4 + 1 + 1 |
| 586 | if chainparams['elements']: |
| 587 | # Elements has empty surjection and rangeproof |
| 588 | base_weight += 2 * 4 |
| 589 | # And fee output (bitcoin_tx_output_weight(0)): |
| 590 | base_weight += (8 + 1 + 0) * 4 + (32 + 1 + 1 + 1) * 4 |
| 591 | # Bech32 change output |
| 592 | change_weight = (8 + 1 + (1 + 1 + 20)) * 4 |
| 593 | else: |
| 594 | # P2TR output |
| 595 | change_weight = (8 + 1 + (1 + 1 + 32)) * 4 |
| 596 | |
| 597 | # Both minimal and higher feerate |
| 598 | for feerate in (253, 1000): |
| 599 | # Try with both 1 and 2 inputs |
| 600 | for amount, num_inputs in ((260, 1), (5000, 2)): |
| 601 | prep = l1.rpc.fundpsbt(amount, f"{feerate}perkw", base_weight, excess_as_change=True) |
| 602 | assert prep['estimated_final_weight'] == base_weight + change_weight + input_weight * num_inputs |
| 603 | signed = l1.rpc.signpsbt(prep['psbt'])['signed_psbt'] |
| 604 | sent = l1.rpc.sendpsbt(signed) |
| 605 | txinfo = bitcoind.rpc.getmempoolentry(sent['txid']) |
| 606 | if did_short_sig(l1): |
| 607 | assert txinfo['weight'] <= prep['estimated_final_weight'] |
| 608 | else: |
| 609 | assert txinfo['weight'] == prep['estimated_final_weight'] |
| 610 | # We never actually added that `amount` output to PSBT, so that appears as "fee" |
| 611 | fee = int(txinfo['fees']['base'] * 100_000_000) - amount |
| 612 | actual_feerate = fee / (txinfo['weight'] / 1000) |
| 613 | check_feerate([l1], actual_feerate, feerate) |
| 614 | |
| 615 | |
| 616 | def test_reserveinputs(node_factory, bitcoind, chainparams): |
nothing calls this directly
no test coverage detected