|
|
@ -534,10 +534,9 @@ def test_routing_gossip(node_factory, bitcoind): |
|
|
|
wait_for(lambda: check_gossip(n)) |
|
|
|
|
|
|
|
|
|
|
|
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") |
|
|
|
@unittest.skipIf(not DEVELOPER, "needs dev-set-max-scids-encode-size") |
|
|
|
def test_gossip_query_channel_range(node_factory, bitcoind): |
|
|
|
l1, l2, l3, l4 = node_factory.line_graph(4, opts={'log-level': 'io'}, |
|
|
|
fundchannel=False) |
|
|
|
l1, l2, l3, l4 = node_factory.line_graph(4, fundchannel=False) |
|
|
|
|
|
|
|
# Make public channels on consecutive blocks |
|
|
|
l1.fundwallet(10**6) |
|
|
@ -567,110 +566,159 @@ def test_gossip_query_channel_range(node_factory, bitcoind): |
|
|
|
|
|
|
|
assert block23 == block12 + 1 |
|
|
|
|
|
|
|
# l1 asks for all channels, gets both. |
|
|
|
ret = l1.rpc.dev_query_channel_range(id=l2.info['id'], |
|
|
|
first=0, |
|
|
|
num=1000000) |
|
|
|
|
|
|
|
assert ret['final_first_block'] == 0 |
|
|
|
assert ret['final_num_blocks'] == 1000000 |
|
|
|
assert ret['final_complete'] |
|
|
|
assert len(ret['short_channel_ids']) == 2 |
|
|
|
assert ret['short_channel_ids'][0] == scid12 |
|
|
|
assert ret['short_channel_ids'][1] == scid23 |
|
|
|
# Asks l2 for all channels, gets both. |
|
|
|
msgs = l2.query_gossip('query_channel_range', |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f', |
|
|
|
0, 1000000) |
|
|
|
encoded = subprocess.run(['devtools/mkencoded', '--scids', '00', scid12, scid23], |
|
|
|
check=True, |
|
|
|
timeout=TIMEOUT, |
|
|
|
stdout=subprocess.PIPE).stdout.strip().decode() |
|
|
|
# reply_channel_range == 264 |
|
|
|
assert msgs == ['0108' |
|
|
|
# blockhash |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f' |
|
|
|
# first_blocknum, number_of_blocks, complete |
|
|
|
+ format(0, '08x') + format(1000000, '08x') + '01' |
|
|
|
# encoded_short_ids |
|
|
|
+ format(len(encoded) // 2, '04x') |
|
|
|
+ encoded] |
|
|
|
|
|
|
|
# Does not include scid12 |
|
|
|
ret = l1.rpc.dev_query_channel_range(id=l2.info['id'], |
|
|
|
first=0, |
|
|
|
num=block12) |
|
|
|
assert ret['final_first_block'] == 0 |
|
|
|
assert ret['final_num_blocks'] == block12 |
|
|
|
assert ret['final_complete'] |
|
|
|
assert len(ret['short_channel_ids']) == 0 |
|
|
|
msgs = l2.query_gossip('query_channel_range', |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f', |
|
|
|
0, block12) |
|
|
|
# reply_channel_range == 264 |
|
|
|
assert msgs == ['0108' |
|
|
|
# blockhash |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f' |
|
|
|
# first_blocknum, number_of_blocks, complete |
|
|
|
+ format(0, '08x') + format(block12, '08x') + '01' |
|
|
|
# encoded_short_ids |
|
|
|
'000100'] |
|
|
|
|
|
|
|
# Does include scid12 |
|
|
|
ret = l1.rpc.dev_query_channel_range(id=l2.info['id'], |
|
|
|
first=0, |
|
|
|
num=block12 + 1) |
|
|
|
assert ret['final_first_block'] == 0 |
|
|
|
assert ret['final_num_blocks'] == block12 + 1 |
|
|
|
assert ret['final_complete'] |
|
|
|
assert len(ret['short_channel_ids']) == 1 |
|
|
|
assert ret['short_channel_ids'][0] == scid12 |
|
|
|
msgs = l2.query_gossip('query_channel_range', |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f', |
|
|
|
0, block12 + 1) |
|
|
|
encoded = subprocess.run(['devtools/mkencoded', '--scids', '00', scid12], |
|
|
|
check=True, |
|
|
|
timeout=TIMEOUT, |
|
|
|
stdout=subprocess.PIPE).stdout.strip().decode() |
|
|
|
# reply_channel_range == 264 |
|
|
|
assert msgs == ['0108' |
|
|
|
# blockhash |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f' |
|
|
|
# first_blocknum, number_of_blocks, complete |
|
|
|
+ format(0, '08x') + format(block12 + 1, '08x') + '01' |
|
|
|
# encoded_short_ids |
|
|
|
+ format(len(encoded) // 2, '04x') |
|
|
|
+ encoded] |
|
|
|
|
|
|
|
# Doesn't include scid23 |
|
|
|
ret = l1.rpc.dev_query_channel_range(id=l2.info['id'], |
|
|
|
first=0, |
|
|
|
num=block23) |
|
|
|
assert ret['final_first_block'] == 0 |
|
|
|
assert ret['final_num_blocks'] == block23 |
|
|
|
assert ret['final_complete'] |
|
|
|
assert len(ret['short_channel_ids']) == 1 |
|
|
|
assert ret['short_channel_ids'][0] == scid12 |
|
|
|
msgs = l2.query_gossip('query_channel_range', |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f', |
|
|
|
0, block23) |
|
|
|
encoded = subprocess.run(['devtools/mkencoded', '--scids', '00', scid12], |
|
|
|
check=True, |
|
|
|
timeout=TIMEOUT, |
|
|
|
stdout=subprocess.PIPE).stdout.strip().decode() |
|
|
|
# reply_channel_range == 264 |
|
|
|
assert msgs == ['0108' |
|
|
|
# blockhash |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f' |
|
|
|
# first_blocknum, number_of_blocks, complete |
|
|
|
+ format(0, '08x') + format(block23, '08x') + '01' |
|
|
|
# encoded_short_ids |
|
|
|
+ format(len(encoded) // 2, '04x') |
|
|
|
+ encoded] |
|
|
|
|
|
|
|
# Does include scid23 |
|
|
|
ret = l1.rpc.dev_query_channel_range(id=l2.info['id'], |
|
|
|
first=block12, |
|
|
|
num=block23 - block12 + 1) |
|
|
|
assert ret['final_first_block'] == block12 |
|
|
|
assert ret['final_num_blocks'] == block23 - block12 + 1 |
|
|
|
assert ret['final_complete'] |
|
|
|
assert len(ret['short_channel_ids']) == 2 |
|
|
|
assert ret['short_channel_ids'][0] == scid12 |
|
|
|
assert ret['short_channel_ids'][1] == scid23 |
|
|
|
msgs = l2.query_gossip('query_channel_range', |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f', |
|
|
|
block12, block23 - block12 + 1) |
|
|
|
encoded = subprocess.run(['devtools/mkencoded', '--scids', '00', scid12, scid23], |
|
|
|
check=True, |
|
|
|
timeout=TIMEOUT, |
|
|
|
stdout=subprocess.PIPE).stdout.strip().decode() |
|
|
|
# reply_channel_range == 264 |
|
|
|
assert msgs == ['0108' |
|
|
|
# blockhash |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f' |
|
|
|
# first_blocknum, number_of_blocks, complete |
|
|
|
+ format(block12, '08x') + format(block23 - block12 + 1, '08x') + '01' |
|
|
|
# encoded_short_ids |
|
|
|
+ format(len(encoded) // 2, '04x') |
|
|
|
+ encoded] |
|
|
|
|
|
|
|
# Only includes scid23 |
|
|
|
ret = l1.rpc.dev_query_channel_range(id=l2.info['id'], |
|
|
|
first=block23, |
|
|
|
num=1) |
|
|
|
assert ret['final_first_block'] == block23 |
|
|
|
assert ret['final_num_blocks'] == 1 |
|
|
|
assert ret['final_complete'] |
|
|
|
assert len(ret['short_channel_ids']) == 1 |
|
|
|
assert ret['short_channel_ids'][0] == scid23 |
|
|
|
msgs = l2.query_gossip('query_channel_range', |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f', |
|
|
|
block23, 1) |
|
|
|
encoded = subprocess.run(['devtools/mkencoded', '--scids', '00', scid23], |
|
|
|
check=True, |
|
|
|
timeout=TIMEOUT, |
|
|
|
stdout=subprocess.PIPE).stdout.strip().decode() |
|
|
|
# reply_channel_range == 264 |
|
|
|
assert msgs == ['0108' |
|
|
|
# blockhash |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f' |
|
|
|
# first_blocknum, number_of_blocks, complete |
|
|
|
+ format(block23, '08x') + format(1, '08x') + '01' |
|
|
|
# encoded_short_ids |
|
|
|
+ format(len(encoded) // 2, '04x') |
|
|
|
+ encoded] |
|
|
|
|
|
|
|
# Past both |
|
|
|
ret = l1.rpc.dev_query_channel_range(id=l2.info['id'], |
|
|
|
first=block23 + 1, |
|
|
|
num=1000000) |
|
|
|
assert ret['final_first_block'] == block23 + 1 |
|
|
|
assert ret['final_num_blocks'] == 1000000 |
|
|
|
assert ret['final_complete'] |
|
|
|
assert len(ret['short_channel_ids']) == 0 |
|
|
|
|
|
|
|
# Turn on IO logging in l1 channeld. |
|
|
|
subprocess.run(['kill', '-USR1', l1.subd_pid('channeld')]) |
|
|
|
msgs = l2.query_gossip('query_channel_range', |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f', |
|
|
|
block23 + 1, 1000000) |
|
|
|
# reply_channel_range == 264 |
|
|
|
assert msgs == ['0108' |
|
|
|
# blockhash |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f' |
|
|
|
# first_blocknum, number_of_blocks, complete |
|
|
|
+ format(block23 + 1, '08x') + format(1000000, '08x') + '01' |
|
|
|
# encoded_short_ids |
|
|
|
+ '000100'] |
|
|
|
|
|
|
|
# Make l2 split reply into two (technically async) |
|
|
|
l2.rpc.dev_set_max_scids_encode_size(max=9) |
|
|
|
l2.daemon.wait_for_log('Set max_scids_encode_bytes to 9') |
|
|
|
ret = l1.rpc.dev_query_channel_range(id=l2.info['id'], |
|
|
|
first=0, |
|
|
|
num=1000000) |
|
|
|
|
|
|
|
# Turns out it sends: 0+53, 53+26, 79+13, 92+7, 99+3, 102+2, 104+1, 105+999895 |
|
|
|
l1.daemon.wait_for_logs([r'\[IN\] 0108'] * 8) |
|
|
|
|
|
|
|
msgs = l2.query_gossip('query_channel_range', |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f', |
|
|
|
0, 1000000) |
|
|
|
# It should definitely have split |
|
|
|
assert ret['final_first_block'] != 0 or ret['final_num_blocks'] != 1000000 |
|
|
|
assert ret['final_complete'] |
|
|
|
assert len(ret['short_channel_ids']) == 2 |
|
|
|
assert ret['short_channel_ids'][0] == scid12 |
|
|
|
assert ret['short_channel_ids'][1] == scid23 |
|
|
|
l2.daemon.wait_for_log('queue_channel_ranges full: splitting') |
|
|
|
# Turns out it sends: 0+53, 53+26, 79+13, 92+7, 99+3, 102+2, 104+1, 105+999895 |
|
|
|
start = 0 |
|
|
|
scids = '00' |
|
|
|
for m in msgs: |
|
|
|
assert m.startswith('0108' |
|
|
|
# blockhash |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f') |
|
|
|
this_start = int(m[4 + 64:4 + 64 + 8], base=16) |
|
|
|
num = int(m[4 + 64 + 8:4 + 64 + 8 + 8], base=16) |
|
|
|
# Pull off end of packet, assume it's uncompressed, and no TLVs! |
|
|
|
scids += m[4 + 64 + 8 + 8 + 2 + 4 + 2:] |
|
|
|
assert this_start == start |
|
|
|
start += num |
|
|
|
|
|
|
|
# Test overflow case doesn't split forever; should still only get 8 for this |
|
|
|
ret = l1.rpc.dev_query_channel_range(id=l2.info['id'], |
|
|
|
first=1, |
|
|
|
num=429496000) |
|
|
|
l1.daemon.wait_for_logs([r'\[IN\] 0108'] * 8) |
|
|
|
encoded = subprocess.run(['devtools/mkencoded', '--scids', '00', scid12, scid23], |
|
|
|
check=True, |
|
|
|
timeout=TIMEOUT, |
|
|
|
stdout=subprocess.PIPE).stdout.strip().decode() |
|
|
|
assert scids == encoded |
|
|
|
|
|
|
|
# And no more! |
|
|
|
time.sleep(1) |
|
|
|
assert not l1.daemon.is_in_log(r'\[IN\] 0108', start=l1.daemon.logsearch_start) |
|
|
|
# Test overflow case doesn't split forever; should still only get 8 for this |
|
|
|
msgs = l2.query_gossip('query_channel_range', |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f', |
|
|
|
1, 429496000) |
|
|
|
assert len(msgs) == 8 |
|
|
|
|
|
|
|
# This should actually be large enough for zlib to kick in! |
|
|
|
l3.fund_channel(l4, 10**5) |
|
|
|
scid34 = l3.fund_channel(l4, 10**5) |
|
|
|
bitcoind.generate_block(5) |
|
|
|
l2.daemon.wait_for_log('Received node_announcement for node ' + l4.info['id']) |
|
|
|
|
|
|
@ -679,25 +727,22 @@ def test_gossip_query_channel_range(node_factory, bitcoind): |
|
|
|
l2.daemon.wait_for_log('Set max_scids_encode_bytes to {}' |
|
|
|
.format(2**32 - 1)) |
|
|
|
|
|
|
|
ret = l1.rpc.dev_query_channel_range(id=l2.info['id'], |
|
|
|
first=0, |
|
|
|
num=65535) |
|
|
|
l1.daemon.wait_for_log( |
|
|
|
# WIRE_REPLY_CHANNEL_RANGE |
|
|
|
r'\[IN\] 0108' |
|
|
|
# chain_hash |
|
|
|
+ '................................................................' |
|
|
|
# first_blocknum |
|
|
|
+ '00000000' |
|
|
|
# number_of_blocks |
|
|
|
+ '0000ffff' |
|
|
|
# complete |
|
|
|
+ '01' |
|
|
|
# length |
|
|
|
+ '....' |
|
|
|
# encoding |
|
|
|
+ '01' |
|
|
|
) |
|
|
|
msgs = l2.query_gossip('query_channel_range', |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f', |
|
|
|
0, 65535) |
|
|
|
encoded = subprocess.run(['devtools/mkencoded', '--scids', '01', scid12, scid23, scid34], |
|
|
|
check=True, |
|
|
|
timeout=TIMEOUT, |
|
|
|
stdout=subprocess.PIPE).stdout.strip().decode() |
|
|
|
# reply_channel_range == 264 |
|
|
|
assert msgs == ['0108' |
|
|
|
# blockhash |
|
|
|
'06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f' |
|
|
|
# first_blocknum, number_of_blocks, complete |
|
|
|
+ format(0, '08x') + format(65535, '08x') + '01' |
|
|
|
# encoded_short_ids |
|
|
|
+ format(len(encoded) // 2, '04x') |
|
|
|
+ encoded] |
|
|
|
|
|
|
|
|
|
|
|
# Long test involving 4 lightningd instances. |
|
|
|