mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 23:24:27 +01:00
pytest: test CPFP using anchors.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -3669,3 +3669,70 @@ def test_onchain_rexmit_tx(node_factory, bitcoind):
|
||||
|
||||
l1.start()
|
||||
wait_for(lambda: len(bitcoind.rpc.getrawmempool()) == 1)
|
||||
|
||||
|
||||
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd anchors unsupported')
|
||||
@pytest.mark.developer("needs dev_disconnect")
|
||||
def test_closing_anchorspend_htlc_tx_rbf(node_factory, bitcoind):
|
||||
# We want an outstanding HTLC for l1, so it uses anchor to push.
|
||||
# Set feerates to lowball for now.
|
||||
l1, l2 = node_factory.line_graph(2, opts=[{'feerates': (1000,) * 4,
|
||||
'experimental-anchors': None},
|
||||
{'feerates': (1000,) * 4,
|
||||
'experimental-anchors': None,
|
||||
'disconnect': ['-WIRE_UPDATE_FAIL_HTLC']}])
|
||||
assert 'anchors_zero_fee_htlc_tx/even' in only_one(l1.rpc.listpeerchannels()['channels'])['channel_type']['names']
|
||||
|
||||
inv = l2.rpc.invoice(123000, 'label', 'description')
|
||||
l2.rpc.delinvoice('label', 'unpaid')
|
||||
|
||||
rhash = inv['payment_hash']
|
||||
routestep = {
|
||||
'amount_msat': 123000000,
|
||||
'id': l2.info['id'],
|
||||
'delay': 12,
|
||||
'channel': first_scid(l1, l2)
|
||||
}
|
||||
l1.rpc.sendpay([routestep], rhash, payment_secret=inv['payment_secret'])
|
||||
l2.daemon.wait_for_log('dev_disconnect')
|
||||
l2.stop()
|
||||
|
||||
# Tell it fees have gone up: this should make it spend the anchor!
|
||||
l1.set_feerates((2000, 2000, 2000, 2000))
|
||||
bitcoind.generate_block(14)
|
||||
|
||||
l1.daemon.wait_for_log('Peer permanent failure in CHANNELD_NORMAL: Offered HTLC 0 SENT_ADD_ACK_REVOCATION cltv 116 hit deadline')
|
||||
l1.daemon.wait_for_log('Creating anchor spend for CPFP')
|
||||
|
||||
wait_for(lambda: len(bitcoind.rpc.getrawmempool()) == 2)
|
||||
|
||||
# But we don't mine it! And fees go up again!
|
||||
l1.set_feerates((3000, 3000, 3000, 3000))
|
||||
bitcoind.generate_block(1, needfeerate=5000)
|
||||
|
||||
l1.daemon.wait_for_log('RBF anchor spend')
|
||||
l1.daemon.wait_for_log('sendrawtx exit 0')
|
||||
|
||||
# And now we'll get it in (there's some rounding, so feerate a bit lower!)
|
||||
bitcoind.generate_block(1, needfeerate=2990)
|
||||
|
||||
wait_for(lambda: 'ONCHAIN:Tracking our own unilateral close' in only_one(l1.rpc.listpeerchannels()['channels'])['status'])
|
||||
|
||||
# Now it needs to expire the HTLC tx.
|
||||
_, txid, blocks = l1.wait_for_onchaind_tx('OUR_HTLC_TIMEOUT_TX',
|
||||
'OUR_UNILATERAL/OUR_HTLC')
|
||||
assert blocks == -3
|
||||
|
||||
# It will have RBFd it already, to get that txid!
|
||||
assert l1.daemon.is_in_log(r'RBF HTLC txid .* \(fee 0sat\) with txid {} \(fee .*sat\)'.format(txid))
|
||||
|
||||
# Requirements go up again! We should RBF again.
|
||||
l1.set_feerates((5000, 5000, 5000, 5000))
|
||||
line = l1.daemon.wait_for_log(r'RBF HTLC txid {} \(fee .*sat\) with txid .* '.format(txid))
|
||||
txid = re.match(r'.*with txid ([0-9a-f]*) ', line).group(1)
|
||||
|
||||
# It will enter the mempool
|
||||
wait_for(lambda: txid in bitcoind.rpc.getrawmempool())
|
||||
|
||||
# And this will mine it!
|
||||
bitcoind.generate_block(1, needfeerate=4990)
|
||||
|
||||
Reference in New Issue
Block a user