Browse Source

pytest: add more multi-part-payment tests.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
travis-debug
Rusty Russell 5 years ago
committed by Christian Decker
parent
commit
326ceab8ad
  1. 73
      tests/test_pay.py

73
tests/test_pay.py

@ -2647,3 +2647,76 @@ def test_partial_payment(node_factory, bitcoind, executor):
assert pay['status'] == 'complete'
assert pay['number_of_parts'] == 2
assert pay['amount_sent_msat'] == Millisatoshi(1002)
@unittest.skipIf(not EXPERIMENTAL_FEATURES, "needs partid support")
def test_partial_payment_timeout(node_factory, bitcoind):
l1, l2 = node_factory.line_graph(2)
inv = l2.rpc.invoice(1000, 'inv', 'inv')
paysecret = l2.rpc.decodepay(inv['bolt11'])['payment_secret']
route = l1.rpc.getroute(l2.info['id'], 500, 1)['route']
l1.rpc.call('sendpay', [route, inv['payment_hash'], None, 1000, inv['bolt11'], paysecret, 1])
with pytest.raises(RpcError, match=r'WIRE_MPP_TIMEOUT'):
l1.rpc.call('waitsendpay', [inv['payment_hash'], 70 + TIMEOUT // 4, 1])
# We can still pay it normally.
l1.rpc.call('sendpay', [route, inv['payment_hash'], None, 1000, inv['bolt11'], paysecret, 1])
l1.rpc.call('sendpay', [route, inv['payment_hash'], None, 1000, inv['bolt11'], paysecret, 2])
l1.rpc.call('waitsendpay', [inv['payment_hash'], TIMEOUT, 1])
l1.rpc.call('waitsendpay', [inv['payment_hash'], TIMEOUT, 2])
@unittest.skipIf(not EXPERIMENTAL_FEATURES, "needs partid support")
def test_partial_payment_restart(node_factory, bitcoind):
"""Test that we recover a set when we restart"""
l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True,
opts=[{}]
+ [{'may_reconnect': True}] * 2)
inv = l3.rpc.invoice(1000, 'inv', 'inv')
paysecret = l3.rpc.decodepay(inv['bolt11'])['payment_secret']
route = l1.rpc.getroute(l3.info['id'], 500, 1)['route']
l1.rpc.call('sendpay', [route, inv['payment_hash'], None, 1000, inv['bolt11'], paysecret, 1])
wait_for(lambda: [f['status'] for f in l2.rpc.listforwards()['forwards']] == ['offered'])
# Restart, and make sure it's reconnected to l2.
l3.restart()
print(l2.rpc.listpeers())
wait_for(lambda: [p['connected'] for p in l2.rpc.listpeers()['peers']] == [True, True])
# Pay second part.
l1.rpc.call('sendpay', [route, inv['payment_hash'], None, 1000, inv['bolt11'], paysecret, 2])
l1.rpc.call('waitsendpay', [inv['payment_hash'], TIMEOUT, 1])
l1.rpc.call('waitsendpay', [inv['payment_hash'], TIMEOUT, 2])
@unittest.skipIf(not DEVELOPER, "needs dev-fail")
@unittest.skipIf(not EXPERIMENTAL_FEATURES, "needs partid support")
def test_partial_payment_htlc_loss(node_factory, bitcoind):
"""Test that we discard a set when the HTLC is lost"""
l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True)
inv = l3.rpc.invoice(1000, 'inv', 'inv')
paysecret = l3.rpc.decodepay(inv['bolt11'])['payment_secret']
route = l1.rpc.getroute(l3.info['id'], 500, 1)['route']
l1.rpc.call('sendpay', [route, inv['payment_hash'], None, 1000, inv['bolt11'], paysecret, 1])
wait_for(lambda: [f['status'] for f in l2.rpc.listforwards()['forwards']] == ['offered'])
l2.rpc.dev_fail(l3.info['id'])
# Since HTLC is missing from commit (dust), it's closed as soon as l2 sees
# it onchain. l3 shouldn't crash though.
bitcoind.generate_block(1, wait_for_mempool=1)
with pytest.raises(RpcError,
match=r'WIRE_PERMANENT_CHANNEL_FAILURE \(reply from remote\)'):
l1.rpc.call('waitsendpay', [inv['payment_hash'], TIMEOUT, 1])

Loading…
Cancel
Save