topology: don't show private nodes in listchannels.

This alters a few remaining tests, as well.

[ Inclused even more test fixes from Alex Myers <alex@endothermic.dev>! ]

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Deprecated: JSON-RPC: `listchannels` listing private channels: use listpeerchannels
This commit is contained in:
Rusty Russell 2023-12-13 16:06:19 +10:30
parent 3a6b9f2ec6
commit 58a1c4c012
7 changed files with 50 additions and 48 deletions

View File

@ -13,6 +13,9 @@ The **listchannels** RPC command returns data on channels that are known
to the node. Because channels may be bidirectional, up to 2 objects will
be returned for each channel (one for each direction).
Note that for local channels, listpeerchannels(7) gives much more detailed
information: **listchannels** only shows public gossip information (previously it merged local information, but that was deprecated in *v24.02*).
If *short\_channel\_id* is a short channel id, then only known channels with a
matching *short\_channel\_id* are returned. Otherwise, it must be null.
@ -37,7 +40,7 @@ On success, an object containing **channels** is returned. It is an array of ob
- **destination** (pubkey): the destination node
- **short\_channel\_id** (short\_channel\_id): short channel id of channel
- **direction** (u32): direction (0 if source < destination, 1 otherwise).
- **public** (boolean): true if this is announced (otherwise it must be our channel)
- **public** (boolean): true if this is announced (from *v24.02*, being false is deprecated)
- **amount\_msat** (msat): the total capacity of this channel (always a whole number of satoshis)
- **message\_flags** (u8): as defined by BOLT #7
- **channel\_flags** (u8): as defined by BOLT #7
@ -80,4 +83,4 @@ Lightning RFC site
- BOLT \#7:
<https://github.com/lightning/bolts/blob/master/07-routing-gossip.md>
[comment]: # ( SHA256STAMP:cef9786aeca2eddaca0d1adf6dc3d0eef442297e0f63d7c49647e65dbca73396)
[comment]: # ( SHA256STAMP:5e729a362943aa9481cc12e410c1f507020983251871fbac497dbb8679ca36ca)

View File

@ -47,7 +47,7 @@
},
"public": {
"type": "boolean",
"description": "true if this is announced (otherwise it must be our channel)"
"description": "true if this is announced (from *v24.02*, being false is deprecated)"
},
"amount_msat": {
"type": "msat",

View File

@ -359,7 +359,7 @@ static struct command_result *listpeerchannels_done(struct command *cmd,
struct node_map *connected;
struct gossmap_chan *c;
struct json_stream *js;
struct gossmap *gossmap = get_gossmap(false);
struct gossmap *gossmap = get_gossmap(true);
connected = local_connected(opts, buf, result);

View File

@ -316,7 +316,7 @@ def test_grpc_keysend_routehint(bitcoind, node_factory):
])
# FIXME: keysend needs (unannounced) channel in gossip_store
l1.wait_channel_active(first_scid(l1, l2))
l1.wait_local_channel_active(first_scid(l1, l2))
# And now we send a keysend with that routehint list
call = clnpb.KeysendRequest(

View File

@ -2400,12 +2400,14 @@ def test_channel_reenable(node_factory):
# Restart l2, will cause l1 to reconnect
l2.stop()
wait_for(lambda: [c['active'] for c in l1.rpc.listchannels()['channels']] == [False, False])
wait_for(lambda: [c['peer_connected'] for c in l1.rpc.listpeerchannels()['channels']] == [False])
l2.start()
# Updates may be suppressed if redundant; just test results.
wait_for(lambda: [c['active'] for c in l1.rpc.listchannels()['channels']] == [True, True])
wait_for(lambda: [c['peer_connected'] for c in l1.rpc.listpeerchannels()['channels']] == [True])
wait_for(lambda: [c['active'] for c in l2.rpc.listchannels()['channels']] == [True, True])
wait_for(lambda: [c['peer_connected'] for c in l2.rpc.listpeerchannels()['channels']] == [True])
def test_update_fee(node_factory, bitcoind):

View File

@ -92,7 +92,8 @@ def test_gossip_disable_channels(node_factory, bitcoind):
def count_active(node):
chans = node.rpc.listchannels()['channels']
active = [c for c in chans if c['active']]
return len(active)
connected = len([p for p in node.rpc.listpeerchannels()['channels'] if p['peer_connected'] is True])
return connected * len(active)
l1.wait_channel_active(scid)
l2.wait_channel_active(scid)
@ -394,23 +395,32 @@ def test_gossip_jsonrpc(node_factory):
# Shouldn't send announce signatures until 6 deep.
assert not l1.daemon.is_in_log('peer_out WIRE_ANNOUNCEMENT_SIGNATURES')
# Channels should be activated locally
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 2)
wait_for(lambda: len(l2.rpc.listchannels()['channels']) == 2)
# Make sure we can route through the channel, will raise on failure
l1.rpc.getroute(l2.info['id'], 100, 1)
# Outgoing should be active, but not public.
channels1 = l1.rpc.listchannels()['channels']
channels2 = l2.rpc.listchannels()['channels']
# Channels not should be activated locally
assert l1.rpc.listchannels() == {'channels': []}
assert l2.rpc.listchannels() == {'channels': []}
assert [c['active'] for c in channels1] == [True, True]
assert [c['active'] for c in channels2] == [True, True]
# The incoming direction will be considered public, hence check for out
# outgoing only
assert len([c for c in channels1 if not c['public']]) == 2
assert len([c for c in channels2 if not c['public']]) == 2
# Outgoing should be public, even if not announced yet.
channels1 = l1.rpc.listpeerchannels()['channels']
channels2 = l2.rpc.listpeerchannels()['channels']
assert [c['private'] for c in channels1] == [False]
assert [c['private'] for c in channels2] == [False]
# Now proceed to funding-depth and do a full gossip round
l1.bitcoin.generate_block(5)
# Could happen in either order.
l1.daemon.wait_for_logs(['peer_out WIRE_ANNOUNCEMENT_SIGNATURES',
'peer_in WIRE_ANNOUNCEMENT_SIGNATURES'])
# Just wait for the update to kick off and then check the effect
needle = "Received node_announcement for node"
l1.daemon.wait_for_log(needle)
l2.daemon.wait_for_log(needle)
l1.wait_channel_active(only_one(channels1)['short_channel_id'])
l2.wait_channel_active(only_one(channels1)['short_channel_id'])
# Test listchannels-by-source
channels1 = l1.rpc.listchannels(source=l1.info['id'])['channels']
@ -440,19 +450,6 @@ def test_gossip_jsonrpc(node_factory):
with pytest.raises(RpcError, match=r"Can only specify one of.*"):
l1.rpc.listchannels(short_channel_id="1x1x1", source=l2.info['id'])
# Now proceed to funding-depth and do a full gossip round
l1.bitcoin.generate_block(5)
# Could happen in either order.
l1.daemon.wait_for_logs(['peer_out WIRE_ANNOUNCEMENT_SIGNATURES',
'peer_in WIRE_ANNOUNCEMENT_SIGNATURES'])
# Just wait for the update to kick off and then check the effect
needle = "Received node_announcement for node"
l1.daemon.wait_for_log(needle)
l2.daemon.wait_for_log(needle)
l1.wait_channel_active(only_one(channels1)['short_channel_id'])
l2.wait_channel_active(only_one(channels1)['short_channel_id'])
nodes = l1.rpc.listnodes()['nodes']
assert set([n['nodeid'] for n in nodes]) == set([l1.info['id'], l2.info['id']])
@ -561,20 +558,20 @@ def test_gossip_persistence(node_factory, bitcoind):
return sorted([c['short_channel_id'] for c in chans if c['active']])
def non_public(node):
chans = node.rpc.listchannels()['channels']
return sorted([c['short_channel_id'] for c in chans if not c['public']])
# Not just c["private"] == True, but immature ones too.
public_chans = [c['short_channel_id'] for c in node.rpc.listchannels()['channels']]
our_chans = [c['short_channel_id'] for c in node.rpc.listpeerchannels()['channels'] if c['state'] in ('CHANNELD_NORMAL', 'CHANNELD_AWAITING_SPLICE')]
return sorted(list(set(our_chans) - set(public_chans)))
# Channels should be activated
wait_for(lambda: active(l1) == [scid12, scid12, scid23, scid23])
wait_for(lambda: active(l2) == [scid12, scid12, scid23, scid23])
# This one sees its private channel
wait_for(lambda: active(l3) == [scid12, scid12, scid23, scid23, scid34, scid34])
# This one has private channels, but doesn't appear in listchannels.
wait_for(lambda: active(l3) == [scid12, scid12, scid23, scid23])
# l1 restarts and doesn't connect, but loads from persisted store, all
# local channels should be disabled, leaving only the two l2 <-> l3
# directions
# l1 restarts and public gossip should persist
l1.restart()
wait_for(lambda: active(l1) == [scid23, scid23])
wait_for(lambda: active(l1) == [scid12, scid12, scid23, scid23])
# Now reconnect, they should re-enable the two l1 <-> l2 directions
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
@ -590,24 +587,24 @@ def test_gossip_persistence(node_factory, bitcoind):
wait_for(lambda: active(l1) == [scid23, scid23])
wait_for(lambda: active(l2) == [scid23, scid23])
wait_for(lambda: active(l3) == [scid23, scid23, scid34, scid34])
wait_for(lambda: active(l3) == [scid23, scid23])
# The channel l3 -> l4 should be known only to them
assert non_public(l1) == []
assert non_public(l2) == []
wait_for(lambda: non_public(l3) == [scid34, scid34])
wait_for(lambda: non_public(l4) == [scid34, scid34])
wait_for(lambda: non_public(l3) == [scid34])
wait_for(lambda: non_public(l4) == [scid34])
# Finally, it should also remember the deletion after a restart
l3.restart()
l4.restart()
l2.rpc.connect(l3.info['id'], 'localhost', l3.port)
l3.rpc.connect(l4.info['id'], 'localhost', l4.port)
wait_for(lambda: active(l3) == [scid23, scid23, scid34, scid34])
wait_for(lambda: active(l3) == [scid23, scid23])
# Both l3 and l4 should remember their local-only channel
wait_for(lambda: non_public(l3) == [scid34, scid34])
wait_for(lambda: non_public(l4) == [scid34, scid34])
wait_for(lambda: non_public(l3) == [scid34])
wait_for(lambda: non_public(l4) == [scid34])
def test_routing_gossip_reconnect(node_factory):

View File

@ -309,7 +309,7 @@ def test_pay_get_error_with_update(node_factory):
l3.stop()
# Make sure that l2 has seen disconnect, considers channel disabled.
wait_for(lambda: [c['active'] for c in l2.rpc.listchannels(chanid2)['channels']] == [False, False])
wait_for(lambda: only_one(l2.rpc.listpeerchannels(l3.info['id'])['channels'])['peer_connected'] is False)
assert(l1.is_channel_active(chanid2))
with pytest.raises(RpcError, match=r'WIRE_TEMPORARY_CHANNEL_FAILURE'):