From 73ac0fb6ce7854d42240adb4a8c8c936ca90a1aa Mon Sep 17 00:00:00 2001 From: niftynei Date: Thu, 4 Feb 2021 13:17:53 -0600 Subject: [PATCH] df-tests: happy path rbf test I can has RBF? --- tests/test_opening.py | 91 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 tests/test_opening.py diff --git a/tests/test_opening.py b/tests/test_opening.py new file mode 100644 index 000000000..7e273c36f --- /dev/null +++ b/tests/test_opening.py @@ -0,0 +1,91 @@ +from fixtures import * # noqa: F401,F403 +from fixtures import TEST_NETWORK +from utils import ( + only_one, wait_for, sync_blockheight, EXPERIMENTAL_FEATURES +) + +import unittest + + +def find_next_feerate(node, peer): + chan = only_one(only_one(node.rpc.listpeers(peer.info['id'])['peers'])['channels']) + return chan['next_feerate'] + + +@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') +@unittest.skipIf(not EXPERIMENTAL_FEATURES, "dual-funding is experimental only") +def test_v2_rbf(node_factory, bitcoind, chainparams): + l1, l2 = node_factory.get_nodes(2, + opts=[{'dev-force-features': '+223'}, + {'dev-force-features': '+223'}]) + + l1.rpc.connect(l2.info['id'], 'localhost', l2.port) + amount = 2**24 + chan_amount = 100000 + bitcoind.rpc.sendtoaddress(l1.rpc.newaddr()['bech32'], amount / 10**8 + 0.01) + bitcoind.generate_block(1) + # Wait for it to arrive. + wait_for(lambda: len(l1.rpc.listfunds()['outputs']) > 0) + + res = l1.rpc.fundchannel(l2.info['id'], chan_amount) + chan_id = res['channel_id'] + vins = bitcoind.rpc.decoderawtransaction(res['tx'])['vin'] + assert(only_one(vins)) + prev_utxos = ["{}:{}".format(vins[0]['txid'], vins[0]['vout'])] + + # Check that we're waiting for lockin + l1.daemon.wait_for_log(' to DUALOPEND_AWAITING_LOCKIN') + + next_feerate = find_next_feerate(l1, l2) + + # Check that feerate info is correct + info_1 = only_one(only_one(l1.rpc.listpeers(l2.info['id'])['peers'])['channels']) + assert info_1['initial_feerate'] == info_1['last_feerate'] + rate = int(info_1['last_feerate'][:-5]) + assert int(info_1['next_feerate'][:-5]) == rate + rate // 4 + assert info_1['next_fee_step'] == 1 + + # Initiate an RBF + startweight = 42 + 172 # base weight, funding output + initpsbt = l1.rpc.utxopsbt(chan_amount, next_feerate, startweight, + prev_utxos, reservedok=True, + min_witness_weight=110, + excess_as_change=True) + + # Do the bump + bump = l1.rpc.openchannel_bump(chan_id, chan_amount, initpsbt['psbt']) + + update = l1.rpc.openchannel_update(chan_id, bump['psbt']) + assert update['commitments_secured'] + + # Check that feerate info has incremented + info_2 = only_one(only_one(l1.rpc.listpeers(l2.info['id'])['peers'])['channels']) + assert info_1['initial_feerate'] == info_2['initial_feerate'] + assert info_1['next_feerate'] == info_2['last_feerate'] + + rate = int(info_2['last_feerate'][:-5]) + assert int(info_2['next_feerate'][:-5]) == rate + rate // 4 + assert info_2['next_fee_step'] == 2 + + # Sign our inputs, and continue + signed_psbt = l1.rpc.signpsbt(update['psbt'])['signed_psbt'] + l1.rpc.openchannel_signed(chan_id, signed_psbt) + + bitcoind.generate_block(1) + sync_blockheight(bitcoind, [l1]) + l1.daemon.wait_for_log(' to CHANNELD_NORMAL') + + # Check that feerate info is gone + info_1 = only_one(only_one(l1.rpc.listpeers(l2.info['id'])['peers'])['channels']) + assert 'initial_feerate' not in info_1 + assert 'last_feerate' not in info_1 + assert 'next_feerate' not in info_1 + assert 'next_fee_step' not in info_1 + + # Shut l2 down, force close the channel. + l2.stop() + resp = l1.rpc.close(l2.info['id'], unilateraltimeout=1) + assert resp['type'] == 'unilateral' + l1.daemon.wait_for_log(' to CHANNELD_SHUTTING_DOWN') + l1.daemon.wait_for_log('sendrawtx exit 0') +