pytest: Test `pay` can exclude error node

This commit is contained in:
trueptolemy 2019-09-05 22:44:19 +08:00 committed by ZmnSCPxj, ZmnSCPxj jxPCSmnZ
parent a3a0f651e3
commit d4104c15aa
1 changed files with 66 additions and 0 deletions

View File

@ -121,6 +121,72 @@ def test_pay_limits(node_factory):
assert status[0]['strategy'] == "Initial attempt"
def test_pay_exclude_node(node_factory, bitcoind):
"""Test excluding the node if there's the NODE-level error in the failure_code
"""
# FIXME: Remove our reliance on HTLCs failing on startup and the need for
# this plugin
opts = [{}, {'plugin': os.path.join(os.getcwd(), 'tests/plugins/fail_htlcs.py')}, {}]
l1, l2, l3 = node_factory.line_graph(3, opts=opts, wait_for_announce=True)
amount = 10**8
inv = l3.rpc.invoice(amount, "test1", 'description')['bolt11']
with pytest.raises(RpcError):
l1.rpc.pay(inv)
# It should have retried (once without routehint, too)
status = l1.rpc.call('paystatus', {'bolt11': inv})['pay'][0]['attempts']
# Excludes channel, then ignores routehint which includes that, then
# it excludes other channel.
assert len(status) == 2
assert status[0]['strategy'] == "Initial attempt"
assert status[0]['failure']['data']['failcodename'] == 'WIRE_TEMPORARY_NODE_FAILURE'
assert status[1]['strategy'].startswith("Excluded node {}".format(l2.info['id']))
assert 'failure' in status[1]
# l1->l4->l5->l3 is the longer route. This makes sure this route won't be
# tried for the first pay attempt.
l4 = node_factory.get_node()
l5 = node_factory.get_node()
l1.rpc.connect(l4.info['id'], 'localhost', l4.port)
l4.rpc.connect(l5.info['id'], 'localhost', l5.port)
l5.rpc.connect(l3.info['id'], 'localhost', l3.port)
scid14 = l1.fund_channel(l4, 10**6, wait_for_active=False)
scid45 = l4.fund_channel(l5, 10**6, wait_for_active=False)
scid53 = l5.fund_channel(l3, 10**6, wait_for_active=False)
bitcoind.generate_block(5)
l1.daemon.wait_for_logs([r'update for channel {}/0 now ACTIVE'
.format(scid14),
r'update for channel {}/1 now ACTIVE'
.format(scid14),
r'update for channel {}/0 now ACTIVE'
.format(scid45),
r'update for channel {}/1 now ACTIVE'
.format(scid45),
r'update for channel {}/0 now ACTIVE'
.format(scid53),
r'update for channel {}/1 now ACTIVE'
.format(scid53)])
inv = l3.rpc.invoice(amount, "test2", 'description')['bolt11']
# This `pay` will work
l1.rpc.pay(inv)
# It should have retried (once without routehint, too)
status = l1.rpc.call('paystatus', {'bolt11': inv})['pay'][0]['attempts']
# Excludes channel, then ignores routehint which includes that, then
# it excludes other channel.
assert len(status) == 2
assert status[0]['strategy'] == "Initial attempt"
assert status[0]['failure']['data']['failcodename'] == 'WIRE_TEMPORARY_NODE_FAILURE'
assert status[1]['strategy'].startswith("Excluded node {}".format(l2.info['id']))
assert 'success' in status[1]
def test_pay0(node_factory):
"""Test paying 0 amount
"""