Skip to content

Commit 30ec8cb

Browse files
niftyneirustyrussell
authored andcommitted
dualfund, test: add test for dropping to chain during RBF
Here we make sure we can drop the initial tx to chain, and that an inflight txid that's missing its commitment sigs is properly ignored.
1 parent f4b4f77 commit 30ec8cb

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

tests/test_opening.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,70 @@ def test_rbf_reconnect_tx_sigs(node_factory, bitcoind, chainparams):
10311031
assert l1_funding_txid == l2_funding_txid
10321032

10331033

1034+
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
1035+
@pytest.mark.openchannel('v2')
1036+
def test_rbf_to_chain_before_commit(node_factory, bitcoind, chainparams):
1037+
disconnects = ['=WIRE_TX_ADD_INPUT', # Initial funding succeeds
1038+
'=WIRE_COMMITMENT_SIGNED',
1039+
'-WIRE_COMMITMENT_SIGNED']
1040+
l1, l2 = node_factory.get_nodes(2,
1041+
opts=[{'disconnect': disconnects,
1042+
'may_reconnect': True,
1043+
'dev-no-reconnect': None},
1044+
{'may_reconnect': True,
1045+
'dev-no-reconnect': None,
1046+
'allow_broken_log': True}])
1047+
1048+
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
1049+
amount = 2**24
1050+
chan_amount = 100000
1051+
bitcoind.rpc.sendtoaddress(l1.rpc.newaddr()['bech32'], amount / 10**8 + 0.01)
1052+
bitcoind.generate_block(1)
1053+
# Wait for it to arrive.
1054+
wait_for(lambda: len(l1.rpc.listfunds()['outputs']) > 0)
1055+
1056+
res = l1.rpc.fundchannel(l2.info['id'], chan_amount)
1057+
chan_id = res['channel_id']
1058+
vins = bitcoind.rpc.decoderawtransaction(res['tx'])['vin']
1059+
assert(only_one(vins))
1060+
prev_utxos = ["{}:{}".format(vins[0]['txid'], vins[0]['vout'])]
1061+
1062+
# Check that we're waiting for lockin
1063+
l1.daemon.wait_for_log(' to DUALOPEND_AWAITING_LOCKIN')
1064+
1065+
# rbf the lease with a higher amount
1066+
rate = int(find_next_feerate(l1, l2)[:-5])
1067+
# We 4x the feerate to beat the min-relay fee
1068+
next_feerate = '{}perkw'.format(rate * 4)
1069+
1070+
# Initiate an RBF
1071+
startweight = 42 + 172 # base weight, funding output
1072+
initpsbt = l1.rpc.utxopsbt(chan_amount, next_feerate, startweight,
1073+
prev_utxos, reservedok=True,
1074+
min_witness_weight=110,
1075+
excess_as_change=True)
1076+
1077+
# Peers try RBF, break on initial COMMITMENT_SIGNED
1078+
bump = l1.rpc.openchannel_bump(chan_id, chan_amount, initpsbt['psbt'])
1079+
with pytest.raises(RpcError):
1080+
l1.rpc.openchannel_update(chan_id, bump['psbt'])
1081+
wait_for(lambda: l1.rpc.getpeer(l2.info['id'])['connected'] is False)
1082+
1083+
# We don't have the commtiments yet, there's no scratch_txid
1084+
inflights = only_one(l1.rpc.listpeerchannels()['channels'])['inflight']
1085+
assert len(inflights) == 2
1086+
assert 'scratch_txid' not in inflights[1]
1087+
1088+
# Close the channel!
1089+
l1.rpc.close(chan_id, 1)
1090+
l1.daemon.wait_for_logs(['Broadcasting txid {}'.format(inflights[0]['scratch_txid']),
1091+
'sendrawtx exit 0'])
1092+
1093+
wait_for(lambda: inflights[0]['scratch_txid'] in bitcoind.rpc.getrawmempool())
1094+
assert inflights[0]['funding_txid'] in bitcoind.rpc.getrawmempool()
1095+
assert inflights[1]['funding_txid'] not in bitcoind.rpc.getrawmempool()
1096+
1097+
10341098
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
10351099
@pytest.mark.openchannel('v2')
10361100
def test_rbf_no_overlap(node_factory, bitcoind, chainparams):

0 commit comments

Comments
 (0)