Browse Source

routing: Only mark channel unroutable for a short time.

Fixes: #867
ppa-0.6.1
ZmnSCPxj 7 years ago
committed by Christian Decker
parent
commit
a57a2dcb86
  1. 26
      gossipd/routing.c
  2. 4
      gossipd/routing.h

26
gossipd/routing.c

@ -7,6 +7,7 @@
#include <ccan/endian/endian.h>
#include <ccan/structeq/structeq.h>
#include <ccan/tal/str/str.h>
#include <ccan/time/time.h>
#include <common/features.h>
#include <common/pseudorand.h>
#include <common/status.h>
@ -226,6 +227,7 @@ get_or_make_connection(struct routing_state *rstate,
nc->dst = to;
nc->channel_announcement = NULL;
nc->channel_update = NULL;
nc->unroutable_until = 0;
/* Hook it into in/out arrays. */
i = tal_count(to->in);
@ -342,9 +344,9 @@ static void bfg_one_edge(struct node *node, size_t edgenum, double riskfactor)
}
/* Determine if the given node_connection is routable */
static bool nc_is_routable(const struct node_connection *nc)
static bool nc_is_routable(const struct node_connection *nc, time_t now)
{
return nc->active;
return nc->active && nc->unroutable_until < now;
}
/* riskfactor is already scaled to per-block amount */
@ -357,6 +359,10 @@ find_route(const tal_t *ctx, struct routing_state *rstate,
struct node_map_iter it;
struct node_connection *first_conn;
int runs, i, best;
/* Call time_now() once at the start, so that our tight loop
* does not keep calling into operating system for the
* current time */
time_t now = time_now().ts.tv_sec;
/* Note: we map backwards, since we know the amount of satoshi we want
* at the end, and need to derive how much we need to send. */
@ -403,7 +409,7 @@ find_route(const tal_t *ctx, struct routing_state *rstate,
type_to_string(trc, struct pubkey,
&n->id),
i, num_edges);
if (!nc_is_routable(n->in[i])) {
if (!nc_is_routable(n->in[i], now)) {
SUPERVERBOSE("...unroutable");
continue;
}
@ -830,6 +836,7 @@ void handle_channel_update(struct routing_state *rstate, const u8 *update)
c->base_fee = fee_base_msat;
c->proportional_fee = fee_proportional_millionths;
c->active = (flags & ROUTING_FLAGS_DISABLED) == 0;
c->unroutable_until = 0;
status_trace("Channel %s(%d) was updated.",
type_to_string(trc, struct short_channel_id,
&short_channel_id),
@ -1047,7 +1054,8 @@ get_out_node_connection_of(struct routing_state *rstate,
*/
static void routing_failure_on_nc(struct routing_state *rstate,
enum onion_type failcode,
struct node_connection *nc)
struct node_connection *nc,
time_t now)
{
/* BOLT #4:
*
@ -1055,7 +1063,8 @@ static void routing_failure_on_nc(struct routing_state *rstate,
* - SHOULD restore the channels as it receives new `channel_update`s.
*/
if (!(failcode & PERM))
nc->active = false;
/* Prevent it for 20 seconds. */
nc->unroutable_until = now + 20;
else
delete_connection(rstate, nc);
}
@ -1071,6 +1080,7 @@ void routing_failure(struct routing_state *rstate,
struct node_connection *nc;
int i;
enum wire_type t;
time_t now = time_now().ts.tv_sec;
status_trace("Received routing failure 0x%04x (%s), "
"erring node %s, "
@ -1099,13 +1109,13 @@ void routing_failure(struct routing_state *rstate,
*/
if (failcode & NODE) {
for (i = 0; i < tal_count(node->in); ++i)
routing_failure_on_nc(rstate, failcode, node->in[i]);
routing_failure_on_nc(rstate, failcode, node->in[i], now);
for (i = 0; i < tal_count(node->out); ++i)
routing_failure_on_nc(rstate, failcode, node->out[i]);
routing_failure_on_nc(rstate, failcode, node->out[i], now);
} else {
nc = get_out_node_connection_of(rstate, node, scid);
if (nc)
routing_failure_on_nc(rstate, failcode, nc);
routing_failure_on_nc(rstate, failcode, nc, now);
else
status_trace("UNUSUAL routing_failure: "
"Channel %s not an out channel "

4
gossipd/routing.h

@ -38,6 +38,10 @@ struct node_connection {
/* Cached `channel_announcement` and `channel_update` we might forward to new peers*/
u8 *channel_announcement;
u8 *channel_update;
/* If greater than current time, this connection should not
* be used for routing. */
time_t unroutable_until;
};
struct node {

Loading…
Cancel
Save