Skip to content

Commit

Permalink
gossipd: allow an array of excluded channels for getroute_request.
Browse files Browse the repository at this point in the history
Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell authored and cdecker committed Jan 15, 2019
1 parent 8738940 commit 599ec5e
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 9 deletions.
3 changes: 3 additions & 0 deletions gossipd/gossip_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ gossip_getroute_request,,msatoshi,u64
gossip_getroute_request,,riskfactor,u16
gossip_getroute_request,,final_cltv,u32
gossip_getroute_request,,fuzz,double
gossip_getroute_request,,num_excluded,u16
gossip_getroute_request,,excluded,num_excluded*struct short_channel_id
gossip_getroute_request,,excluded_dir,num_excluded*bool

gossip_getroute_reply,3106
gossip_getroute_reply,,num_hops,u16
Expand Down
9 changes: 6 additions & 3 deletions gossipd/gossipd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1870,17 +1870,20 @@ static struct io_plan *getroute_req(struct io_conn *conn, struct daemon *daemon,
u8 *out;
struct route_hop *hops;
double fuzz;
struct short_channel_id *excluded;
bool *excluded_dir;

/* To choose between variations, we need to know how much we're
* sending (eliminates too-small channels, and also effects the fees
* we'll pay), how to trade off more locktime vs. more fees, and how
* much cltv we need a the final node to give exact values for each
* intermediate hop, as well as how much random fuzz to inject to
* avoid being too predictable. */
if (!fromwire_gossip_getroute_request(msg,
if (!fromwire_gossip_getroute_request(msg, msg,
&source, &destination,
&msatoshi, &riskfactor,
&final_cltv, &fuzz))
&final_cltv, &fuzz,
&excluded, &excluded_dir))
master_badmsg(WIRE_GOSSIP_GETROUTE_REQUEST, msg);

status_trace("Trying to find a route from %s to %s for %"PRIu64" msatoshi",
Expand All @@ -1890,7 +1893,7 @@ static struct io_plan *getroute_req(struct io_conn *conn, struct daemon *daemon,
/* routing.c does all the hard work; can return NULL. */
hops = get_route(tmpctx, daemon->rstate, &source, &destination,
msatoshi, riskfactor, final_cltv,
fuzz, siphash_seed());
fuzz, siphash_seed(), excluded, excluded_dir);

out = towire_gossip_getroute_reply(NULL, hops);
daemon_conn_send(daemon->master, take(out));
Expand Down
30 changes: 27 additions & 3 deletions gossipd/routing.c
Original file line number Diff line number Diff line change
Expand Up @@ -1496,20 +1496,44 @@ struct route_hop *get_route(const tal_t *ctx, struct routing_state *rstate,
const struct pubkey *destination,
const u64 msatoshi, double riskfactor,
u32 final_cltv,
double fuzz, const struct siphash_seed *base_seed)
double fuzz, const struct siphash_seed *base_seed,
const struct short_channel_id *excluded,
const bool *excluded_dir)
{
struct chan **route;
u64 total_amount;
unsigned int total_delay;
u64 fee;
struct route_hop *hops;
int i;
struct node *n;
u64 *saved_capacity;

assert(tal_count(excluded) == tal_count(excluded_dir));
saved_capacity = tal_arr(tmpctx, u64, tal_count(excluded));

/* Temporarily set excluded channels' capacity to zero. */
for (size_t i = 0; i < tal_count(excluded); i++) {
struct chan *chan = get_channel(rstate, &excluded[i]);
if (!chan)
continue;
saved_capacity[i]
= chan->half[excluded_dir[i]].htlc_maximum_msat;
chan->half[excluded_dir[i]].htlc_maximum_msat = 0;
}

route = find_route(ctx, rstate, source, destination, msatoshi,
riskfactor / BLOCKS_PER_YEAR / 10000,
fuzz, base_seed, &fee);

/* Now restore the capacity. */
for (size_t i = 0; i < tal_count(excluded); i++) {
struct chan *chan = get_channel(rstate, &excluded[i]);
if (!chan)
continue;
chan->half[excluded_dir[i]].htlc_maximum_msat
= saved_capacity[i];
}

if (!route) {
return NULL;
}
Expand All @@ -1521,7 +1545,7 @@ struct route_hop *get_route(const tal_t *ctx, struct routing_state *rstate,

/* Start at destination node. */
n = get_node(rstate, destination);
for (i = tal_count(route) - 1; i >= 0; i--) {
for (int i = tal_count(route) - 1; i >= 0; i--) {
const struct half_chan *c;
int idx = half_chan_to(n, route[i]);
c = &route[i]->half[idx];
Expand Down
4 changes: 3 additions & 1 deletion gossipd/routing.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,9 @@ struct route_hop *get_route(const tal_t *ctx, struct routing_state *rstate,
const u64 msatoshi, double riskfactor,
u32 final_cltv,
double fuzz,
const struct siphash_seed *base_seed);
const struct siphash_seed *base_seed,
const struct short_channel_id *excluded,
const bool *excluded_dir);
/* Disable channel(s) based on the given routing failure. */
void routing_failure(struct routing_state *rstate,
const struct pubkey *erring_node,
Expand Down
3 changes: 2 additions & 1 deletion lightningd/gossip_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,8 @@ static struct command_result *json_getroute(struct command *cmd,

u8 *req = towire_gossip_getroute_request(cmd, source, destination,
*msatoshi, *riskfactor * 1000,
*cltv, fuzz);
*cltv, fuzz,
NULL, NULL);
subd_req(ld->gossip, ld->gossip, req, -1, 0, json_getroute_reply, cmd);
return command_still_pending(cmd);
}
Expand Down
2 changes: 1 addition & 1 deletion lightningd/payalgo.c
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ static struct command_result *json_pay_try(struct pay *pay)
pay->msatoshi + overpayment,
pay->riskfactor,
pay->min_final_cltv_expiry,
&pay->fuzz);
&pay->fuzz, NULL, NULL);
subd_req(pay->try_parent, cmd->ld->gossip, req, -1, 0, json_pay_getroute_reply, pay);

return NULL;
Expand Down

0 comments on commit 599ec5e

Please sign in to comment.