pytest: protect against bad gossip messages from mining confirms too fast.
If we fund a channel between two nodes, then mine all the blocks to announce it, any other nodes may see the announcement before the blocks, causing CI to complain about "bad gossip": ``` lightningd-4: 2022-01-25T22:33:25.468Z DEBUG 032cf15d1ad9c4a08d26eab1918f732d8ef8fdc6abb9640bf3db174372c491304e-gossipd: Ignoring future channel_announcment for 113x1x1 (current block 112) lightningd-4: 2022-01-25T22:33:25.468Z DEBUG 032cf15d1ad9c4a08d26eab1918f732d8ef8fdc6abb9640bf3db174372c491304e-gossipd: Bad gossip order: WIRE_CHANNEL_UPDATE before announcement 113x1x1/0 lightningd-4: 2022-01-25T22:33:25.468Z DEBUG 032cf15d1ad9c4a08d26eab1918f732d8ef8fdc6abb9640bf3db174372c491304e-gossipd: Bad gossip order: WIRE_CHANNEL_UPDATE before announcement 113x1x1/1 lightningd-4: 2022-01-25T22:33:25.468Z DEBUG 032cf15d1ad9c4a08d26eab1918f732d8ef8fdc6abb9640bf3db174372c491304e-gossipd: Bad gossip order: WIRE_NODE_ANNOUNCEMENT before announcement 032cf15d1ad9c4a08d26eab1918f732d8ef8fdc6abb9640bf3db174372c491304e ``` Add a new helper for this case, and use it where there are more than 2 nodes. Cleans up test_routing_gossip and a few other places which did this manually. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
6d9f6ffd67
commit
e8d2176e6b
|
@ -118,6 +118,17 @@ def sync_blockheight(bitcoind, nodes):
|
||||||
wait_for(lambda: n.rpc.getinfo()['blockheight'] == height)
|
wait_for(lambda: n.rpc.getinfo()['blockheight'] == height)
|
||||||
|
|
||||||
|
|
||||||
|
def mine_funding_to_announce(bitcoind, nodes, num_blocks=5, wait_for_mempool=0):
|
||||||
|
"""Mine blocks so a channel can be announced (5, if it's already
|
||||||
|
mined), but make sure we don't leave nodes behind who will reject the
|
||||||
|
announcement. Not needed if there are only two nodes.
|
||||||
|
|
||||||
|
"""
|
||||||
|
bitcoind.generate_block(num_blocks - 1, wait_for_mempool)
|
||||||
|
sync_blockheight(bitcoind, nodes)
|
||||||
|
bitcoind.generate_block(1)
|
||||||
|
|
||||||
|
|
||||||
def wait_channel_quiescent(n1, n2):
|
def wait_channel_quiescent(n1, n2):
|
||||||
wait_for(lambda: only_one(only_one(n1.rpc.listpeers(n2.info['id'])['peers'])['channels'])['htlcs'] == [])
|
wait_for(lambda: only_one(only_one(n1.rpc.listpeers(n2.info['id'])['peers'])['channels'])['htlcs'] == [])
|
||||||
wait_for(lambda: only_one(only_one(n2.rpc.listpeers(n1.info['id'])['peers'])['channels'])['htlcs'] == [])
|
wait_for(lambda: only_one(only_one(n2.rpc.listpeers(n1.info['id'])['peers'])['channels'])['htlcs'] == [])
|
||||||
|
|
|
@ -8,7 +8,7 @@ from utils import (
|
||||||
account_balance, first_channel_id, closing_fee, TEST_NETWORK,
|
account_balance, first_channel_id, closing_fee, TEST_NETWORK,
|
||||||
scriptpubkey_addr, calc_lease_fee, EXPERIMENTAL_FEATURES,
|
scriptpubkey_addr, calc_lease_fee, EXPERIMENTAL_FEATURES,
|
||||||
check_utxos_channel, anchor_expected, check_coin_moves,
|
check_utxos_channel, anchor_expected, check_coin_moves,
|
||||||
check_balance_snaps
|
check_balance_snaps, mine_funding_to_announce
|
||||||
)
|
)
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
@ -281,7 +281,7 @@ def test_closing_different_fees(node_factory, bitcoind, executor):
|
||||||
# Technically, this is async to fundchannel returning.
|
# Technically, this is async to fundchannel returning.
|
||||||
l1.daemon.wait_for_log('sendrawtx exit 0')
|
l1.daemon.wait_for_log('sendrawtx exit 0')
|
||||||
|
|
||||||
bitcoind.generate_block(6)
|
mine_funding_to_announce(bitcoind, peers, num_blocks=6)
|
||||||
|
|
||||||
# Now wait for them all to hit normal state, do payments
|
# Now wait for them all to hit normal state, do payments
|
||||||
l1.daemon.wait_for_logs(['update for channel .* now ACTIVE'] * num_peers
|
l1.daemon.wait_for_logs(['update for channel .* now ACTIVE'] * num_peers
|
||||||
|
@ -349,7 +349,8 @@ def test_closing_specified_destination(node_factory, bitcoind, chainparams):
|
||||||
l1.pay(l3, 100000000)
|
l1.pay(l3, 100000000)
|
||||||
l1.pay(l4, 100000000)
|
l1.pay(l4, 100000000)
|
||||||
|
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4])
|
||||||
|
|
||||||
addr = chainparams['example_addr']
|
addr = chainparams['example_addr']
|
||||||
l1.rpc.close(chan12, None, addr)
|
l1.rpc.close(chan12, None, addr)
|
||||||
l1.rpc.call('close', {'id': chan13, 'destination': addr})
|
l1.rpc.call('close', {'id': chan13, 'destination': addr})
|
||||||
|
@ -2160,7 +2161,7 @@ def test_onchain_middleman_simple(node_factory, bitcoind):
|
||||||
channel_id = first_channel_id(l1, l2)
|
channel_id = first_channel_id(l1, l2)
|
||||||
|
|
||||||
# Make sure routes finalized.
|
# Make sure routes finalized.
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3])
|
||||||
l1.wait_channel_active(c23)
|
l1.wait_channel_active(c23)
|
||||||
|
|
||||||
# Give l1 some money to play with.
|
# Give l1 some money to play with.
|
||||||
|
@ -2280,7 +2281,7 @@ def test_onchain_middleman_their_unilateral_in(node_factory, bitcoind):
|
||||||
channel_id = first_channel_id(l1, l2)
|
channel_id = first_channel_id(l1, l2)
|
||||||
|
|
||||||
# Make sure routes finalized.
|
# Make sure routes finalized.
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3])
|
||||||
l1.wait_channel_active(c23)
|
l1.wait_channel_active(c23)
|
||||||
|
|
||||||
# Make sure l3 sees gossip for channel now; it can get upset
|
# Make sure l3 sees gossip for channel now; it can get upset
|
||||||
|
|
|
@ -11,7 +11,7 @@ from utils import (
|
||||||
expected_channel_features,
|
expected_channel_features,
|
||||||
check_coin_moves, first_channel_id, account_balance, basic_fee,
|
check_coin_moves, first_channel_id, account_balance, basic_fee,
|
||||||
scriptpubkey_addr,
|
scriptpubkey_addr,
|
||||||
EXPERIMENTAL_FEATURES
|
EXPERIMENTAL_FEATURES, mine_funding_to_announce
|
||||||
)
|
)
|
||||||
from pyln.testing.utils import SLOW_MACHINE, VALGRIND, EXPERIMENTAL_DUAL_FUND, FUNDAMOUNT
|
from pyln.testing.utils import SLOW_MACHINE, VALGRIND, EXPERIMENTAL_DUAL_FUND, FUNDAMOUNT
|
||||||
|
|
||||||
|
@ -2556,7 +2556,7 @@ def test_disconnectpeer(node_factory, bitcoind):
|
||||||
|
|
||||||
# Fund channel l1 -> l3
|
# Fund channel l1 -> l3
|
||||||
l1.fundchannel(l3, 10**6)
|
l1.fundchannel(l3, 10**6)
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3])
|
||||||
|
|
||||||
# disconnecting a non gossiping peer results in error
|
# disconnecting a non gossiping peer results in error
|
||||||
with pytest.raises(RpcError, match=r'Peer is in state CHANNELD_NORMAL'):
|
with pytest.raises(RpcError, match=r'Peer is in state CHANNELD_NORMAL'):
|
||||||
|
@ -2945,11 +2945,9 @@ def test_restart_many_payments(node_factory, bitcoind):
|
||||||
# OK to use change from previous fundings
|
# OK to use change from previous fundings
|
||||||
l1.rpc.fundchannel(n.info['id'], 10**6, minconf=0)
|
l1.rpc.fundchannel(n.info['id'], 10**6, minconf=0)
|
||||||
|
|
||||||
# Now mine them, get scids; make sure they all see the first block
|
# Now mine them, get scids
|
||||||
# otherwise they may complain about channel_announcement from the future.
|
mine_funding_to_announce(bitcoind, [l1] + nodes,
|
||||||
bitcoind.generate_block(1, wait_for_mempool=num * 2)
|
num_blocks=6, wait_for_mempool=num * 2)
|
||||||
sync_blockheight(bitcoind, [l1] + nodes)
|
|
||||||
bitcoind.generate_block(5)
|
|
||||||
|
|
||||||
wait_for(lambda: [only_one(n.rpc.listpeers()['peers'])['channels'][0]['state'] for n in nodes] == ['CHANNELD_NORMAL'] * len(nodes))
|
wait_for(lambda: [only_one(n.rpc.listpeers()['peers'])['channels'][0]['state'] for n in nodes] == ['CHANNELD_NORMAL'] * len(nodes))
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@ from fixtures import TEST_NETWORK
|
||||||
from pyln.client import RpcError, Millisatoshi
|
from pyln.client import RpcError, Millisatoshi
|
||||||
from utils import (
|
from utils import (
|
||||||
DEVELOPER, wait_for, TIMEOUT, only_one, sync_blockheight,
|
DEVELOPER, wait_for, TIMEOUT, only_one, sync_blockheight,
|
||||||
expected_node_features, COMPAT, EXPERIMENTAL_FEATURES
|
expected_node_features, COMPAT, EXPERIMENTAL_FEATURES,
|
||||||
|
mine_funding_to_announce
|
||||||
)
|
)
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
@ -37,7 +38,7 @@ def test_gossip_pruning(node_factory, bitcoind):
|
||||||
scid1, _ = l1.fundchannel(l2, 10**6)
|
scid1, _ = l1.fundchannel(l2, 10**6)
|
||||||
scid2, _ = l2.fundchannel(l3, 10**6)
|
scid2, _ = l2.fundchannel(l3, 10**6)
|
||||||
|
|
||||||
bitcoind.generate_block(6)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3])
|
||||||
|
|
||||||
# Channels should be activated locally
|
# Channels should be activated locally
|
||||||
wait_for(lambda: [c['active'] for c in l1.rpc.listchannels()['channels']] == [True] * 4)
|
wait_for(lambda: [c['active'] for c in l1.rpc.listchannels()['channels']] == [True] * 4)
|
||||||
|
@ -201,7 +202,7 @@ def test_announce_and_connect_via_dns(node_factory, bitcoind):
|
||||||
l3.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
l3.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
||||||
l4.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
l4.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
||||||
scid, _ = l1.fundchannel(l2, 10**6)
|
scid, _ = l1.fundchannel(l2, 10**6)
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3])
|
||||||
|
|
||||||
# wait until l3 and l4 see l1 via gossip with announced addresses
|
# wait until l3 and l4 see l1 via gossip with announced addresses
|
||||||
wait_for(lambda: len(l3.rpc.listnodes(l1.info['id'])['nodes']) == 1)
|
wait_for(lambda: len(l3.rpc.listnodes(l1.info['id'])['nodes']) == 1)
|
||||||
|
@ -252,7 +253,7 @@ def test_gossip_timestamp_filter(node_factory, bitcoind, chainparams):
|
||||||
|
|
||||||
# Make a public channel.
|
# Make a public channel.
|
||||||
chan12, _ = l1.fundchannel(l2, 10**5)
|
chan12, _ = l1.fundchannel(l2, 10**5)
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4])
|
||||||
|
|
||||||
l3.wait_for_channel_updates([chan12])
|
l3.wait_for_channel_updates([chan12])
|
||||||
after_12 = int(time.time())
|
after_12 = int(time.time())
|
||||||
|
@ -334,7 +335,7 @@ def test_connect_by_gossip(node_factory, bitcoind):
|
||||||
|
|
||||||
# Nodes are gossiped only if they have channels
|
# Nodes are gossiped only if they have channels
|
||||||
chanid, _ = l2.fundchannel(l3, 10**6)
|
chanid, _ = l2.fundchannel(l3, 10**6)
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3])
|
||||||
|
|
||||||
# Let channel reach announcement depth
|
# Let channel reach announcement depth
|
||||||
l2.wait_channel_active(chanid)
|
l2.wait_channel_active(chanid)
|
||||||
|
@ -442,7 +443,7 @@ def test_gossip_jsonrpc(node_factory):
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.developer("Too slow without --dev-fast-gossip")
|
@pytest.mark.developer("Too slow without --dev-fast-gossip")
|
||||||
def test_gossip_badsig(node_factory):
|
def test_gossip_badsig(node_factory, bitcoind):
|
||||||
"""Make sure node announcement signatures are ok.
|
"""Make sure node announcement signatures are ok.
|
||||||
|
|
||||||
This is a smoke test to see if signatures fail. This used to be the case
|
This is a smoke test to see if signatures fail. This used to be the case
|
||||||
|
@ -460,7 +461,7 @@ def test_gossip_badsig(node_factory):
|
||||||
l2.fundchannel(l3, 10**6)
|
l2.fundchannel(l3, 10**6)
|
||||||
|
|
||||||
# Wait for route propagation.
|
# Wait for route propagation.
|
||||||
l1.bitcoin.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3])
|
||||||
l1.daemon.wait_for_log('Received node_announcement for node {}'
|
l1.daemon.wait_for_log('Received node_announcement for node {}'
|
||||||
.format(l3.info['id']))
|
.format(l3.info['id']))
|
||||||
assert not l1.daemon.is_in_log('signature verification failed')
|
assert not l1.daemon.is_in_log('signature verification failed')
|
||||||
|
@ -517,7 +518,7 @@ def test_gossip_persistence(node_factory, bitcoind):
|
||||||
scid23, _ = l2.fundchannel(l3, 10**6)
|
scid23, _ = l2.fundchannel(l3, 10**6)
|
||||||
|
|
||||||
# Make channels public, except for l3 -> l4, which is kept local-only for now
|
# Make channels public, except for l3 -> l4, which is kept local-only for now
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4])
|
||||||
scid34, _ = l3.fundchannel(l4, 10**6)
|
scid34, _ = l3.fundchannel(l4, 10**6)
|
||||||
bitcoind.generate_block(1)
|
bitcoind.generate_block(1)
|
||||||
|
|
||||||
|
@ -610,7 +611,7 @@ def test_gossip_no_empty_announcements(node_factory, bitcoind, chainparams):
|
||||||
fundchannel=False)
|
fundchannel=False)
|
||||||
|
|
||||||
l3.fundchannel(l4, 10**5)
|
l3.fundchannel(l4, 10**5)
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4])
|
||||||
|
|
||||||
# l2 sends CHANNEL_ANNOUNCEMENT to l1, then disconnects/
|
# l2 sends CHANNEL_ANNOUNCEMENT to l1, then disconnects/
|
||||||
l2.daemon.wait_for_log('dev_disconnect')
|
l2.daemon.wait_for_log('dev_disconnect')
|
||||||
|
@ -644,20 +645,16 @@ def test_gossip_no_empty_announcements(node_factory, bitcoind, chainparams):
|
||||||
def test_routing_gossip(node_factory, bitcoind):
|
def test_routing_gossip(node_factory, bitcoind):
|
||||||
nodes = node_factory.get_nodes(5)
|
nodes = node_factory.get_nodes(5)
|
||||||
|
|
||||||
sync_blockheight(bitcoind, nodes)
|
|
||||||
for i in range(len(nodes) - 1):
|
for i in range(len(nodes) - 1):
|
||||||
src, dst = nodes[i], nodes[i + 1]
|
src, dst = nodes[i], nodes[i + 1]
|
||||||
src.rpc.connect(dst.info['id'], 'localhost', dst.port)
|
src.rpc.connect(dst.info['id'], 'localhost', dst.port)
|
||||||
src.openchannel(dst, 25000, confirm=False, wait_for_announce=False)
|
src.openchannel(dst, 25000, confirm=False, wait_for_announce=False)
|
||||||
sync_blockheight(bitcoind, nodes)
|
|
||||||
|
|
||||||
# Avoid "bad gossip" caused by future announcements (a node below
|
# openchannel calls fundwallet which mines a block; so first channel
|
||||||
# confirmation height receiving and ignoring the announcement,
|
# is 4 deep, last is unconfirmed.
|
||||||
# thus marking followup messages as bad).
|
|
||||||
sync_blockheight(bitcoind, nodes)
|
|
||||||
|
|
||||||
# Allow announce messages.
|
# Allow announce messages.
|
||||||
bitcoind.generate_block(6)
|
mine_funding_to_announce(bitcoind, nodes, num_blocks=6, wait_for_mempool=1)
|
||||||
|
|
||||||
# Deep check that all channels are in there
|
# Deep check that all channels are in there
|
||||||
comb = []
|
comb = []
|
||||||
|
@ -691,17 +688,15 @@ def test_gossip_query_channel_range(node_factory, bitcoind, chainparams):
|
||||||
l2.fundwallet(10**6)
|
l2.fundwallet(10**6)
|
||||||
|
|
||||||
num_tx = len(bitcoind.rpc.getrawmempool())
|
num_tx = len(bitcoind.rpc.getrawmempool())
|
||||||
|
# We want these one block apart.
|
||||||
l1.rpc.fundchannel(l2.info['id'], 10**5)['tx']
|
l1.rpc.fundchannel(l2.info['id'], 10**5)['tx']
|
||||||
wait_for(lambda: len(bitcoind.rpc.getrawmempool()) == num_tx + 1)
|
bitcoind.generate_block(wait_for_mempool=num_tx + 1)
|
||||||
bitcoind.generate_block(1)
|
sync_blockheight(bitcoind, [l1, l2, l3, l4])
|
||||||
|
|
||||||
num_tx = len(bitcoind.rpc.getrawmempool())
|
|
||||||
l2.rpc.fundchannel(l3.info['id'], 10**5)['tx']
|
l2.rpc.fundchannel(l3.info['id'], 10**5)['tx']
|
||||||
wait_for(lambda: len(bitcoind.rpc.getrawmempool()) == num_tx + 1)
|
|
||||||
bitcoind.generate_block(1)
|
|
||||||
|
|
||||||
# Get them both to gossip depth.
|
# Get them both to gossip depth.
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4],
|
||||||
|
num_blocks=6,
|
||||||
|
wait_for_mempool=1)
|
||||||
|
|
||||||
# Make sure l2 has received all the gossip.
|
# Make sure l2 has received all the gossip.
|
||||||
l2.daemon.wait_for_logs(['Received node_announcement for node ' + l1.info['id'],
|
l2.daemon.wait_for_logs(['Received node_announcement for node ' + l1.info['id'],
|
||||||
|
@ -874,7 +869,7 @@ def test_gossip_query_channel_range(node_factory, bitcoind, chainparams):
|
||||||
|
|
||||||
# This should actually be large enough for zlib to kick in!
|
# This should actually be large enough for zlib to kick in!
|
||||||
scid34, _ = l3.fundchannel(l4, 10**5)
|
scid34, _ = l3.fundchannel(l4, 10**5)
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4])
|
||||||
l2.daemon.wait_for_log('Received node_announcement for node ' + l4.info['id'])
|
l2.daemon.wait_for_log('Received node_announcement for node ' + l4.info['id'])
|
||||||
|
|
||||||
# Restore infinite encode size.
|
# Restore infinite encode size.
|
||||||
|
@ -924,12 +919,6 @@ def test_report_routing_failure(node_factory, bitcoind):
|
||||||
# Finally the only possible path is
|
# Finally the only possible path is
|
||||||
# l1-l2-l3-l4.
|
# l1-l2-l3-l4.
|
||||||
|
|
||||||
def fund_from_to_payer(lsrc, ldst, lpayer):
|
|
||||||
lsrc.rpc.connect(ldst.info['id'], 'localhost', ldst.port)
|
|
||||||
c, _ = lsrc.fundchannel(ldst, 10000000)
|
|
||||||
bitcoind.generate_block(5)
|
|
||||||
lpayer.wait_for_channel_updates([c])
|
|
||||||
|
|
||||||
# Setup
|
# Setup
|
||||||
# Construct lightningd
|
# Construct lightningd
|
||||||
l1, l2, l3, l4 = node_factory.get_nodes(4)
|
l1, l2, l3, l4 = node_factory.get_nodes(4)
|
||||||
|
@ -946,7 +935,7 @@ def test_report_routing_failure(node_factory, bitcoind):
|
||||||
dst.daemon.lightning_dir))
|
dst.daemon.lightning_dir))
|
||||||
c, _ = src.fundchannel(dst, 10**6)
|
c, _ = src.fundchannel(dst, 10**6)
|
||||||
channels.append(c)
|
channels.append(c)
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4])
|
||||||
|
|
||||||
for c in channels:
|
for c in channels:
|
||||||
l1.wait_channel_active(c)
|
l1.wait_channel_active(c)
|
||||||
|
@ -982,7 +971,7 @@ def test_query_short_channel_id(node_factory, bitcoind, chainparams):
|
||||||
# Make channels public.
|
# Make channels public.
|
||||||
scid12, _ = l1.fundchannel(l2, 10**5)
|
scid12, _ = l1.fundchannel(l2, 10**5)
|
||||||
scid23, _ = l2.fundchannel(l3, 10**5)
|
scid23, _ = l2.fundchannel(l3, 10**5)
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3])
|
||||||
|
|
||||||
# It will know about everything.
|
# It will know about everything.
|
||||||
l1.daemon.wait_for_log('Received node_announcement for node {}'.format(l3.info['id']))
|
l1.daemon.wait_for_log('Received node_announcement for node {}'.format(l3.info['id']))
|
||||||
|
@ -1369,7 +1358,7 @@ def test_gossip_notices_close(node_factory, bitcoind):
|
||||||
node_factory.join_nodes([l2, l3])
|
node_factory.join_nodes([l2, l3])
|
||||||
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
||||||
|
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3])
|
||||||
|
|
||||||
# Make sure l1 learns about channel and nodes.
|
# Make sure l1 learns about channel and nodes.
|
||||||
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 2)
|
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 2)
|
||||||
|
@ -1468,7 +1457,7 @@ def test_getroute_exclude(node_factory, bitcoind):
|
||||||
# Now, create an alternate (better) route.
|
# Now, create an alternate (better) route.
|
||||||
l2.rpc.connect(l4.info['id'], 'localhost', l4.port)
|
l2.rpc.connect(l4.info['id'], 'localhost', l4.port)
|
||||||
scid, _ = l2.fundchannel(l4, 1000000, wait_for_active=False)
|
scid, _ = l2.fundchannel(l4, 1000000, wait_for_active=False)
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4, l5])
|
||||||
|
|
||||||
# We don't wait above, because we care about it hitting l1.
|
# We don't wait above, because we care about it hitting l1.
|
||||||
l1.daemon.wait_for_logs([r'update for channel {}/0 now ACTIVE'
|
l1.daemon.wait_for_logs([r'update for channel {}/0 now ACTIVE'
|
||||||
|
@ -1505,7 +1494,7 @@ def test_getroute_exclude(node_factory, bitcoind):
|
||||||
scid15, _ = l1.fundchannel(l5, 1000000, wait_for_active=False)
|
scid15, _ = l1.fundchannel(l5, 1000000, wait_for_active=False)
|
||||||
l5.rpc.connect(l4.info['id'], 'localhost', l4.port)
|
l5.rpc.connect(l4.info['id'], 'localhost', l4.port)
|
||||||
scid54, _ = l5.fundchannel(l4, 1000000, wait_for_active=False)
|
scid54, _ = l5.fundchannel(l4, 1000000, wait_for_active=False)
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4, l5])
|
||||||
|
|
||||||
# We don't wait above, because we care about it hitting l1.
|
# We don't wait above, because we care about it hitting l1.
|
||||||
l1.daemon.wait_for_logs([r'update for channel {}/0 now ACTIVE'
|
l1.daemon.wait_for_logs([r'update for channel {}/0 now ACTIVE'
|
||||||
|
@ -1589,7 +1578,7 @@ def setup_gossip_store_test(node_factory, bitcoind):
|
||||||
scid23, _ = l2.fundchannel(l3, 10**6)
|
scid23, _ = l2.fundchannel(l3, 10**6)
|
||||||
|
|
||||||
# Have that channel announced.
|
# Have that channel announced.
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3])
|
||||||
# Make sure we've got node_announcements
|
# Make sure we've got node_announcements
|
||||||
wait_for(lambda: ['alias' in n for n in l2.rpc.listnodes()['nodes']] == [True, True])
|
wait_for(lambda: ['alias' in n for n in l2.rpc.listnodes()['nodes']] == [True, True])
|
||||||
|
|
||||||
|
@ -2115,7 +2104,7 @@ def test_topology_leak(node_factory, bitcoind):
|
||||||
l1, l2, l3 = node_factory.line_graph(3)
|
l1, l2, l3 = node_factory.line_graph(3)
|
||||||
|
|
||||||
l1.rpc.listchannels()
|
l1.rpc.listchannels()
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3])
|
||||||
|
|
||||||
# Wait until l1 sees all the channels.
|
# Wait until l1 sees all the channels.
|
||||||
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 4)
|
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 4)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from fixtures import * # noqa: F401,F403
|
from fixtures import * # noqa: F401,F403
|
||||||
from fixtures import TEST_NETWORK
|
from fixtures import TEST_NETWORK
|
||||||
from pyln.client import RpcError, Millisatoshi
|
from pyln.client import RpcError, Millisatoshi
|
||||||
from utils import only_one, wait_for, wait_channel_quiescent
|
from utils import only_one, wait_for, wait_channel_quiescent, mine_funding_to_announce
|
||||||
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -221,7 +221,7 @@ def test_invoice_routeboost_private(node_factory, bitcoind):
|
||||||
l0 = node_factory.get_node()
|
l0 = node_factory.get_node()
|
||||||
l0.rpc.connect(l1.info['id'], 'localhost', l1.port)
|
l0.rpc.connect(l1.info['id'], 'localhost', l1.port)
|
||||||
scid_dummy, _ = l0.fundchannel(l1, 2 * (10**5))
|
scid_dummy, _ = l0.fundchannel(l1, 2 * (10**5))
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l0, l1, l2, l3])
|
||||||
|
|
||||||
# Make sure channel is totally public.
|
# Make sure channel is totally public.
|
||||||
wait_for(lambda: [c['public'] for c in l2.rpc.listchannels(scid_dummy)['channels']] == [True, True])
|
wait_for(lambda: [c['public'] for c in l2.rpc.listchannels(scid_dummy)['channels']] == [True, True])
|
||||||
|
@ -285,7 +285,7 @@ def test_invoice_routeboost_private(node_factory, bitcoind):
|
||||||
# the exposure of private channels.
|
# the exposure of private channels.
|
||||||
l3.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
l3.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
||||||
scid2, _ = l3.fundchannel(l2, (10**5))
|
scid2, _ = l3.fundchannel(l2, (10**5))
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l0, l1, l2, l3])
|
||||||
|
|
||||||
# Make sure channel is totally public.
|
# Make sure channel is totally public.
|
||||||
wait_for(lambda: [c['public'] for c in l2.rpc.listchannels(scid2)['channels']] == [True, True])
|
wait_for(lambda: [c['public'] for c in l2.rpc.listchannels(scid2)['channels']] == [True, True])
|
||||||
|
|
|
@ -7,7 +7,7 @@ from pyln.client import RpcError
|
||||||
from threading import Event
|
from threading import Event
|
||||||
from pyln.testing.utils import (
|
from pyln.testing.utils import (
|
||||||
DEVELOPER, TIMEOUT, VALGRIND, DEPRECATED_APIS, sync_blockheight, only_one,
|
DEVELOPER, TIMEOUT, VALGRIND, DEPRECATED_APIS, sync_blockheight, only_one,
|
||||||
wait_for, TailableProc, env
|
wait_for, TailableProc, env, mine_funding_to_announce
|
||||||
)
|
)
|
||||||
from utils import (
|
from utils import (
|
||||||
account_balance, scriptpubkey_addr, check_coin_moves
|
account_balance, scriptpubkey_addr, check_coin_moves
|
||||||
|
@ -2291,7 +2291,7 @@ def test_listforwards(node_factory, bitcoind):
|
||||||
c24, _ = l2.fundchannel(l4, 10**5)
|
c24, _ = l2.fundchannel(l4, 10**5)
|
||||||
|
|
||||||
# Wait until channels are active
|
# Wait until channels are active
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4])
|
||||||
l1.wait_channel_active(c23)
|
l1.wait_channel_active(c23)
|
||||||
|
|
||||||
# successful payments
|
# successful payments
|
||||||
|
|
|
@ -8,7 +8,7 @@ from pyln.proto.onion import TlvPayload
|
||||||
from pyln.testing.utils import EXPERIMENTAL_DUAL_FUND, FUNDAMOUNT
|
from pyln.testing.utils import EXPERIMENTAL_DUAL_FUND, FUNDAMOUNT
|
||||||
from utils import (
|
from utils import (
|
||||||
DEVELOPER, wait_for, only_one, sync_blockheight, TIMEOUT,
|
DEVELOPER, wait_for, only_one, sync_blockheight, TIMEOUT,
|
||||||
EXPERIMENTAL_FEATURES, env, VALGRIND
|
EXPERIMENTAL_FEATURES, env, VALGRIND, mine_funding_to_announce
|
||||||
)
|
)
|
||||||
import copy
|
import copy
|
||||||
import os
|
import os
|
||||||
|
@ -182,7 +182,7 @@ def test_pay_exclude_node(node_factory, bitcoind):
|
||||||
scid14, _ = l1.fundchannel(l4, 10**6, wait_for_active=False)
|
scid14, _ = l1.fundchannel(l4, 10**6, wait_for_active=False)
|
||||||
scid45, _ = l4.fundchannel(l5, 10**6, wait_for_active=False)
|
scid45, _ = l4.fundchannel(l5, 10**6, wait_for_active=False)
|
||||||
scid53, _ = l5.fundchannel(l3, 10**6, wait_for_active=False)
|
scid53, _ = l5.fundchannel(l3, 10**6, wait_for_active=False)
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4, l5])
|
||||||
|
|
||||||
l1.daemon.wait_for_logs([r'update for channel {}/0 now ACTIVE'
|
l1.daemon.wait_for_logs([r'update for channel {}/0 now ACTIVE'
|
||||||
.format(scid14),
|
.format(scid14),
|
||||||
|
@ -1137,7 +1137,7 @@ def test_forward_different_fees_and_cltv(node_factory, bitcoind):
|
||||||
|
|
||||||
c1, _ = l1.fundchannel(l2, 10**6)
|
c1, _ = l1.fundchannel(l2, 10**6)
|
||||||
c2, _ = l2.fundchannel(l3, 10**6)
|
c2, _ = l2.fundchannel(l3, 10**6)
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3])
|
||||||
|
|
||||||
# Make sure l1 has seen announce for all channels.
|
# Make sure l1 has seen announce for all channels.
|
||||||
l1.wait_channel_active(c1)
|
l1.wait_channel_active(c1)
|
||||||
|
@ -1244,7 +1244,7 @@ def test_forward_pad_fees_and_cltv(node_factory, bitcoind):
|
||||||
|
|
||||||
c1, _ = l1.fundchannel(l2, 10**6)
|
c1, _ = l1.fundchannel(l2, 10**6)
|
||||||
c2, _ = l2.fundchannel(l3, 10**6)
|
c2, _ = l2.fundchannel(l3, 10**6)
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3])
|
||||||
|
|
||||||
# Make sure l1 has seen announce for all channels.
|
# Make sure l1 has seen announce for all channels.
|
||||||
l1.wait_channel_active(c1)
|
l1.wait_channel_active(c1)
|
||||||
|
@ -1290,9 +1290,7 @@ def test_forward_stats(node_factory, bitcoind):
|
||||||
l2.openchannel(l4, 10**6, wait_for_announce=False)
|
l2.openchannel(l4, 10**6, wait_for_announce=False)
|
||||||
l2.openchannel(l5, 10**6, wait_for_announce=False)
|
l2.openchannel(l5, 10**6, wait_for_announce=False)
|
||||||
|
|
||||||
bitcoind.generate_block(1)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4, l5])
|
||||||
sync_blockheight(bitcoind, [l1, l2, l3, l4, l5])
|
|
||||||
bitcoind.generate_block(5)
|
|
||||||
|
|
||||||
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 8)
|
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 8)
|
||||||
|
|
||||||
|
@ -1419,7 +1417,7 @@ def test_forward_local_failed_stats(node_factory, bitcoind, executor):
|
||||||
l6.fundchannel(l1, 10**6)
|
l6.fundchannel(l1, 10**6)
|
||||||
|
|
||||||
# Make sure routes finalized.
|
# Make sure routes finalized.
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4, l5, l6])
|
||||||
l1.wait_channel_active(c23)
|
l1.wait_channel_active(c23)
|
||||||
l1.wait_channel_active(c24)
|
l1.wait_channel_active(c24)
|
||||||
l1.wait_channel_active(c25)
|
l1.wait_channel_active(c25)
|
||||||
|
@ -1702,7 +1700,7 @@ def test_pay_retry(node_factory, bitcoind, executor, chainparams):
|
||||||
scid35, _ = l3.fundchannel(l5, 10**6, wait_for_active=False)
|
scid35, _ = l3.fundchannel(l5, 10**6, wait_for_active=False)
|
||||||
|
|
||||||
# Make sure l1 sees all 7 channels
|
# Make sure l1 sees all 7 channels
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4, l5])
|
||||||
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 14)
|
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 14)
|
||||||
|
|
||||||
# Exhaust shortcut channels one at a time, to force retries.
|
# Exhaust shortcut channels one at a time, to force retries.
|
||||||
|
@ -1763,7 +1761,7 @@ def test_pay_routeboost(node_factory, bitcoind, compat):
|
||||||
scidl2l3, _ = l2.fundchannel(l3, 10**6)
|
scidl2l3, _ = l2.fundchannel(l3, 10**6)
|
||||||
|
|
||||||
# Make sure l1 knows about the 2->3 channel.
|
# Make sure l1 knows about the 2->3 channel.
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4, l5])
|
||||||
l1.daemon.wait_for_logs([r'update for channel {}/0 now ACTIVE'
|
l1.daemon.wait_for_logs([r'update for channel {}/0 now ACTIVE'
|
||||||
.format(scidl2l3),
|
.format(scidl2l3),
|
||||||
r'update for channel {}/1 now ACTIVE'
|
r'update for channel {}/1 now ACTIVE'
|
||||||
|
@ -2030,8 +2028,7 @@ def test_setchannelfee_state(node_factory, bitcoind):
|
||||||
# cid = result['channels'][0]['channel_id']
|
# cid = result['channels'][0]['channel_id']
|
||||||
|
|
||||||
# test routing correct new fees once routing is established
|
# test routing correct new fees once routing is established
|
||||||
bitcoind.generate_block(6)
|
mine_funding_to_announce(bitcoind, [l0, l1, l2])
|
||||||
sync_blockheight(bitcoind, [l0, l1, l2])
|
|
||||||
|
|
||||||
l0.wait_for_route(l2)
|
l0.wait_for_route(l2)
|
||||||
inv = l2.rpc.invoice(100000, 'test_setchannelfee_state', 'desc')['bolt11']
|
inv = l2.rpc.invoice(100000, 'test_setchannelfee_state', 'desc')['bolt11']
|
||||||
|
@ -2595,7 +2592,7 @@ def test_tlv_or_legacy(node_factory, bitcoind):
|
||||||
l3.daemon.wait_for_log("Got onion.*'type': 'tlv'")
|
l3.daemon.wait_for_log("Got onion.*'type': 'tlv'")
|
||||||
|
|
||||||
# We need 5 more blocks to announce l1->l2 channel.
|
# We need 5 more blocks to announce l1->l2 channel.
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3])
|
||||||
|
|
||||||
# Make sure l1 knows about l2
|
# Make sure l1 knows about l2
|
||||||
wait_for(lambda: 'alias' in l1.rpc.listnodes(l2.info['id'])['nodes'][0])
|
wait_for(lambda: 'alias' in l1.rpc.listnodes(l2.info['id'])['nodes'][0])
|
||||||
|
@ -2828,7 +2825,7 @@ def test_partial_payment(node_factory, bitcoind, executor):
|
||||||
scid24, _ = l2.fundchannel(l4, 100000)
|
scid24, _ = l2.fundchannel(l4, 100000)
|
||||||
l3.rpc.connect(l4.info['id'], 'localhost', l4.port)
|
l3.rpc.connect(l4.info['id'], 'localhost', l4.port)
|
||||||
scid34, _ = l3.fundchannel(l4, 100000)
|
scid34, _ = l3.fundchannel(l4, 100000)
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4])
|
||||||
|
|
||||||
# Wait until l1 knows about all channels.
|
# Wait until l1 knows about all channels.
|
||||||
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 8)
|
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 8)
|
||||||
|
@ -3633,7 +3630,7 @@ def test_mpp_adaptive(node_factory, bitcoind):
|
||||||
assert(c12['spendable_msat'].millisatoshis < amt)
|
assert(c12['spendable_msat'].millisatoshis < amt)
|
||||||
assert(c34['spendable_msat'].millisatoshis < amt)
|
assert(c34['spendable_msat'].millisatoshis < amt)
|
||||||
|
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4])
|
||||||
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 8)
|
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 8)
|
||||||
|
|
||||||
inv = l4.rpc.invoice(
|
inv = l4.rpc.invoice(
|
||||||
|
@ -3728,8 +3725,7 @@ def test_mpp_presplit_routehint_conflict(node_factory, bitcoind):
|
||||||
l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
|
l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
|
||||||
l2.fundchannel(l3, 10**7, announce_channel=False)
|
l2.fundchannel(l3, 10**7, announce_channel=False)
|
||||||
|
|
||||||
bitcoind.generate_block(6)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3])
|
||||||
sync_blockheight(bitcoind, [l1, l2, l3])
|
|
||||||
|
|
||||||
# Wait for l3 to learn about l1->l2, otherwise it will think
|
# Wait for l3 to learn about l1->l2, otherwise it will think
|
||||||
# l2 is a deadend and not add it to the routehint.
|
# l2 is a deadend and not add it to the routehint.
|
||||||
|
@ -3894,8 +3890,7 @@ def test_mpp_waitblockheight_routehint_conflict(node_factory, bitcoind, executor
|
||||||
l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
|
l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
|
||||||
l2.fundchannel(l3, 10**7, announce_channel=False)
|
l2.fundchannel(l3, 10**7, announce_channel=False)
|
||||||
|
|
||||||
bitcoind.generate_block(6)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3])
|
||||||
sync_blockheight(bitcoind, [l1, l2, l3])
|
|
||||||
|
|
||||||
# Wait for l3 to learn about l1->l2, otherwise it will think
|
# Wait for l3 to learn about l1->l2, otherwise it will think
|
||||||
# l2 is a deadend and not add it to the routehint.
|
# l2 is a deadend and not add it to the routehint.
|
||||||
|
@ -4017,8 +4012,7 @@ def test_mpp_interference_2(node_factory, bitcoind, executor):
|
||||||
l3.fundchannel(l6, int((unit * 6).to_satoshi()), announce_channel=False)
|
l3.fundchannel(l6, int((unit * 6).to_satoshi()), announce_channel=False)
|
||||||
|
|
||||||
# Now wait for the buyers to learn the entire public network.
|
# Now wait for the buyers to learn the entire public network.
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4, l5, l6, l7])
|
||||||
sync_blockheight(bitcoind, [l1, l2, l3, l4, l5, l6, l7])
|
|
||||||
for channel in public_network:
|
for channel in public_network:
|
||||||
wait_for(lambda: len(l2.rpc.listchannels(channel)['channels']) == 2)
|
wait_for(lambda: len(l2.rpc.listchannels(channel)['channels']) == 2)
|
||||||
wait_for(lambda: len(l3.rpc.listchannels(channel)['channels']) == 2)
|
wait_for(lambda: len(l3.rpc.listchannels(channel)['channels']) == 2)
|
||||||
|
@ -4120,8 +4114,7 @@ def test_mpp_overload_payee(node_factory, bitcoind):
|
||||||
l5.fundbalancedchannel(l6, amt)]
|
l5.fundbalancedchannel(l6, amt)]
|
||||||
|
|
||||||
# Ensure l1 knows the entire public network.
|
# Ensure l1 knows the entire public network.
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3, l4, l5, l6])
|
||||||
sync_blockheight(bitcoind, [l1, l2, l3, l4, l5, l6])
|
|
||||||
for c in public_network:
|
for c in public_network:
|
||||||
wait_for(lambda: len(l1.rpc.listchannels(c)['channels']) >= 2)
|
wait_for(lambda: len(l1.rpc.listchannels(c)['channels']) >= 2)
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ from utils import (
|
||||||
DEVELOPER, only_one, sync_blockheight, TIMEOUT, wait_for, TEST_NETWORK,
|
DEVELOPER, only_one, sync_blockheight, TIMEOUT, wait_for, TEST_NETWORK,
|
||||||
DEPRECATED_APIS, expected_peer_features, expected_node_features,
|
DEPRECATED_APIS, expected_peer_features, expected_node_features,
|
||||||
expected_channel_features, account_balance,
|
expected_channel_features, account_balance,
|
||||||
check_coin_moves, first_channel_id, EXPERIMENTAL_DUAL_FUND
|
check_coin_moves, first_channel_id, EXPERIMENTAL_DUAL_FUND,
|
||||||
|
mine_funding_to_announce
|
||||||
)
|
)
|
||||||
|
|
||||||
import ast
|
import ast
|
||||||
|
@ -1723,7 +1724,9 @@ def test_hook_crash(node_factory, executor, bitcoind):
|
||||||
n.rpc.plugin_start(p)
|
n.rpc.plugin_start(p)
|
||||||
l1.openchannel(n, 10**6, confirm=False, wait_for_announce=False)
|
l1.openchannel(n, 10**6, confirm=False, wait_for_announce=False)
|
||||||
|
|
||||||
bitcoind.generate_block(6)
|
# Mine final openchannel tx first.
|
||||||
|
sync_blockheight(bitcoind, [l1] + nodes)
|
||||||
|
mine_funding_to_announce(bitcoind, [l1] + nodes, wait_for_mempool=1)
|
||||||
|
|
||||||
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 2 * len(perm))
|
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 2 * len(perm))
|
||||||
|
|
||||||
|
@ -1918,7 +1921,7 @@ def test_coin_movement_notices(node_factory, bitcoind, chainparams):
|
||||||
{'may_reconnect': True, 'plugin': coin_plugin},
|
{'may_reconnect': True, 'plugin': coin_plugin},
|
||||||
], wait_for_announce=True)
|
], wait_for_announce=True)
|
||||||
|
|
||||||
bitcoind.generate_block(5)
|
mine_funding_to_announce(bitcoind, [l1, l2, l3])
|
||||||
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 4)
|
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 4)
|
||||||
amount = 10**8
|
amount = 10**8
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from pyln.testing.utils import TEST_NETWORK, TIMEOUT, VALGRIND, DEVELOPER, DEPRECATED_APIS # noqa: F401
|
from pyln.testing.utils import TEST_NETWORK, TIMEOUT, VALGRIND, DEVELOPER, DEPRECATED_APIS # noqa: F401
|
||||||
from pyln.testing.utils import env, only_one, wait_for, write_config, TailableProc, sync_blockheight, wait_channel_quiescent, get_tx_p2wsh_outnum # noqa: F401
|
from pyln.testing.utils import env, only_one, wait_for, write_config, TailableProc, sync_blockheight, wait_channel_quiescent, get_tx_p2wsh_outnum, mine_funding_to_announce # noqa: F401
|
||||||
import bitstring
|
import bitstring
|
||||||
from pyln.client import Millisatoshi
|
from pyln.client import Millisatoshi
|
||||||
from pyln.testing.utils import EXPERIMENTAL_DUAL_FUND
|
from pyln.testing.utils import EXPERIMENTAL_DUAL_FUND
|
||||||
|
|
Loading…
Reference in New Issue