(node_factory, bitcoind, chainparams)
| 1056 | @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') |
| 1057 | @pytest.mark.openchannel('v2') |
| 1058 | def test_rbf_to_chain_before_commit(node_factory, bitcoind, chainparams): |
| 1059 | disconnects = ['=WIRE_COMMITMENT_SIGNED', |
| 1060 | '-WIRE_COMMITMENT_SIGNED'] |
| 1061 | l1, l2 = node_factory.get_nodes(2, |
| 1062 | opts=[{'may_reconnect': True, |
| 1063 | 'dev-no-reconnect': None}, |
| 1064 | {'disconnect': disconnects, |
| 1065 | 'may_reconnect': True, |
| 1066 | 'dev-no-reconnect': None}]) |
| 1067 | |
| 1068 | l1.rpc.connect(l2.info['id'], 'localhost', l2.port) |
| 1069 | amount = 2**24 |
| 1070 | chan_amount = 100000 |
| 1071 | bitcoind.rpc.sendtoaddress(l1.rpc.newaddr()['p2tr'], amount / 10**8 + 0.01) |
| 1072 | bitcoind.generate_block(1) |
| 1073 | # Wait for it to arrive. |
| 1074 | wait_for(lambda: len(l1.rpc.listfunds()['outputs']) > 0) |
| 1075 | |
| 1076 | res = l1.rpc.fundchannel(l2.info['id'], chan_amount) |
| 1077 | chan_id = res['channel_id'] |
| 1078 | vins = bitcoind.rpc.decoderawtransaction(res['tx'])['vin'] |
| 1079 | assert(only_one(vins)) |
| 1080 | prev_utxos = ["{}:{}".format(vins[0]['txid'], vins[0]['vout'])] |
| 1081 | |
| 1082 | # Check that we're waiting for lockin |
| 1083 | l1.daemon.wait_for_log(' to DUALOPEND_AWAITING_LOCKIN') |
| 1084 | |
| 1085 | # rbf the lease with a higher amount |
| 1086 | rate = int(find_next_feerate(l1, l2)[:-5]) |
| 1087 | # We 4x the feerate to beat the min-relay fee |
| 1088 | next_feerate = '{}perkw'.format(rate * 4) |
| 1089 | |
| 1090 | # Initiate an RBF |
| 1091 | startweight = 42 + 172 # base weight, funding output |
| 1092 | initpsbt = l1.rpc.utxopsbt(chan_amount, next_feerate, startweight, |
| 1093 | prev_utxos, reservedok=True, |
| 1094 | excess_as_change=True) |
| 1095 | |
| 1096 | # Peers try RBF, break on initial COMMITMENT_SIGNED |
| 1097 | bump = l1.rpc.openchannel_bump(chan_id, chan_amount, initpsbt['psbt']) |
| 1098 | with pytest.raises(RpcError): |
| 1099 | l1.rpc.openchannel_update(chan_id, bump['psbt']) |
| 1100 | wait_for(lambda: l1.rpc.getpeer(l2.info['id'])['connected'] is False) |
| 1101 | |
| 1102 | # We don't have the commtiments yet, there's no scratch_txid |
| 1103 | inflights = only_one(l1.rpc.listpeerchannels()['channels'])['inflight'] |
| 1104 | assert len(inflights) == 2 |
| 1105 | assert 'scratch_txid' not in inflights[1] |
| 1106 | |
| 1107 | # Close the channel! |
| 1108 | l1.rpc.close(chan_id, 1) |
| 1109 | l1.daemon.wait_for_logs(['Broadcasting txid {}'.format(inflights[0]['scratch_txid']), |
| 1110 | 'sendrawtx exit 0']) |
| 1111 | |
| 1112 | wait_for(lambda: inflights[0]['scratch_txid'] in bitcoind.rpc.getrawmempool()) |
| 1113 | assert inflights[0]['funding_txid'] in bitcoind.rpc.getrawmempool() |
| 1114 | assert inflights[1]['funding_txid'] not in bitcoind.rpc.getrawmempool() |
| 1115 |
nothing calls this directly
no test coverage detected