add askrene-disable-channel

Changelog-EXPERIMENTAL: askrene: add askrene-disable-channel RPC
Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
This commit is contained in:
Lagrang3 2024-10-04 08:51:53 +09:30 committed by Rusty Russell
parent f46219b505
commit 33404b03a0
4 changed files with 149 additions and 0 deletions

View File

@ -361,6 +361,56 @@
"Main web site: <https://github.com/ElementsProject/lightning>"
]
},
"lightning-askrene-disable-channel.json": {
"$schema": "../rpc-schema-draft.json",
"type": "object",
"additionalProperties": false,
"rpc": "askrene-disable-channel",
"title": "Command to disable a channel in a layer (EXPERIMENTAL)",
"description": [
"WARNING: experimental, so API may change.",
"",
"The **askrene-disable-channel** RPC command tells askrene to disable a channel whenever the given layer is used. This is mainly useful to force the use of alternate paths."
],
"request": {
"required": [
"layer",
"short_channel_id_dir"
],
"properties": {
"layer": {
"type": "string",
"description": [
"The name of the layer to apply this change to."
]
},
"short_channel_id_dir": {
"type": "short_channel_id_dir",
"description": [
"The channel and direction to disable."
]
}
}
},
"response": {
"required": [],
"properties": {}
},
"see_also": [
"lightning-getroutes(7)",
"lightning-askrene-create-channel(7)",
"lightning-askrene-inform-channel(7)",
"lightning-askrene-disable-node(7)",
"lightning-askrene-listlayers(7)",
"lightning-askrene-age(7)"
],
"author": [
"Rusty Russell <<rusty@rustcorp.com.au>> is mainly responsible."
],
"resources": [
"Main web site: <https://github.com/ElementsProject/lightning>"
]
},
"lightning-askrene-disable-node.json": {
"$schema": "../rpc-schema-draft.json",
"type": "object",

View File

@ -0,0 +1,50 @@
{
"$schema": "../rpc-schema-draft.json",
"type": "object",
"additionalProperties": false,
"rpc": "askrene-disable-channel",
"title": "Command to disable a channel in a layer (EXPERIMENTAL)",
"description": [
"WARNING: experimental, so API may change.",
"",
"The **askrene-disable-channel** RPC command tells askrene to disable a channel whenever the given layer is used. This is mainly useful to force the use of alternate paths."
],
"request": {
"required": [
"layer",
"short_channel_id_dir"
],
"properties": {
"layer": {
"type": "string",
"description": [
"The name of the layer to apply this change to."
]
},
"short_channel_id_dir": {
"type": "short_channel_id_dir",
"description": [
"The channel and direction to disable."
]
}
}
},
"response": {
"required": [],
"properties": {}
},
"see_also": [
"lightning-getroutes(7)",
"lightning-askrene-create-channel(7)",
"lightning-askrene-inform-channel(7)",
"lightning-askrene-disable-node(7)",
"lightning-askrene-listlayers(7)",
"lightning-askrene-age(7)"
],
"author": [
"Rusty Russell <<rusty@rustcorp.com.au>> is mainly responsible."
],
"resources": [
"Main web site: <https://github.com/ElementsProject/lightning>"
]
}

View File

@ -870,6 +870,32 @@ static struct command_result *json_askrene_inform_channel(struct command *cmd,
return command_finished(cmd, response);
}
static struct command_result *json_askrene_disable_channel(struct command *cmd,
const char *buffer,
const jsmntok_t *params)
{
struct short_channel_id_dir *scidd;
const char *layername;
struct layer *layer;
struct json_stream *response;
struct askrene *askrene = get_askrene(cmd->plugin);
if (!param(cmd, buffer, params,
p_req("layer", param_layername, &layername),
p_req("short_channel_id_dir", param_short_channel_id_dir, &scidd),
NULL))
return command_param_failed();
layer = find_layer(askrene, layername);
if (!layer)
layer = new_layer(askrene, layername);
layer_add_disabled_channel(layer, scidd);
response = jsonrpc_stream_success(cmd);
return command_finished(cmd, response);
}
static struct command_result *json_askrene_disable_node(struct command *cmd,
const char *buffer,
const jsmntok_t *params)
@ -972,6 +998,10 @@ static const struct plugin_command commands[] = {
"askrene-age",
json_askrene_age,
},
{
"askrene-disable-channel",
json_askrene_disable_channel,
},
};
static void askrene_markmem(struct plugin *plugin, struct htable *memtable)

View File

@ -17,6 +17,7 @@ def test_layers(node_factory):
expect = {'layer': 'test_layers',
'disabled_nodes': [],
'disabled_channels': [],
'created_channels': [],
'constraints': []}
l2.rpc.askrene_disable_node('test_layers', l1.info['id'])
@ -25,6 +26,10 @@ def test_layers(node_factory):
assert l2.rpc.askrene_listlayers() == {'layers': [expect]}
assert l2.rpc.askrene_listlayers('test_layers2') == {'layers': []}
l2.rpc.askrene_disable_channel('test_layers', "1x2x3/0")
expect['disabled_channels'].append("1x2x3/0")
assert l2.rpc.askrene_listlayers('test_layers') == {'layers': [expect]}
# Tell it l3 connects to l1!
l2.rpc.askrene_create_channel('test_layers',
l3.info['id'],
@ -164,6 +169,20 @@ def test_getroutes(node_factory):
# Set up l1 with this as the gossip_store
l1 = node_factory.get_node(gossip_store_file=gsfile.name)
def direction(nodemap, src, dst):
if nodemap[src] < nodemap[dst]:
return 0
return 1
# Disabling channels makes getroutes fail
l1.rpc.askrene_disable_channel("chans_disabled", f"0x1x0/{direction(nodemap, 0, 1)}")
with pytest.raises(RpcError, match="Could not find route"):
l1.rpc.getroutes(source=nodemap[0],
destination=nodemap[1],
amount_msat=1000,
layers=["chans_disabled"],
maxfee_msat=1000,
final_cltv=99)
# Start easy
assert l1.rpc.getroutes(source=nodemap[0],
destination=nodemap[1],