Browse Source

pytest: use get_nodes more widely.

I started replacing all get_node() calls, but got bored, so then just did the
tests which call get_node() 3 times or more.

Ends up not making a measurable speed difference, but it does make some
things neater and more standard.

Times with SLOW_MACHINE=1 (given that's how Travis tests):

Time before (non-valgrind):
	393 sec (had 3 failures?)
Time after (non-valgrind):
	410 sec

Time before (valgrind):
	890 seconds (had 2 failures)
Time after (valgrind):
	892 sec

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
bump-pyln-proto
Rusty Russell 4 years ago
committed by Christian Decker
parent
commit
fde353ab00
  1. 268
      tests/test_closing.py
  2. 33
      tests/test_connection.py
  3. 50
      tests/test_gossip.py
  4. 4
      tests/test_invoices.py
  5. 54
      tests/test_misc.py
  6. 78
      tests/test_pay.py
  7. 11
      tests/test_plugin.py

268
tests/test_closing.py

@ -278,16 +278,14 @@ def test_closing_negotiation_reconnect(node_factory, bitcoind):
disconnects = ['-WIRE_CLOSING_SIGNED',
'@WIRE_CLOSING_SIGNED',
'+WIRE_CLOSING_SIGNED']
l1 = node_factory.get_node(disconnect=disconnects, may_reconnect=True)
l2 = node_factory.get_node(may_reconnect=True)
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
chan = l1.fund_channel(l2, 10**6)
l1, l2 = node_factory.line_graph(2, opts=[{'disconnect': disconnects,
'may_reconnect': True},
{'may_reconnect': True}])
l1.pay(l2, 200000000)
assert bitcoind.rpc.getmempoolinfo()['size'] == 0
l1.rpc.close(chan)
l1.rpc.close(l2.info['id'])
l1.daemon.wait_for_log(' to CHANNELD_SHUTTING_DOWN')
l2.daemon.wait_for_log(' to CHANNELD_SHUTTING_DOWN')
@ -362,20 +360,14 @@ def test_closing_specified_destination(node_factory, bitcoind, chainparams):
def closing_negotiation_step(node_factory, bitcoind, chainparams, opts):
rate = 29006 # closing fee negotiation starts at 21000
opener = node_factory.get_node(feerates=(rate, rate, rate, rate))
rate = 27625 # closing fee negotiation starts at 20000
peer = node_factory.get_node(feerates=(rate, rate, rate, rate))
orate = 29006 # closing fee negotiation starts at 21000
prate = 27625 # closing fee negotiation starts at 20000
opener, peer = node_factory.line_graph(2, opts=[{'feerates': (orate, orate, orate, orate)},
{'feerates': (prate, prate, prate, prate)}])
opener_id = opener.info['id']
peer_id = peer.info['id']
fund_amount = 10**6
opener.rpc.connect(peer_id, 'localhost', peer.port)
opener.fund_channel(peer, fund_amount)
assert bitcoind.rpc.getmempoolinfo()['size'] == 0
if opts['close_initiated_by'] == 'opener':
@ -508,15 +500,14 @@ def test_penalty_inhtlc(node_factory, bitcoind, executor, chainparams):
coin_mvt_plugin = os.path.join(os.getcwd(), 'tests/plugins/coin_movements.py')
# We suppress each one after first commit; HTLC gets added not fulfilled.
# Feerates identical so we don't get gratuitous commit to update them
l1 = node_factory.get_node(disconnect=['=WIRE_COMMITMENT_SIGNED-nocommit'],
may_fail=True, feerates=(7500, 7500, 7500, 7500),
allow_broken_log=True,
options={'plugin': coin_mvt_plugin})
l2 = node_factory.get_node(disconnect=['=WIRE_COMMITMENT_SIGNED-nocommit'],
options={'plugin': coin_mvt_plugin})
l1, l2 = node_factory.line_graph(2, opts=[{'disconnect': ['=WIRE_COMMITMENT_SIGNED-nocommit'],
'may_fail': True,
'feerates': (7500, 7500, 7500, 7500),
'allow_broken_log': True,
'plugin': coin_mvt_plugin},
{'disconnect': ['=WIRE_COMMITMENT_SIGNED-nocommit'],
'plugin': coin_mvt_plugin}])
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.fund_channel(l2, 10**6)
channel_id = first_channel_id(l1, l2)
# Now, this will get stuck due to l1 commit being disabled..
@ -605,16 +596,14 @@ def test_penalty_outhtlc(node_factory, bitcoind, executor, chainparams):
coin_mvt_plugin = os.path.join(os.getcwd(), 'tests/plugins/coin_movements.py')
# First we need to get funds to l2, so suppress after second.
# Feerates identical so we don't get gratuitous commit to update them
l1 = node_factory.get_node(disconnect=['=WIRE_COMMITMENT_SIGNED*3-nocommit'],
may_fail=True,
feerates=(7500, 7500, 7500, 7500),
allow_broken_log=True,
options={'plugin': coin_mvt_plugin})
l2 = node_factory.get_node(disconnect=['=WIRE_COMMITMENT_SIGNED*3-nocommit'],
options={'plugin': coin_mvt_plugin})
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.fund_channel(l2, 10**6)
l1, l2 = node_factory.line_graph(2,
opts=[{'disconnect': ['=WIRE_COMMITMENT_SIGNED*3-nocommit'],
'may_fail': True,
'feerates': (7500, 7500, 7500, 7500),
'allow_broken_log': True,
'plugin': coin_mvt_plugin},
{'disconnect': ['=WIRE_COMMITMENT_SIGNED*3-nocommit'],
'plugin': coin_mvt_plugin}])
channel_id = first_channel_id(l1, l2)
# Move some across to l2.
@ -727,38 +716,29 @@ def test_penalty_htlc_tx_fulfill(node_factory, bitcoind, chainparams):
# We track channel balances, to verify that accounting is ok.
coin_mvt_plugin = os.path.join(os.getcwd(), 'tests/plugins/coin_movements.py')
l1 = node_factory.get_node(disconnect=['=WIRE_UPDATE_FULFILL_HTLC',
'-WIRE_UPDATE_FULFILL_HTLC'],
may_reconnect=True,
options={'dev-no-reconnect': None})
l2 = node_factory.get_node(options={'plugin': coin_mvt_plugin,
'disable-mpp': None,
l1, l2, l3, l4 = node_factory.line_graph(4,
opts=[{'disconnect': ['-WIRE_UPDATE_FULFILL_HTLC'],
'may_reconnect': True,
'dev-no-reconnect': None},
may_reconnect=True,
allow_broken_log=True)
l3 = node_factory.get_node(options={'plugin': coin_mvt_plugin,
'dev-no-reconnect': None},
may_reconnect=True,
allow_broken_log=True)
l4 = node_factory.get_node(may_reconnect=True, options={'dev-no-reconnect': None})
l2.rpc.connect(l1.info['id'], 'localhost', l1.port)
l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
l3.rpc.connect(l4.info['id'], 'localhost', l4.port)
{'plugin': coin_mvt_plugin,
'disable-mpp': None,
'dev-no-reconnect': None,
'may_reconnect': True,
'allow_broken_log': True},
{'plugin': coin_mvt_plugin,
'dev-no-reconnect': None,
'may_reconnect': True,
'allow_broken_log': True},
{'dev-no-reconnect': None,
'may_reconnect': True}],
wait_for_announce=True)
c12 = l2.fund_channel(l1, 10**6)
l2.fund_channel(l3, 10**6)
c34 = l3.fund_channel(l4, 10**6)
channel_id = first_channel_id(l2, l3)
bitcoind.generate_block(5)
l1.wait_channel_active(c34)
l4.wait_channel_active(c12)
# push some money so that 1 + 4 can both send htlcs
inv = l1.rpc.invoice(10**9 // 2, '1', 'balancer')
l2.rpc.pay(inv['bolt11'])
l2.rpc.waitsendpay(inv['payment_hash'])
inv = l2.rpc.invoice(10**9 // 2, '1', 'balancer')
l1.rpc.pay(inv['bolt11'])
l1.rpc.waitsendpay(inv['payment_hash'])
inv = l4.rpc.invoice(10**9 // 2, '1', 'balancer')
l2.rpc.pay(inv['bolt11'])
@ -874,43 +854,31 @@ def test_penalty_htlc_tx_timeout(node_factory, bitcoind, chainparams):
# We track channel balances, to verify that accounting is ok.
coin_mvt_plugin = os.path.join(os.getcwd(), 'tests/plugins/coin_movements.py')
l1 = node_factory.get_node(disconnect=['=WIRE_UPDATE_FULFILL_HTLC',
'-WIRE_UPDATE_FULFILL_HTLC'],
may_reconnect=True,
options={'dev-no-reconnect': None})
l2 = node_factory.get_node(options={'plugin': coin_mvt_plugin,
l1, l2, l3, l4, l5 = node_factory.get_nodes(5,
opts=[{'disconnect': ['-WIRE_UPDATE_FULFILL_HTLC'],
'may_reconnect': True,
'dev-no-reconnect': None},
may_reconnect=True,
allow_broken_log=True)
l3 = node_factory.get_node(options={'plugin': coin_mvt_plugin,
'dev-no-reconnect': None},
may_reconnect=True,
allow_broken_log=True)
l4 = node_factory.get_node(may_reconnect=True, options={'dev-no-reconnect': None})
l5 = node_factory.get_node(disconnect=['-WIRE_UPDATE_FULFILL_HTLC'],
may_reconnect=True,
options={'dev-no-reconnect': None})
{'plugin': coin_mvt_plugin,
'dev-no-reconnect': None,
'may_reconnect': True,
'allow_broken_log': True},
{'plugin': coin_mvt_plugin,
'dev-no-reconnect': None,
'may_reconnect': True,
'allow_broken_log': True},
{'dev-no-reconnect': None},
{'disconnect': ['-WIRE_UPDATE_FULFILL_HTLC'],
'may_reconnect': True,
'dev-no-reconnect': None}])
node_factory.join_nodes([l1, l2, l3, l4], wait_for_announce=True)
node_factory.join_nodes([l3, l5], wait_for_announce=True)
l2.rpc.connect(l1.info['id'], 'localhost', l1.port)
l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
l3.rpc.connect(l4.info['id'], 'localhost', l4.port)
l3.rpc.connect(l5.info['id'], 'localhost', l5.port)
c12 = l2.fund_channel(l1, 10**6)
l2.fund_channel(l3, 10**6)
c34 = l3.fund_channel(l4, 10**6)
c35 = l3.fund_channel(l5, 10**6)
channel_id = first_channel_id(l2, l3)
bitcoind.generate_block(5)
l1.wait_channel_active(c34)
l1.wait_channel_active(c35)
l4.wait_channel_active(c12)
l5.wait_channel_active(c12)
# push some money so that 1 + 4 can both send htlcs
inv = l1.rpc.invoice(10**9 // 2, '1', 'balancer')
l2.rpc.pay(inv['bolt11'])
inv = l2.rpc.invoice(10**9 // 2, '1', 'balancer')
l1.rpc.pay(inv['bolt11'])
inv = l4.rpc.invoice(10**9 // 2, '1', 'balancer')
l2.rpc.pay(inv['bolt11'])
@ -1027,22 +995,22 @@ def test_onchain_first_commit(node_factory, bitcoind):
# HTLC 1->2, 1 fails just after funding.
disconnects = ['+WIRE_FUNDING_LOCKED', 'permfail']
l1 = node_factory.get_node(disconnect=disconnects, options={'plugin': coin_mvt_plugin})
# Make locktime different, as we once had them reversed!
l2 = node_factory.get_node(options={'watchtime-blocks': 10, 'plugin': coin_mvt_plugin})
l1, l2 = node_factory.line_graph(2, opts=[{'disconnect': disconnects,
'plugin': coin_mvt_plugin},
{'watchtime-blocks': 10,
'plugin': coin_mvt_plugin}],
fundchannel=False)
l1.fundwallet(10**7)
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.rpc.fundchannel(l2.info['id'], 10**6)
l1.daemon.wait_for_log('sendrawtx exit 0')
l1.bitcoin.generate_block(1)
bitcoind.generate_block(1)
# l1 will drop to chain.
l1.daemon.wait_for_log('permfail')
l1.daemon.wait_for_log('sendrawtx exit 0')
l1.bitcoin.generate_block(1)
bitcoind.generate_block(1)
l1.daemon.wait_for_log(' to ONCHAIN')
l2.daemon.wait_for_log(' to ONCHAIN')
@ -1117,14 +1085,11 @@ def test_onchain_unwatch(node_factory, bitcoind):
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1")
def test_onchaind_replay(node_factory, bitcoind):
disconnects = ['+WIRE_REVOKE_AND_ACK', 'permfail']
options = {'watchtime-blocks': 201, 'cltv-delta': 101}
# Feerates identical so we don't get gratuitous commit to update them
l1 = node_factory.get_node(options=options, disconnect=disconnects,
feerates=(7500, 7500, 7500, 7500))
l2 = node_factory.get_node(options=options)
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.fund_channel(l2, 10**6)
l1, l2 = node_factory.line_graph(2, opts=[{'watchtime-blocks': 201, 'cltv-delta': 101,
'disconnect': disconnects,
'feerates': (7500, 7500, 7500, 7500)},
{'watchtime-blocks': 201, 'cltv-delta': 101}])
rhash = l2.rpc.invoice(10**8, 'onchaind_replay', 'desc')['payment_hash']
routestep = {
@ -1176,13 +1141,12 @@ def test_onchain_dust_out(node_factory, bitcoind, executor):
# HTLC 1->2, 1 fails after it's irrevocably committed
disconnects = ['@WIRE_REVOKE_AND_ACK', 'permfail']
# Feerates identical so we don't get gratuitous commit to update them
l1 = node_factory.get_node(disconnect=disconnects,
feerates=(7500, 7500, 7500, 7500),
options={'plugin': coin_mvt_plugin})
l2 = node_factory.get_node(options={'plugin': coin_mvt_plugin})
l1, l2 = node_factory.line_graph(2,
opts=[{'disconnect': disconnects,
'feerates': (7500, 7500, 7500, 7500),
'plugin': coin_mvt_plugin},
{'plugin': coin_mvt_plugin}])
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.fund_channel(l2, 10**6)
channel_id = first_channel_id(l1, l2)
# Must be dust!
@ -1248,13 +1212,12 @@ def test_onchain_timeout(node_factory, bitcoind, executor):
# HTLC 1->2, 1 fails just after it's irrevocably committed
disconnects = ['+WIRE_REVOKE_AND_ACK*3', 'permfail']
# Feerates identical so we don't get gratuitous commit to update them
l1 = node_factory.get_node(disconnect=disconnects,
feerates=(7500, 7500, 7500, 7500),
options={'plugin': coin_mvt_plugin})
l2 = node_factory.get_node(options={'plugin': coin_mvt_plugin})
l1, l2 = node_factory.line_graph(2,
opts=[{'disconnect': disconnects,
'feerates': (7500, 7500, 7500, 7500),
'plugin': coin_mvt_plugin},
{'plugin': coin_mvt_plugin}])
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.fund_channel(l2, 10**6)
channel_id = first_channel_id(l1, l2)
rhash = l2.rpc.invoice(10**8, 'onchain_timeout', 'desc')['payment_hash']
@ -1333,9 +1296,10 @@ def test_onchain_middleman(node_factory, bitcoind):
# HTLC 1->2->3, 1->2 goes down after 2 gets preimage from 3.
disconnects = ['-WIRE_UPDATE_FULFILL_HTLC', 'permfail']
l1 = node_factory.get_node(options={'plugin': coin_mvt_plugin})
l2 = node_factory.get_node(disconnect=disconnects, options={'plugin': coin_mvt_plugin})
l3 = node_factory.get_node()
l1, l2, l3 = node_factory.get_nodes(3, opts=[{'plugin': coin_mvt_plugin},
{'plugin': coin_mvt_plugin,
'disconnect': disconnects},
{}])
# l2 connects to both, so l1 can't reconnect and thus l2 drops to chain
l2.rpc.connect(l1.info['id'], 'localhost', l1.port)
@ -1422,12 +1386,11 @@ def test_onchain_middleman_their_unilateral_in(node_factory, bitcoind):
l1_disconnects = ['=WIRE_UPDATE_FULFILL_HTLC', 'permfail']
l2_disconnects = ['-WIRE_UPDATE_FULFILL_HTLC']
l1 = node_factory.get_node(disconnect=l1_disconnects,
options={'plugin': coin_mvt_plugin})
l2 = node_factory.get_node(disconnect=l2_disconnects,
options={'plugin': coin_mvt_plugin})
l3 = node_factory.get_node()
l1, l2, l3 = node_factory.get_nodes(3, opts=[{'plugin': coin_mvt_plugin,
'disconnect': l1_disconnects},
{'plugin': coin_mvt_plugin,
'disconnect': l2_disconnects},
{}])
l2.rpc.connect(l1.info['id'], 'localhost', l1.port)
l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
@ -1508,20 +1471,12 @@ def test_onchain_their_unilateral_out(node_factory, bitcoind):
disconnects = ['-WIRE_UPDATE_FAIL_HTLC', 'permfail']
l1 = node_factory.get_node(disconnect=disconnects,
options={'plugin': coin_mvt_plugin})
l2 = node_factory.get_node(options={'plugin': coin_mvt_plugin})
l2.rpc.connect(l1.info['id'], 'localhost', l1.port)
c12 = l2.fund_channel(l1, 10**6)
l1, l2 = node_factory.line_graph(2, opts=[{'plugin': coin_mvt_plugin},
{'disconnect': disconnects,
'plugin': coin_mvt_plugin}])
channel_id = first_channel_id(l1, l2)
bitcoind.generate_block(5)
l1.wait_channel_active(c12)
sync_blockheight(bitcoind, [l1, l2])
route = l2.rpc.getroute(l1.info['id'], 10**8, 1)["route"]
route = l1.rpc.getroute(l2.info['id'], 10**8, 1)["route"]
assert len(route) == 1
q = queue.Queue()
@ -1530,7 +1485,7 @@ def test_onchain_their_unilateral_out(node_factory, bitcoind):
try:
# rhash is fake
rhash = 'B1' * 32
l2.rpc.sendpay(route, rhash)
l1.rpc.sendpay(route, rhash)
q.put(None)
except Exception as err:
q.put(err)
@ -1539,16 +1494,16 @@ def test_onchain_their_unilateral_out(node_factory, bitcoind):
t.daemon = True
t.start()
# l1 will drop to chain.
l1.daemon.wait_for_log('sendrawtx exit 0')
l1.bitcoin.generate_block(1)
l2.daemon.wait_for_log(' to ONCHAIN')
# l2 will drop to chain.
l2.daemon.wait_for_log('sendrawtx exit 0')
l2.bitcoin.generate_block(1)
l1.daemon.wait_for_log(' to ONCHAIN')
l2.daemon.wait_for_log('THEIR_UNILATERAL/OUR_HTLC')
l2.daemon.wait_for_log(' to ONCHAIN')
l1.daemon.wait_for_log('THEIR_UNILATERAL/OUR_HTLC')
# l2 should wait til to_self_delay (10), then fulfill onchain
l1.bitcoin.generate_block(9)
l2.wait_for_onchaind_broadcast('OUR_HTLC_TIMEOUT_TO_US',
# l1 should wait til to_self_delay (10), then fulfill onchain
l2.bitcoin.generate_block(9)
l1.wait_for_onchaind_broadcast('OUR_HTLC_TIMEOUT_TO_US',
'THEIR_UNILATERAL/OUR_HTLC')
err = q.get(timeout=10)
@ -1559,13 +1514,13 @@ def test_onchain_their_unilateral_out(node_factory, bitcoind):
assert not t.is_alive()
# 100 blocks after last spend, l1+l2 should be done.
l1.bitcoin.generate_block(100)
l2.daemon.wait_for_log('onchaind complete, forgetting peer')
l2.bitcoin.generate_block(100)
l1.daemon.wait_for_log('onchaind complete, forgetting peer')
l2.daemon.wait_for_log('onchaind complete, forgetting peer')
# Verify accounting for l1 & l2
assert account_balance(l1, channel_id) == 0
assert account_balance(l2, channel_id) == 0
assert account_balance(l1, channel_id) == 0
def test_listfunds_after_their_unilateral(node_factory, bitcoind):
@ -1603,12 +1558,9 @@ def test_onchain_feechange(node_factory, bitcoind, executor):
# We need 2 to drop to chain, because then 1's HTLC timeout tx
# is generated on-the-fly, and is thus feerate sensitive.
disconnects = ['-WIRE_UPDATE_FAIL_HTLC', 'permfail']
l1 = node_factory.get_node(may_reconnect=True)
l2 = node_factory.get_node(disconnect=disconnects,
may_reconnect=True)
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.fund_channel(l2, 10**6)
l1, l2 = node_factory.line_graph(2, opts=[{'may_reconnect': True},
{'may_reconnect': True,
'disconnect': disconnects}])
rhash = l2.rpc.invoice(10**8, 'onchain_timeout', 'desc')['payment_hash']
# We underpay, so it fails.

33
tests/test_connection.py

@ -171,12 +171,11 @@ def test_opening_tiny_channel(node_factory):
l4_min_capacity = 10000 # the current default
l5_min_capacity = 20000 # a server with more than default minimum
l1 = node_factory.get_node(options={'min-capacity-sat': l1_min_capacity})
l2 = node_factory.get_node(options={'min-capacity-sat': l2_min_capacity})
l3 = node_factory.get_node(options={'min-capacity-sat': l3_min_capacity})
l4 = node_factory.get_node(options={'min-capacity-sat': l4_min_capacity})
l5 = node_factory.get_node(options={'min-capacity-sat': l5_min_capacity})
l1, l2, l3, l4, l5 = node_factory.get_nodes(5, opts=[{'min-capacity-sat': l1_min_capacity},
{'min-capacity-sat': l2_min_capacity},
{'min-capacity-sat': l3_min_capacity},
{'min-capacity-sat': l4_min_capacity},
{'min-capacity-sat': l5_min_capacity}])
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.rpc.connect(l3.info['id'], 'localhost', l3.port)
l1.rpc.connect(l4.info['id'], 'localhost', l4.port)
@ -212,9 +211,7 @@ def test_opening_tiny_channel(node_factory):
def test_second_channel(node_factory):
l1 = node_factory.get_node()
l2 = node_factory.get_node()
l3 = node_factory.get_node()
l1, l2, l3 = node_factory.get_nodes(3)
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.rpc.connect(l3.info['id'], 'localhost', l3.port)
@ -428,9 +425,7 @@ def test_reconnect_no_update(node_factory, executor):
def test_connect_stresstest(node_factory, executor):
# This test is unreliable, but it's better than nothing.
l1 = node_factory.get_node(may_reconnect=True)
l2 = node_factory.get_node(may_reconnect=True)
l3 = node_factory.get_node(may_reconnect=True)
l1, l2, l3 = node_factory.get_nodes(3, opts={'may_reconnect': True})
# Hack l3 into a clone of l2, to stress reconnect code.
l3.stop()
@ -1162,9 +1157,8 @@ def test_funding_close_upfront(node_factory, bitcoind):
@unittest.skipIf(TEST_NETWORK != 'regtest', "External wallet support doesn't work with elements yet.")
def test_funding_external_wallet(node_factory, bitcoind):
l1 = node_factory.get_node(options={'funding-confirms': 2})
l2 = node_factory.get_node(options={'funding-confirms': 2})
l3 = node_factory.get_node()
l1, l2, l3 = node_factory.get_nodes(3, opts=[{'funding-confirms': 2},
{'funding-confirms': 2}, {}])
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
assert(l1.rpc.listpeers()['peers'][0]['id'] == l2.info['id'])
@ -1422,7 +1416,12 @@ def test_update_fee(node_factory, bitcoind):
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1")
def test_fee_limits(node_factory, bitcoind):
l1, l2 = node_factory.line_graph(2, opts={'dev-max-fee-multiplier': 5, 'may_reconnect': True}, fundchannel=True)
l1, l2, l3, l4 = node_factory.get_nodes(4, opts=[{'dev-max-fee-multiplier': 5, 'may_reconnect': True},
{'dev-max-fee-multiplier': 5, 'may_reconnect': True},
{'ignore-fee-limits': True, 'may_reconnect': True},
{}])
node_factory.join_nodes([l1, l2], fundchannel=True)
# Kick off fee adjustment using HTLC.
l1.pay(l2, 1000)
@ -1441,7 +1440,6 @@ def test_fee_limits(node_factory, bitcoind):
sync_blockheight(bitcoind, [l1, l2])
# Trying to open a channel with too low a fee-rate is denied
l4 = node_factory.get_node()
l1.rpc.connect(l4.info['id'], 'localhost', l4.port)
with pytest.raises(RpcError, match='They sent error .* feerate_per_kw 253 below minimum'):
l1.fund_channel(l4, 10**6)
@ -1452,7 +1450,6 @@ def test_fee_limits(node_factory, bitcoind):
l1.start()
# Try with node which sets --ignore-fee-limits
l3 = node_factory.get_node(options={'ignore-fee-limits': 'true'}, may_reconnect=True)
l1.rpc.connect(l3.info['id'], 'localhost', l3.port)
chan = l1.fund_channel(l3, 10**6)

50
tests/test_gossip.py

@ -456,10 +456,11 @@ def test_routing_gossip_reconnect(node_factory):
# Connect two peers, reconnect and then see if we resume the
# gossip.
disconnects = ['-WIRE_CHANNEL_ANNOUNCEMENT']
l1 = node_factory.get_node(disconnect=disconnects,
may_reconnect=True)
l2 = node_factory.get_node(may_reconnect=True)
l3 = node_factory.get_node()
l1, l2, l3 = node_factory.get_nodes(3,
opts=[{'disconnect': disconnects,
'may_reconnect': True},
{'may_reconnect': True},
{}])
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.openchannel(l2, 20000)
@ -475,17 +476,13 @@ def test_routing_gossip_reconnect(node_factory):
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1")
def test_gossip_no_empty_announcements(node_factory, bitcoind):
# Need full IO logging so we can see gossip
opts = {'log-level': 'io'}
l1, l2 = node_factory.get_nodes(2, opts=opts)
# l3 sends CHANNEL_ANNOUNCEMENT to l2, but not CHANNEL_UDPATE.
l3 = node_factory.get_node(disconnect=['+WIRE_CHANNEL_ANNOUNCEMENT'],
options={'dev-no-reconnect': None},
may_reconnect=True)
l4 = node_factory.get_node(may_reconnect=True)
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
l3.rpc.connect(l4.info['id'], 'localhost', l4.port)
l1, l2, l3, l4 = node_factory.line_graph(4, opts=[{'log-level': 'io'},
{'log-level': 'io'},
{'disconnect': ['+WIRE_CHANNEL_ANNOUNCEMENT'],
'may_reconnect': True},
{'may_reconnect': True}],
fundchannel=False)
# Make an announced-but-not-updated channel.
l3.fund_channel(l4, 10**5)
@ -1094,9 +1091,11 @@ def test_gossipwith(node_factory):
def test_gossip_notices_close(node_factory, bitcoind):
# We want IO logging so we can replay a channel_announce to l1;
# We also *really* do feed it bad gossip!
l1 = node_factory.get_node(options={'log-level': 'io'},
allow_bad_gossip=True)
l2, l3 = node_factory.line_graph(2)
l1, l2, l3 = node_factory.get_nodes(3, opts=[{'log-level': 'io',
'allow_bad_gossip': True},
{},
{}])
node_factory.join_nodes([l2, l3])
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
bitcoind.generate_block(5)
@ -1174,7 +1173,8 @@ def test_getroute_exclude_duplicate(node_factory):
@unittest.skipIf(not DEVELOPER, "gossip propagation is slow without DEVELOPER=1")
def test_getroute_exclude(node_factory, bitcoind):
"""Test getroute's exclude argument"""
l1, l2, l3, l4 = node_factory.line_graph(4, wait_for_announce=True)
l1, l2, l3, l4, l5 = node_factory.get_nodes(5)
node_factory.join_nodes([l1, l2, l3, l4], wait_for_announce=True)
# This should work
route = l1.rpc.getroute(l4.info['id'], 1, 1)['route']
@ -1230,7 +1230,6 @@ def test_getroute_exclude(node_factory, bitcoind):
with pytest.raises(RpcError):
l1.rpc.getroute(l4.info['id'], 1, 1, exclude=[l3.info['id'], chan_l2l4])
l5 = node_factory.get_node()
l1.rpc.connect(l5.info['id'], 'localhost', l5.port)
scid15 = l1.fund_channel(l5, 1000000, wait_for_active=False)
l5.rpc.connect(l4.info['id'], 'localhost', l4.port)
@ -1520,10 +1519,10 @@ def test_gossip_announce_unknown_block(node_factory, bitcoind):
@unittest.skipIf(not DEVELOPER, "gossip without DEVELOPER=1 is slow")
def test_gossip_no_backtalk(node_factory):
l1, l2 = node_factory.line_graph(2, wait_for_announce=True)
# This connects, gets gossip, but should *not* play it back.
l3 = node_factory.get_node(options={'log-level': 'io'})
# l3 connects, gets gossip, but should *not* play it back.
l1, l2, l3 = node_factory.get_nodes(3,
opts=[{}, {}, {'log-level': 'io'}])
node_factory.join_nodes([l1, l2], wait_for_announce=True)
l3.rpc.connect(l2.info['id'], 'localhost', l2.port)
# Will get channel_announce, then two channel_update and two node_announcement
@ -1539,12 +1538,13 @@ def test_gossip_no_backtalk(node_factory):
@unittest.skipIf(not DEVELOPER, "Needs --dev-gossip")
@unittest.skipIf(TEST_NETWORK != 'regtest', "Channel announcement contains genesis hash, receiving node discards on mismatch")
def test_gossip_ratelimit(node_factory):
l1, l2, l3 = node_factory.get_nodes(3,
opts=[{}, {}, {'dev-gossip-time': 1568096251}])
# These make the channel exist, but we use our own gossip.
l1, l2 = node_factory.line_graph(2, wait_for_announce=True)
node_factory.join_nodes([l1, l2], wait_for_announce=True)
# Here are some ones I generated earlier (by removing gossip
# ratelimiting)
l3 = node_factory.get_node(options={'dev-gossip-time': 1568096251})
subprocess.run(['devtools/gossipwith',
'--max-messages=0',
'{}@localhost:{}'.format(l3.info['id'], l3.port),

4
tests/test_invoices.py

@ -183,7 +183,8 @@ def test_invoice_routeboost(node_factory, bitcoind):
def test_invoice_routeboost_private(node_factory, bitcoind):
"""Test routeboost 'r' hint in bolt11 invoice for private channels
"""
l1, l2 = node_factory.line_graph(2, fundamount=16777215, announce_channels=False)
l1, l2, l3 = node_factory.get_nodes(3)
node_factory.join_nodes([l1, l2], fundamount=16777215, announce_channels=False)
scid = l1.get_channel_scid(l2)
@ -245,7 +246,6 @@ def test_invoice_routeboost_private(node_factory, bitcoind):
# The existence of a public channel, even without capacity, will suppress
# the exposure of private channels.
l3 = node_factory.get_node()
l3.rpc.connect(l2.info['id'], 'localhost', l2.port)
scid2 = l3.fund_channel(l2, (10**5))
bitcoind.generate_block(5)

54
tests/test_misc.py

@ -35,8 +35,7 @@ def test_stop_pending_fundchannel(node_factory, executor):
freeing the daemon, but that needs a DB transaction to be open.
"""
l1 = node_factory.get_node()
l2 = node_factory.get_node()
l1, l2 = node_factory.get_nodes(2)
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
@ -69,8 +68,8 @@ def test_names(node_factory):
('0265b6ab5ec860cd257865d61ef0bbf5b3339c36cbda8b26b74e7f1dca490b6518', 'LOUDPHOTO', '0265b6')
]
for key, alias, color in configs:
n = node_factory.get_node()
nodes = node_factory.get_nodes(len(configs))
for n, (key, alias, color) in zip(nodes, configs):
assert n.daemon.is_in_log(r'public key {}, alias {}.* \(color #{}\)'
.format(key, alias, color))
@ -180,17 +179,19 @@ def test_lightningd_still_loading(node_factory, bitcoind, executor):
}
# Start it, establish channel, get extra funds.
l1, l2 = node_factory.line_graph(2, opts={'may_reconnect': True, 'wait_for_bitcoind_sync': False})
l1, l2, l3 = node_factory.get_nodes(3, opts=[{'may_reconnect': True,
'wait_for_bitcoind_sync': False},
{'may_reconnect': True,
'wait_for_bitcoind_sync': False},
{}])
node_factory.join_nodes([l1, l2])
# Balance l1<->l2 channel
l1.pay(l2, 10**9 // 2)
l1.stop()
# Start extra node.
l3 = node_factory.get_node()
# Now make sure it's behind.
# Now make sure l2 is behind.
bitcoind.generate_block(2)
# Make sure l2/l3 are synced
sync_blockheight(bitcoind, [l2, l3])
@ -463,11 +464,7 @@ def test_htlc_in_timeout(node_factory, bitcoind, executor):
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1")
def test_bech32_funding(node_factory, chainparams):
# Don't get any funds from previous runs.
l1 = node_factory.get_node(random_hsm=True)
l2 = node_factory.get_node(random_hsm=True)
# connect
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1, l2 = node_factory.line_graph(2, opts={'random_hsm': True}, fundchannel=False)
# fund a bech32 address and then open a channel with it
res = l1.openchannel(l2, 20000, 'bech32')
@ -1380,25 +1377,16 @@ def test_reserve_enforcement(node_factory, executor):
def test_htlc_send_timeout(node_factory, bitcoind, compat):
"""Test that we don't commit an HTLC to an unreachable node."""
# Feerates identical so we don't get gratuitous commit to update them
l1 = node_factory.get_node(
options={'log-level': 'io'},
feerates=(7500, 7500, 7500, 7500)
)
l1, l2, l3 = node_factory.line_graph(3, opts=[{'log-level': 'io',
'feerates': (7500, 7500, 7500, 7500)},
# Blackhole it after it sends HTLC_ADD to l3.
l2 = node_factory.get_node(disconnect=['0WIRE_UPDATE_ADD_HTLC'],
options={'log-level': 'io'},
feerates=(7500, 7500, 7500, 7500))
l3 = node_factory.get_node()
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
{'log-level': 'io',
'feerates': (7500, 7500, 7500, 7500),
'disconnect': ['0WIRE_UPDATE_ADD_HTLC']},
{}],
wait_for_announce=True)
l1.fund_channel(l2, 10**6)
chanid2 = l2.fund_channel(l3, 10**6)
# Make sure channels get announced.
bitcoind.generate_block(5)
chanid2 = l2.get_channel_scid(l3)
# Make sure we have 30 seconds without any incoming traffic from l3 to l2
# so it tries to ping before sending WIRE_COMMITMENT_SIGNED.
@ -2247,8 +2235,8 @@ def test_sendcustommsg(node_factory):
"""
plugin = os.path.join(os.path.dirname(__file__), "plugins", "custommsg.py")
opts = {'log-level': 'io', 'plugin': plugin}
l1, l2, l3 = node_factory.line_graph(3, opts=opts)
l4 = node_factory.get_node(options=opts)
l1, l2, l3, l4 = node_factory.get_nodes(4, opts=opts)
node_factory.join_nodes([l1, l2, l3])
l2.connect(l4)
l3.stop()
msg = r'ff' * 32

78
tests/test_pay.py

@ -142,9 +142,12 @@ def test_pay_exclude_node(node_factory, bitcoind):
opts = [
{'disable-mpp': None},
{'plugin': os.path.join(os.getcwd(), 'tests/plugins/fail_htlcs.py')},
{},
{'fee-base': 100, 'fee-per-satoshi': 1000},
{}
]
l1, l2, l3 = node_factory.line_graph(3, opts=opts, wait_for_announce=True)
l1, l2, l3, l4, l5 = node_factory.get_nodes(5, opts=opts)
node_factory.join_nodes([l1, l2, l3], wait_for_announce=True)
amount = 10**8
inv = l3.rpc.invoice(amount, "test1", 'description')['bolt11']
@ -169,8 +172,6 @@ def test_pay_exclude_node(node_factory, bitcoind):
# l1->l4->l5->l3 is the longer route. This makes sure this route won't be
# tried for the first pay attempt. Just to be sure we also raise the fees
# that l4 leverages.
l4 = node_factory.get_node(options={'fee-base': 100, 'fee-per-satoshi': 1000})
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)
@ -1072,9 +1073,9 @@ def test_forward_different_fees_and_cltv(node_factory, bitcoind):
# 1. D: 400 base + 4000 millionths
# We don't do D yet.
l1 = node_factory.get_node(options={'cltv-delta': 10, 'fee-base': 100, 'fee-per-satoshi': 1000})
l2 = node_factory.get_node(options={'cltv-delta': 20, 'fee-base': 200, 'fee-per-satoshi': 2000})
l3 = node_factory.get_node(options={'cltv-delta': 30, 'cltv-final': 9, 'fee-base': 300, 'fee-per-satoshi': 3000})
l1, l2, l3 = node_factory.get_nodes(3, opts=[{'cltv-delta': 10, 'fee-base': 100, 'fee-per-satoshi': 1000},
{'cltv-delta': 20, 'fee-base': 200, 'fee-per-satoshi': 2000},
{'cltv-delta': 30, 'cltv-final': 9, 'fee-base': 300, 'fee-per-satoshi': 3000}])
ret = l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
assert ret['id'] == l2.info['id']
@ -1178,9 +1179,9 @@ def test_forward_different_fees_and_cltv(node_factory, bitcoind):
def test_forward_pad_fees_and_cltv(node_factory, bitcoind):
"""Test that we are allowed extra locktime delta, and fees"""
l1 = node_factory.get_node(options={'cltv-delta': 10, 'fee-base': 100, 'fee-per-satoshi': 1000})
l2 = node_factory.get_node(options={'cltv-delta': 20, 'fee-base': 200, 'fee-per-satoshi': 2000})
l3 = node_factory.get_node(options={'cltv-delta': 30, 'cltv-final': 9, 'fee-base': 300, 'fee-per-satoshi': 3000})
l1, l2, l3 = node_factory.get_nodes(3, opts=[{'cltv-delta': 10, 'fee-base': 100, 'fee-per-satoshi': 1000},
{'cltv-delta': 20, 'fee-base': 200, 'fee-per-satoshi': 2000},
{'cltv-delta': 30, 'cltv-final': 9, 'fee-base': 300, 'fee-per-satoshi': 3000}])
ret = l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
assert ret['id'] == l2.info['id']
@ -1236,9 +1237,8 @@ def test_forward_stats(node_factory, bitcoind):
"""
amount = 10**5
l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=False)
l4 = node_factory.get_node()
l5 = node_factory.get_node(may_fail=True)
l1, l2, l3, l4, l5 = node_factory.get_nodes(5, opts=[{}] * 4 + [{'may_fail': True}])
node_factory.join_nodes([l1, l2, l3], wait_for_announce=False)
l2.openchannel(l4, 10**6, wait_for_announce=False)
l2.openchannel(l5, 10**6, wait_for_announce=True)
@ -1347,12 +1347,12 @@ def test_forward_local_failed_stats(node_factory, bitcoind, executor):
disconnects = ['-WIRE_UPDATE_FAIL_HTLC', 'permfail']
l1 = node_factory.get_node()
l2 = node_factory.get_node()
l3 = node_factory.get_node()
l4 = node_factory.get_node(disconnect=disconnects)
l5 = node_factory.get_node()
l6 = node_factory.get_node()
l1, l2, l3, l4, l5, l6 = node_factory.get_nodes(6, opts=[{},
{},
{},
{'disconnect': disconnects},
{},
{}])
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
@ -1813,12 +1813,10 @@ def test_setchannelfee_usage(node_factory, bitcoind):
DEF_BASE = 10
DEF_PPM = 100
l1 = node_factory.get_node(options={'fee-base': DEF_BASE, 'fee-per-satoshi': DEF_PPM})
l2 = node_factory.get_node(options={'fee-base': DEF_BASE, 'fee-per-satoshi': DEF_PPM})
l3 = node_factory.get_node(options={'fee-base': DEF_BASE, 'fee-per-satoshi': DEF_PPM})
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1, l2, l3 = node_factory.get_nodes(3,
opts={'fee-base': DEF_BASE, 'fee-per-satoshi': DEF_PPM})
node_factory.join_nodes([l1, l2])
l1.rpc.connect(l3.info['id'], 'localhost', l3.port)
l1.fund_channel(l2, 1000000)
def channel_get_fees(scid):
return l1.db.query(
@ -1933,9 +1931,7 @@ def test_setchannelfee_state(node_factory, bitcoind):
DEF_BASE = 0
DEF_PPM = 0
l0 = node_factory.get_node(options={'fee-base': DEF_BASE, 'fee-per-satoshi': DEF_PPM})
l1 = node_factory.get_node(options={'fee-base': DEF_BASE, 'fee-per-satoshi': DEF_PPM})
l2 = node_factory.get_node(options={'fee-base': DEF_BASE, 'fee-per-satoshi': DEF_PPM})
l0, l1, l2 = node_factory.get_nodes(3, opts={'fee-base': DEF_BASE, 'fee-per-satoshi': DEF_PPM})
# connection and funding
l0.rpc.connect(l1.info['id'], 'localhost', l1.port)
@ -2132,9 +2128,7 @@ def test_setchannelfee_all(node_factory, bitcoind):
DEF_BASE = 10
DEF_PPM = 100
l1 = node_factory.get_node(options={'fee-base': DEF_BASE, 'fee-per-satoshi': DEF_PPM})
l2 = node_factory.get_node(options={'fee-base': DEF_BASE, 'fee-per-satoshi': DEF_PPM})
l3 = node_factory.get_node(options={'fee-base': DEF_BASE, 'fee-per-satoshi': DEF_PPM})
l1, l2, l3 = node_factory.get_nodes(3, opts={'fee-base': DEF_BASE, 'fee-per-satoshi': DEF_PPM})
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.rpc.connect(l3.info['id'], 'localhost', l3.port)
l1.fund_channel(l2, 1000000)
@ -2351,16 +2345,11 @@ def test_error_returns_blockheight(node_factory, bitcoind):
@unittest.skipIf(not DEVELOPER, 'Needs dev-routes')
def test_tlv_or_legacy(node_factory, bitcoind):
l1, l2, l3 = node_factory.get_nodes(3,
l1, l2, l3 = node_factory.line_graph(3,
opts={'plugin': os.path.join(os.getcwd(), 'tests/plugins/print_htlc_onion.py')})
# Set up a channel from 1->2 first.
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
scid12 = l1.fund_channel(l2, 1000000)
# Now set up 2->3.
l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
scid23 = l2.fund_channel(l3, 1000000)
scid12 = l1.get_channel_scid(l2)
scid23 = l2.get_channel_scid(l3)
# We need to force l3 to provide route hint from l2 (it won't normally,
# since it sees l2 as a dead end).
@ -2378,8 +2367,8 @@ def test_tlv_or_legacy(node_factory, bitcoind):
l2.daemon.wait_for_log("Got onion.*'type': 'legacy'")
l3.daemon.wait_for_log("Got onion.*'type': 'tlv'")
# Turns out we only need 3 more blocks to announce l1->l2 channel.
bitcoind.generate_block(3)
# We need 5 more blocks to announce l1->l2 channel.
bitcoind.generate_block(5)
# Make sure l1 knows about l2
wait_for(lambda: 'alias' in l1.rpc.listnodes(l2.info['id'])['nodes'][0])
@ -3031,7 +3020,7 @@ def test_pay_exemptfee(node_factory, compat):
@unittest.skipIf(not DEVELOPER, "Requires use_shadow flag")
def test_pay_peer(node_factory):
def test_pay_peer(node_factory, bitcoind):
"""If we have a direct channel to the destination we should use that.
This is complicated a bit by not having sufficient capacity, but the
@ -3042,11 +3031,10 @@ def test_pay_peer(node_factory):
v /
l3
"""
l1, l2 = node_factory.line_graph(2, fundamount=10**6)
l3 = node_factory.get_node()
l1.openchannel(l3, 10**6, wait_for_announce=False)
l3.openchannel(l2, 10**6, wait_for_announce=True)
l1, l2, l3 = node_factory.get_nodes(3)
node_factory.join_nodes([l1, l2])
node_factory.join_nodes([l1, l3])
node_factory.join_nodes([l3, l2], wait_for_announce=True)
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 6)

11
tests/test_plugin.py

@ -789,13 +789,14 @@ def test_forward_event_notification(node_factory, bitcoind, executor):
amount = 10**8
disconnects = ['-WIRE_UPDATE_FAIL_HTLC', 'permfail']
l1, l2, l3 = node_factory.line_graph(3, opts=[
l1, l2, l3, l4, l5 = node_factory.get_nodes(5, opts=[
{},
{'plugin': os.path.join(os.getcwd(), 'tests/plugins/forward_payment_status.py')},
{}
], wait_for_announce=True)
l4 = node_factory.get_node()
l5 = node_factory.get_node(disconnect=disconnects)
{},
{},
{'disconnect': disconnects}])
node_factory.join_nodes([l1, l2, l3], wait_for_announce=True)
l2.openchannel(l4, 10**6, wait_for_announce=False)
l2.openchannel(l5, 10**6, wait_for_announce=True)

Loading…
Cancel
Save