Browse Source

routing: Skip channels that don't have sufficient capacity

We know the total channel capacity after checking for its existence on-chain, so
we can actually make use of that information to discard channels that don't have
a sufficient capacity anyway, reducing the number of failed attempts.
ppa-0.6.1
Christian Decker 7 years ago
parent
commit
14000a22bc
  1. 18
      gossipd/routing.c
  2. 23
      gossipd/test/run-find_route-specific.c
  3. 2
      gossipd/test/run-find_route.c

18
gossipd/routing.c

@ -389,15 +389,21 @@ static void bfg_one_edge(struct node *node,
/* FIXME: Bias against smaller channels. */ /* FIXME: Bias against smaller channels. */
u64 fee; u64 fee;
u64 risk; u64 risk;
u64 requiredcap;
if (node->bfg[h].total == INFINITE) if (node->bfg[h].total == INFINITE)
continue; continue;
fee = connection_fee(c, node->bfg[h].total) * fee_scale; fee = connection_fee(c, node->bfg[h].total) * fee_scale;
risk = node->bfg[h].risk + risk_fee(node->bfg[h].total + fee, requiredcap = node->bfg[h].total + fee;
c->delay, riskfactor); risk = node->bfg[h].risk +
risk_fee(requiredcap, c->delay, riskfactor);
if (node->bfg[h].total + fee + risk >= MAX_MSATOSHI) { if (requiredcap > chan->satoshis * 1000) {
/* Skip this edge if the channel has insufficient
* capacity to route the required amount */
continue;
} else if (requiredcap + risk >= MAX_MSATOSHI) {
SUPERVERBOSE("...extreme %"PRIu64 SUPERVERBOSE("...extreme %"PRIu64
" + fee %"PRIu64 " + fee %"PRIu64
" + risk %"PRIu64" ignored", " + risk %"PRIu64" ignored",
@ -407,13 +413,13 @@ static void bfg_one_edge(struct node *node,
/* nodes[0] is src for connections[0] */ /* nodes[0] is src for connections[0] */
src = chan->nodes[idx]; src = chan->nodes[idx];
if (node->bfg[h].total + fee + risk if (requiredcap + risk <
< src->bfg[h+1].total + src->bfg[h+1].risk) { src->bfg[h + 1].total + src->bfg[h + 1].risk) {
SUPERVERBOSE("...%s can reach here in hoplen %zu total %"PRIu64, SUPERVERBOSE("...%s can reach here in hoplen %zu total %"PRIu64,
type_to_string(trc, struct pubkey, type_to_string(trc, struct pubkey,
&src->id), &src->id),
h, node->bfg[h].total + fee); h, node->bfg[h].total + fee);
src->bfg[h+1].total = node->bfg[h].total + fee; src->bfg[h+1].total = requiredcap;
src->bfg[h+1].risk = risk; src->bfg[h+1].risk = risk;
src->bfg[h+1].prev = chan; src->bfg[h+1].prev = chan;
} }

23
gossipd/test/run-find_route-specific.c

@ -110,7 +110,8 @@ static struct half_chan *
get_or_make_connection(struct routing_state *rstate, get_or_make_connection(struct routing_state *rstate,
const struct pubkey *from_id, const struct pubkey *from_id,
const struct pubkey *to_id, const struct pubkey *to_id,
const char *shortid) const char *shortid,
const u64 satoshis)
{ {
struct short_channel_id scid; struct short_channel_id scid;
struct chan *chan; struct chan *chan;
@ -123,6 +124,7 @@ get_or_make_connection(struct routing_state *rstate,
/* Make sure it's seen as initialized (update non-NULL). */ /* Make sure it's seen as initialized (update non-NULL). */
chan->half[pubkey_idx(from_id, to_id)].channel_update = (void *)chan; chan->half[pubkey_idx(from_id, to_id)].channel_update = (void *)chan;
chan->satoshis = satoshis;
return &chan->half[pubkey_idx(from_id, to_id)]; return &chan->half[pubkey_idx(from_id, to_id)];
} }
@ -169,7 +171,8 @@ int main(void)
rstate = new_routing_state(tmpctx, &zerohash, &a, 0); rstate = new_routing_state(tmpctx, &zerohash, &a, 0);
/* [{'active': True, 'short_id': '6990:2:1/1', 'fee_per_kw': 10, 'delay': 5, 'flags': 1, 'destination': '0230ad0e74ea03976b28fda587bb75bdd357a1938af4424156a18265167f5e40ae', 'source': '02ea622d5c8d6143f15ed3ce1d501dd0d3d09d3b1c83a44d0034949f8a9ab60f06', 'last_update': 1504064344}, */ /* [{'active': True, 'short_id': '6990:2:1/1', 'fee_per_kw': 10, 'delay': 5, 'flags': 1, 'destination': '0230ad0e74ea03976b28fda587bb75bdd357a1938af4424156a18265167f5e40ae', 'source': '02ea622d5c8d6143f15ed3ce1d501dd0d3d09d3b1c83a44d0034949f8a9ab60f06', 'last_update': 1504064344}, */
nc = get_or_make_connection(rstate, &c, &b, "6990:2:1");
nc = get_or_make_connection(rstate, &c, &b, "6990:2:1", 1000);
nc->base_fee = 0; nc->base_fee = 0;
nc->proportional_fee = 10; nc->proportional_fee = 10;
nc->delay = 5; nc->delay = 5;
@ -177,7 +180,7 @@ int main(void)
nc->last_timestamp = 1504064344; nc->last_timestamp = 1504064344;
/* {'active': True, 'short_id': '6989:2:1/0', 'fee_per_kw': 10, 'delay': 5, 'flags': 0, 'destination': '03c173897878996287a8100469f954dd820fcd8941daed91c327f168f3329be0bf', 'source': '0230ad0e74ea03976b28fda587bb75bdd357a1938af4424156a18265167f5e40ae', 'last_update': 1504064344}, */ /* {'active': True, 'short_id': '6989:2:1/0', 'fee_per_kw': 10, 'delay': 5, 'flags': 0, 'destination': '03c173897878996287a8100469f954dd820fcd8941daed91c327f168f3329be0bf', 'source': '0230ad0e74ea03976b28fda587bb75bdd357a1938af4424156a18265167f5e40ae', 'last_update': 1504064344}, */
nc = get_or_make_connection(rstate, &b, &a, "6989:2:1"); nc = get_or_make_connection(rstate, &b, &a, "6989:2:1", 1000);
nc->base_fee = 0; nc->base_fee = 0;
nc->proportional_fee = 10; nc->proportional_fee = 10;
nc->delay = 5; nc->delay = 5;
@ -185,7 +188,7 @@ int main(void)
nc->last_timestamp = 1504064344; nc->last_timestamp = 1504064344;
/* {'active': True, 'short_id': '6990:2:1/0', 'fee_per_kw': 10, 'delay': 5, 'flags': 0, 'destination': '02ea622d5c8d6143f15ed3ce1d501dd0d3d09d3b1c83a44d0034949f8a9ab60f06', 'source': '0230ad0e74ea03976b28fda587bb75bdd357a1938af4424156a18265167f5e40ae', 'last_update': 1504064344}, */ /* {'active': True, 'short_id': '6990:2:1/0', 'fee_per_kw': 10, 'delay': 5, 'flags': 0, 'destination': '02ea622d5c8d6143f15ed3ce1d501dd0d3d09d3b1c83a44d0034949f8a9ab60f06', 'source': '0230ad0e74ea03976b28fda587bb75bdd357a1938af4424156a18265167f5e40ae', 'last_update': 1504064344}, */
nc = get_or_make_connection(rstate, &b, &c, "6990:2:1"); nc = get_or_make_connection(rstate, &b, &c, "6990:2:1", 1000);
nc->base_fee = 0; nc->base_fee = 0;
nc->proportional_fee = 10; nc->proportional_fee = 10;
nc->delay = 5; nc->delay = 5;
@ -193,7 +196,7 @@ int main(void)
nc->last_timestamp = 1504064344; nc->last_timestamp = 1504064344;
/* {'active': True, 'short_id': '6989:2:1/1', 'fee_per_kw': 10, 'delay': 5, 'flags': 1, 'destination': '0230ad0e74ea03976b28fda587bb75bdd357a1938af4424156a18265167f5e40ae', 'source': '03c173897878996287a8100469f954dd820fcd8941daed91c327f168f3329be0bf', 'last_update': 1504064344}]} */ /* {'active': True, 'short_id': '6989:2:1/1', 'fee_per_kw': 10, 'delay': 5, 'flags': 1, 'destination': '0230ad0e74ea03976b28fda587bb75bdd357a1938af4424156a18265167f5e40ae', 'source': '03c173897878996287a8100469f954dd820fcd8941daed91c327f168f3329be0bf', 'last_update': 1504064344}]} */
nc = get_or_make_connection(rstate, &a, &b, "6989:2:1"); nc = get_or_make_connection(rstate, &a, &b, "6989:2:1", 1000);
nc->base_fee = 0; nc->base_fee = 0;
nc->proportional_fee = 10; nc->proportional_fee = 10;
nc->delay = 5; nc->delay = 5;
@ -206,6 +209,16 @@ int main(void)
assert(channel_is_between(route[0], &a, &b)); assert(channel_is_between(route[0], &a, &b));
assert(channel_is_between(route[1], &b, &c)); assert(channel_is_between(route[1], &b, &c));
/* We should not be able to find a route that exceeds our own capacity */
route = find_route(tmpctx, rstate, &a, &c, 1000001, riskfactor, 0.0, NULL, &fee);
assert(!route);
/* Now test with a query that exceeds the channel capacity after adding
* some fees */
route = find_route(tmpctx, rstate, &a, &c, 999999, riskfactor, 0.0, NULL, &fee);
assert(!route);
tal_free(tmpctx); tal_free(tmpctx);
secp256k1_context_destroy(secp256k1_ctx); secp256k1_context_destroy(secp256k1_ctx);
return 0; return 0;

2
gossipd/test/run-find_route.c

@ -121,6 +121,8 @@ static void add_connection(struct routing_state *rstate,
if (!chan) if (!chan)
chan = new_chan(rstate, &scid, from, to); chan = new_chan(rstate, &scid, from, to);
chan->satoshis = 100000;
c = &chan->half[pubkey_idx(from, to)]; c = &chan->half[pubkey_idx(from, to)];
/* Make sure it's seen as initialized (update non-NULL). */ /* Make sure it's seen as initialized (update non-NULL). */
c->channel_update = (void *)c; c->channel_update = (void *)c;

Loading…
Cancel
Save