mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
routing: remove possibility of overflow.
This check is expensive, so just restrict msatoshi going in, as well as turn off channels charging more than 24x fee. # 1M nodes: $ /gossipd/test/run-bench-find_route 1000000 1 > /tmp/out => 44164 msec Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
589cb673ce
commit
2824ff2b30
@ -6,7 +6,6 @@
|
|||||||
#include <ccan/endian/endian.h>
|
#include <ccan/endian/endian.h>
|
||||||
#include <ccan/structeq/structeq.h>
|
#include <ccan/structeq/structeq.h>
|
||||||
#include <ccan/tal/str/str.h>
|
#include <ccan/tal/str/str.h>
|
||||||
#include <common/overflows.h>
|
|
||||||
#include <common/pseudorand.h>
|
#include <common/pseudorand.h>
|
||||||
#include <common/status.h>
|
#include <common/status.h>
|
||||||
#include <common/type_to_string.h>
|
#include <common/type_to_string.h>
|
||||||
@ -21,6 +20,12 @@
|
|||||||
/* 365.25 * 24 * 60 / 10 */
|
/* 365.25 * 24 * 60 / 10 */
|
||||||
#define BLOCKS_PER_YEAR 52596
|
#define BLOCKS_PER_YEAR 52596
|
||||||
|
|
||||||
|
/* For overflow avoidance, we never deal with msatoshi > 40 bits. */
|
||||||
|
#define MAX_MSATOSHI (1ULL << 40)
|
||||||
|
|
||||||
|
/* Proportional fee must be less than 24 bits, so never overflows. */
|
||||||
|
#define MAX_PROPORTIONAL_FEE (1 << 24)
|
||||||
|
|
||||||
static struct node_map *empty_node_map(const tal_t *ctx)
|
static struct node_map *empty_node_map(const tal_t *ctx)
|
||||||
{
|
{
|
||||||
struct node_map *map = tal(ctx, struct node_map);
|
struct node_map *map = tal(ctx, struct node_map);
|
||||||
@ -250,8 +255,9 @@ static u64 connection_fee(const struct node_connection *c, u64 msatoshi)
|
|||||||
{
|
{
|
||||||
u64 fee;
|
u64 fee;
|
||||||
|
|
||||||
if (mul_overflows_u64(c->proportional_fee, msatoshi))
|
assert(msatoshi < MAX_MSATOSHI);
|
||||||
return INFINITE;
|
assert(c->proportional_fee < MAX_PROPORTIONAL_FEE);
|
||||||
|
|
||||||
fee = (c->proportional_fee * msatoshi) / 1000000;
|
fee = (c->proportional_fee * msatoshi) / 1000000;
|
||||||
/* This can't overflow: c->base_fee is a u32 */
|
/* This can't overflow: c->base_fee is a u32 */
|
||||||
return c->base_fee + fee;
|
return c->base_fee + fee;
|
||||||
@ -283,6 +289,15 @@ static void bfg_one_edge(struct node *node, size_t edgenum, double riskfactor)
|
|||||||
fee = connection_fee(c, node->bfg[h].total);
|
fee = connection_fee(c, node->bfg[h].total);
|
||||||
risk = node->bfg[h].risk + risk_fee(node->bfg[h].total + fee,
|
risk = node->bfg[h].risk + risk_fee(node->bfg[h].total + fee,
|
||||||
c->delay, riskfactor);
|
c->delay, riskfactor);
|
||||||
|
|
||||||
|
if (node->bfg[h].total + fee + risk >= MAX_MSATOSHI) {
|
||||||
|
SUPERVERBOSE("...extreme %"PRIu64
|
||||||
|
" + fee %"PRIu64
|
||||||
|
" + risk %"PRIu64" ignored",
|
||||||
|
node->bfg[h].total, fee, risk);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (node->bfg[h].total + fee + risk
|
if (node->bfg[h].total + fee + risk
|
||||||
< c->src->bfg[h+1].total + c->src->bfg[h+1].risk) {
|
< c->src->bfg[h+1].total + c->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,
|
||||||
@ -325,6 +340,12 @@ find_route(const tal_t *ctx, struct routing_state *rstate,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (msatoshi >= MAX_MSATOSHI) {
|
||||||
|
status_trace("find_route: can't route huge amount %"PRIu64,
|
||||||
|
msatoshi);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Reset all the information. */
|
/* Reset all the information. */
|
||||||
clear_bfg(rstate->nodes);
|
clear_bfg(rstate->nodes);
|
||||||
|
|
||||||
@ -639,6 +660,16 @@ void handle_channel_update(struct routing_state *rstate, const u8 *update)
|
|||||||
&short_channel_id),
|
&short_channel_id),
|
||||||
flags);
|
flags);
|
||||||
|
|
||||||
|
if (c->proportional_fee >= MAX_PROPORTIONAL_FEE) {
|
||||||
|
status_trace("Channel %s(%d) massive proportional fee %u:"
|
||||||
|
" disabling.",
|
||||||
|
type_to_string(trc, struct short_channel_id,
|
||||||
|
&short_channel_id),
|
||||||
|
flags,
|
||||||
|
fee_proportional_millionths);
|
||||||
|
c->active = false;
|
||||||
|
}
|
||||||
|
|
||||||
u8 *tag = tal_arr(tmpctx, u8, 0);
|
u8 *tag = tal_arr(tmpctx, u8, 0);
|
||||||
towire_short_channel_id(&tag, &short_channel_id);
|
towire_short_channel_id(&tag, &short_channel_id);
|
||||||
towire_u16(&tag, flags & 0x1);
|
towire_u16(&tag, flags & 0x1);
|
||||||
|
Loading…
Reference in New Issue
Block a user