Browse Source

tests/test_pay.py: Provide test showing that blockheight disagreement causes us to advance routehints too aggressively.

The worst effect is that unpublished nodes are harder to pay, but
even published ones make us do unnecessary work, since we are
losing routehints from the published ones that could help us
actually route better to them.
bump-pyln-proto
ZmnSCPxj jxPCSnmZ 4 years ago
committed by Christian Decker
parent
commit
29df517966
  1. 49
      tests/test_pay.py

49
tests/test_pay.py

@ -3306,3 +3306,52 @@ def test_listpays_ongoing_attempt(node_factory, bitcoind, executor):
# Now restart and see if we still can aggregate things correctly. # Now restart and see if we still can aggregate things correctly.
l1.restart() l1.restart()
l1.rpc.listpays() l1.rpc.listpays()
@pytest.mark.xfail(strict=True)
@unittest.skipIf(not DEVELOPER, "needs use_shadow")
def test_mpp_waitblockheight_routehint_conflict(node_factory, bitcoind, executor):
'''
We have a bug where a blockheight disagreement between us and
the receiver causes us to advance through the routehints a bit
too aggressively.
'''
l1, l2, l3 = node_factory.get_nodes(3)
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1l2 = l1.fund_channel(l2, 10**7, announce_channel=True)
l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
l2.fund_channel(l3, 10**7, announce_channel=False)
bitcoind.generate_block(6)
sync_blockheight(bitcoind, [l1, l2, l3])
# Wait for l3 to learn about l1->l2, otherwise it will think
# l2 is a deadend and not add it to the routehint.
wait_for(lambda: len(l3.rpc.listchannels(l1l2)['channels']) >= 2)
# Now make the l1 payer stop receiving blocks.
def no_more_blocks(req):
return {"result": None,
"error": {"code": -8, "message": "Block height out of range"}, "id": req['id']}
l1.daemon.rpcproxy.mock_rpc('getblockhash', no_more_blocks)
# Increase blockheight by 2, like in test_blockheight_disagreement.
bitcoind.generate_block(2)
sync_blockheight(bitcoind, [l3])
inv = l3.rpc.invoice(Millisatoshi(2 * 10000 * 1000), 'i', 'i', exposeprivatechannels=True)['bolt11']
# Have l1 pay l3
def pay(l1, inv):
l1.rpc.dev_pay(inv, use_shadow=False)
fut = executor.submit(pay, l1, inv)
# Make sure l1 sends out the HTLC.
l1.daemon.wait_for_logs([r'NEW:: HTLC LOCAL'])
# Unblock l1 from new blocks.
l1.daemon.rpcproxy.mock_rpc('getblockhash', None)
# pay command should complete without error
fut.result(TIMEOUT)

Loading…
Cancel
Save