Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

askrene: add expiration parameter to create-layer #7963

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions doc/schemas/lightning-askrene-create-layer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@
"description": [
"True if askrene should save and restore this layer. As a side-effect, create-layer also succeeds if the layer already exists and persistent is true."
]
},
"expiration": {
"type": "u64",
"description": [
"Sets the number of seconds until this layer expires. If this number is specified the layer will be automatically deleted at expiration. A layer cannot be persistent and have an expiration time."
],
"added": "v25.02"
}
}
},
Expand Down
35 changes: 35 additions & 0 deletions plugins/askrene/askrene.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <common/gossmods_listpeerchannels.h>
#include <common/json_param.h>
#include <common/json_stream.h>
#include <common/memleak.h>
#include <common/route.h>
#include <errno.h>
#include <math.h>
Expand Down Expand Up @@ -623,6 +624,7 @@ static struct command_result *do_getroutes(struct command *cmd,
*info->amount, *info->maxfee, *info->finalcltv,
info->layers, localmods, info->local_layer,
&routes, &amounts, info->additional_costs, &probability);

if (err)
return command_fail(cmd, PAY_ROUTE_NOT_FOUND, "%s", err);

Expand Down Expand Up @@ -1060,6 +1062,27 @@ static struct command_result *json_askrene_disable_node(struct command *cmd,
return command_finished(cmd, response);
}

static struct command_result *expire_layer_done(struct command *timer_cmd,
const char *method,
const char *buf,
const jsmntok_t *result,
void *unused)
{
return timer_complete(timer_cmd);
}

static struct command_result *expire_layer(struct command *timer_cmd,
struct layer *l)
{
struct out_req *req;
req = jsonrpc_request_start(timer_cmd, "askrene-remove-layer",
expire_layer_done, plugin_broken_cb, NULL);
json_add_string(req->js, "layer", layer_name(l));
plugin_log(timer_cmd->plugin, LOG_DBG, "removing expired layer '%s'",
layer_name(l));
return send_outreq(req);
}

static struct command_result *json_askrene_create_layer(struct command *cmd,
const char *buffer,
const jsmntok_t *params)
Expand All @@ -1069,10 +1092,12 @@ static struct command_result *json_askrene_create_layer(struct command *cmd,
const char *layername;
struct json_stream *response;
bool *persistent;
u64 *expire_seconds;

if (!param_check(cmd, buffer, params,
p_req("layer", param_string, &layername),
p_opt_def("persistent", param_bool, &persistent, false),
p_opt("expiration", param_u64, &expire_seconds),
NULL))
return command_param_failed();

Expand All @@ -1086,13 +1111,23 @@ static struct command_result *json_askrene_create_layer(struct command *cmd,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Layer already exists");
}
if (persistent && expire_seconds && *persistent == true) {
return command_fail(
cmd, JSONRPC2_INVALID_PARAMS,
"A persistent layer cannot have an expiration time.");
}

if (command_check_only(cmd))
return command_check_done(cmd);

if (!layer)
layer = new_layer(askrene, layername, *persistent);

if (expire_seconds)
notleak(global_timer(cmd->plugin,
time_from_sec(*expire_seconds),
expire_layer, layer));

response = jsonrpc_stream_success(cmd);
json_add_layers(response, askrene, "layers", layer);
return command_finished(cmd, response);
Expand Down
25 changes: 25 additions & 0 deletions tests/test_askrene.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,31 @@ def test_layer_persistence(node_factory):
assert l1.rpc.askrene_listlayers() == {'layers': []}


def test_layer_expiration(node_factory):
l1 = node_factory.get_nodes(1, opts={"disable-plugin": "cln-xpay"})[0]
expect = {
"layer": "tmp_layer",
"persistent": False,
"disabled_nodes": [],
"created_channels": [],
"channel_updates": [],
"constraints": [],
"biases": [],
}

assert l1.rpc.askrene_listlayers() == {"layers": []}
# Add a self-destructing layer
l1.rpc.askrene_create_layer(layer="tmp_layer", expiration=5)
assert l1.rpc.askrene_listlayers() == {"layers": [expect]}
time.sleep(6)
assert l1.rpc.askrene_listlayers() == {"layers": []}

with pytest.raises(
RpcError, match="A persistent layer cannot have an expiration time."
):
l1.rpc.askrene_create_layer(layer="pers_layer", persistent=True, expiration=5)


def check_route_as_expected(routes, paths):
"""Make sure all fields in paths are match those in routes"""
def dict_subset_eq(a, b):
Expand Down
Loading