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.
This commit is contained in:
Christian Decker 2018-07-30 15:31:45 +02:00
parent 8a34933c1a
commit 14000a22bc
3 changed files with 32 additions and 11 deletions

View File

@ -389,15 +389,21 @@ static void bfg_one_edge(struct node *node,
/* FIXME: Bias against smaller channels. */
u64 fee;
u64 risk;
u64 requiredcap;
if (node->bfg[h].total == INFINITE)
continue;
fee = connection_fee(c, node->bfg[h].total) * fee_scale;
risk = node->bfg[h].risk + risk_fee(node->bfg[h].total + fee,
c->delay, riskfactor);
requiredcap = node->bfg[h].total + fee;
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
" + fee %"PRIu64
" + risk %"PRIu64" ignored",
@ -407,13 +413,13 @@ static void bfg_one_edge(struct node *node,
/* nodes[0] is src for connections[0] */
src = chan->nodes[idx];
if (node->bfg[h].total + fee + risk
< src->bfg[h+1].total + src->bfg[h+1].risk) {
if (requiredcap + risk <
src->bfg[h + 1].total + src->bfg[h + 1].risk) {
SUPERVERBOSE("...%s can reach here in hoplen %zu total %"PRIu64,
type_to_string(trc, struct pubkey,
&src->id),
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].prev = chan;
}

View File

@ -110,7 +110,8 @@ static struct half_chan *
get_or_make_connection(struct routing_state *rstate,
const struct pubkey *from_id,
const struct pubkey *to_id,
const char *shortid)
const char *shortid,
const u64 satoshis)
{
struct short_channel_id scid;
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). */
chan->half[pubkey_idx(from_id, to_id)].channel_update = (void *)chan;
chan->satoshis = satoshis;
return &chan->half[pubkey_idx(from_id, to_id)];
}
@ -169,7 +171,8 @@ int main(void)
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}, */
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->proportional_fee = 10;
nc->delay = 5;
@ -177,7 +180,7 @@ int main(void)
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}, */
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->proportional_fee = 10;
nc->delay = 5;
@ -185,7 +188,7 @@ int main(void)
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}, */
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->proportional_fee = 10;
nc->delay = 5;
@ -193,7 +196,7 @@ int main(void)
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}]} */
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->proportional_fee = 10;
nc->delay = 5;
@ -206,6 +209,16 @@ int main(void)
assert(channel_is_between(route[0], &a, &b));
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);
secp256k1_context_destroy(secp256k1_ctx);
return 0;

View File

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