Skip to content

Commit

Permalink
askrene: batch create channels
Browse files Browse the repository at this point in the history
Changelog-EXPERIMENTAL: askrene: modify the RPC call create-channel to be able to add channels in batches.

Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
  • Loading branch information
Lagrang3 committed Sep 13, 2024
1 parent 2bd9c22 commit 94ac4b9
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 163 deletions.
105 changes: 0 additions & 105 deletions doc/schemas/lightning-askrene-create-channel.json

This file was deleted.

116 changes: 116 additions & 0 deletions doc/schemas/lightning-askrene-create-channels.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
{
"$schema": "../rpc-schema-draft.json",
"type": "object",
"additionalProperties": false,
"rpc": "askrene-create-channels",
"title": "Command to add channels to layer (EXPERIMENTAL)",
"description": [
"WARNING: experimental, so API may change.",
"",
"The **askrene-create-channels** RPC command tells askrene to populate one direction of a list of channels in the given layer. If the channels already exist, they will be overridden. If the layer does not exist, it will be created."
],
"request": {
"required": [
"layer",
"channels"
],
"properties": {
"layer": {
"type": "string",
"description": [
"The name of the layer to apply this change to."
]
},
"channels": {
"type": "array",
"items": {
"type": "object",
"required": [
"source",
"destination",
"short_channel_id",
"capacity_msat",
"htlc_mininum_msat",
"htlc_maximum_msat",
"fee_base_msat",
"fee_proportional_millionths",
"delay"
],
"properties": {
"source": {
"type": "pubkey",
"description": [
"The source node id for the channel."
]
},
"destination": {
"type": "pubkey",
"description": [
"The destination node id for the channel."
]
},
"short_channel_id": {
"type": "short_channel_id",
"description": [
"The short channel id for the channel. If a channel with this short channel id already exists in *layer*, the *source*, *destination* and *capacity_msat* must be the same."
]
},
"capacity_msat": {
"type": "msat",
"description": [
"The capacity (onchain size) of the channel."
]
},
"htlc_mininum_msat": {
"type": "msat",
"description": [
"The minimum value allowed in this direction."
]
},
"htlc_maximum_msat": {
"type": "msat",
"description": [
"The maximum value allowed in this direction."
]
},
"fee_base_msat": {
"type": "msat",
"description": [
"The base fee to apply to use the channel in this direction."
]
},
"fee_proportional_millionths": {
"type": "u32",
"description": [
"The proportional fee (in parts per million) to apply to use the channel in this direction."
]
},
"delay": {
"type": "u16",
"description": [
"The CLTV delay required for this direction."
]
}
}
}
}
}
},
"response": {
"required": [],
"properties": {}
},
"see_also": [
"lightning-getroutes(7)",
"lightning-askrene-disable-node(7)",
"lightning-askrene-inform-channel(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>"
]
}
101 changes: 67 additions & 34 deletions plugins/askrene/askrene.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,49 @@ static struct command_result *param_string_array(struct command *cmd,
return NULL;
}

static struct command_result *
param_localchannel_array(struct command *cmd, const char *name,
const char *buffer, const jsmntok_t *tok,
struct local_channel **channels)
{
size_t i;
const jsmntok_t *t;

if (tok->type != JSMN_ARRAY)
return command_fail_badparam(cmd, name, buffer, tok,
"should be an array");

*channels = tal_arr(cmd, struct local_channel, tok->size);
json_for_each_arr(i, t, tok)
{
struct local_channel *c = &(*channels)[i];

const char *err = json_scan(
cmd, buffer, t,
"{source:%"
",destination:%"
",short_channel_id:%"
",capacity_msat:%"
",htlc_minimum_msat:%"
",htlc_maximum_msat:%"
",fee_base_msat:%"
",fee_proportional_millionths:%"
",delay:%}",
JSON_SCAN(json_to_node_id, &c->n1),
JSON_SCAN(json_to_node_id, &c->n2),
JSON_SCAN(json_to_short_channel_id, &c->scid),
JSON_SCAN(json_to_msat, &c->capacity),
JSON_SCAN(json_to_msat, &c->half[0].htlc_min),
JSON_SCAN(json_to_msat, &c->half[0].htlc_max),
JSON_SCAN(json_to_msat, &c->half[0].base_fee),
JSON_SCAN(json_to_u32, &c->half[0].proportional_fee),
JSON_SCAN(json_to_u16, &c->half[0].delay));
if (err)
return command_fail_badparam(cmd, name, buffer, t, err);
}
return NULL;
}

static struct command_result *param_known_layer(struct command *cmd,
const char *name,
const char *buffer,
Expand Down Expand Up @@ -673,56 +716,46 @@ static struct command_result *param_layername(struct command *cmd,
return NULL;
}

static struct command_result *json_askrene_create_channel(struct command *cmd,
const char *buffer,
const jsmntok_t *params)
static struct command_result *
json_askrene_create_channels(struct command *cmd, const char *buffer,
const jsmntok_t *params)
{
const char *layername;
struct local_channel *channels;
struct layer *layer;
const struct local_channel *lc;
struct node_id *src, *dst;
struct short_channel_id *scid;
struct amount_msat *capacity;
struct json_stream *response;
struct amount_msat *htlc_min, *htlc_max, *base_fee;
u32 *proportional_fee;
u16 *delay;
struct askrene *askrene = get_askrene(cmd->plugin);

if (!param_check(cmd, buffer, params,
p_req("layer", param_layername, &layername),
p_req("source", param_node_id, &src),
p_req("destination", param_node_id, &dst),
p_req("short_channel_id", param_short_channel_id, &scid),
p_req("capacity_msat", param_msat, &capacity),
p_req("htlc_minimum_msat", param_msat, &htlc_min),
p_req("htlc_maximum_msat", param_msat, &htlc_max),
p_req("fee_base_msat", param_msat, &base_fee),
p_req("fee_proportional_millionths", param_u32, &proportional_fee),
p_req("delay", param_u16, &delay),
p_req("channels", param_localchannel_array, &channels),
NULL))
return command_param_failed();

/* If it exists, it must match */
layer = find_layer(askrene, layername);
if (layer) {
lc = layer_find_local_channel(layer, *scid);
if (lc && !layer_check_local_channel(lc, src, dst, *capacity)) {
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"channel already exists with different values!");
}
} else
lc = NULL;

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

layer = find_layer(askrene, layername);
if (!layer)
layer = new_layer(askrene, layername);

layer_update_local_channel(layer, src, dst, *scid, *capacity,
*base_fee, *proportional_fee, *delay,
*htlc_min, *htlc_max);
for (size_t i = 0; i < tal_count(channels); i++) {
struct local_channel *c = &channels[i];

/* If it exists, it must match */
lc = layer_find_local_channel(layer, c->scid);
if (lc &&
!layer_check_local_channel(lc, &c->n1, &c->n2, c->capacity))
return command_fail(
cmd, JSONRPC2_INVALID_PARAMS,
"channel already exists with different values!");

layer_update_local_channel(
layer, &c->n1, &c->n2, c->scid, c->capacity,
c->half[0].base_fee, c->half[0].proportional_fee,
c->half[0].delay, c->half[0].htlc_min, c->half[0].htlc_max);
}

response = jsonrpc_stream_success(cmd);
return command_finished(cmd, response);
Expand Down Expand Up @@ -866,8 +899,8 @@ static const struct plugin_command commands[] = {
json_askrene_disable_node,
},
{
"askrene-create-channel",
json_askrene_create_channel,
"askrene-create-channels",
json_askrene_create_channels,
},
{
"askrene-inform-channel",
Expand Down
17 changes: 0 additions & 17 deletions plugins/askrene/layer.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,6 @@
#include <plugins/askrene/askrene.h>
#include <plugins/askrene/layer.h>

/* A channels which doesn't (necessarily) exist in the gossmap. */
struct local_channel {
/* Canonical order, n1 < n2 */
struct node_id n1, n2;
struct short_channel_id scid;
struct amount_msat capacity;

struct added_channel_half {
/* Other fields only valid if this is true */
bool enabled;
u16 delay;
u32 proportional_fee;
struct amount_msat base_fee;
struct amount_msat htlc_min, htlc_max;
} half[2];
};

static const struct constraint_key *
constraint_key(const struct constraint *c)
{
Expand Down
Loading

0 comments on commit 94ac4b9

Please sign in to comment.