mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 13:25:43 +01:00
gossipd: don't mark channels unroutable.
For transient failures, the pay plugin should simply exclude those from route considerations. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
018a3f1d58
commit
4eddf57fd9
@ -126,11 +126,6 @@ gossip_routing_failure,,failcode,u16
|
||||
gossip_routing_failure,,len,u16
|
||||
gossip_routing_failure,,channel_update,len*u8
|
||||
|
||||
# master->gossipd temporarily mark a channel unroutable
|
||||
# (used in case of unparseable onion reply)
|
||||
gossip_mark_channel_unroutable,3022
|
||||
gossip_mark_channel_unroutable,,channel,struct short_channel_id
|
||||
|
||||
# master -> gossipd: a potential funding outpoint was spent, please forget the eventual channel
|
||||
gossip_outpoint_spent,3024
|
||||
gossip_outpoint_spent,,short_channel_id,struct short_channel_id
|
||||
|
|
@ -2540,24 +2540,6 @@ static struct io_plan *handle_routing_failure(struct io_conn *conn,
|
||||
return daemon_conn_read_next(conn, daemon->master);
|
||||
}
|
||||
|
||||
/*~ This allows lightningd to explicitly mark a channel temporarily unroutable.
|
||||
* This is used when we get an unparsable error, and we don't know who to blame;
|
||||
* lightningd uses this to marking routes unroutable at random... */
|
||||
static struct io_plan *
|
||||
handle_mark_channel_unroutable(struct io_conn *conn,
|
||||
struct daemon *daemon,
|
||||
const u8 *msg)
|
||||
{
|
||||
struct short_channel_id channel;
|
||||
|
||||
if (!fromwire_gossip_mark_channel_unroutable(msg, &channel))
|
||||
master_badmsg(WIRE_GOSSIP_MARK_CHANNEL_UNROUTABLE, msg);
|
||||
|
||||
mark_channel_unroutable(daemon->rstate, &channel);
|
||||
|
||||
return daemon_conn_read_next(conn, daemon->master);
|
||||
}
|
||||
|
||||
/*~ This is where lightningd tells us that a channel's funding transaction has
|
||||
* been spent. */
|
||||
static struct io_plan *handle_outpoint_spent(struct io_conn *conn,
|
||||
@ -2642,9 +2624,6 @@ static struct io_plan *recv_req(struct io_conn *conn,
|
||||
case WIRE_GOSSIP_ROUTING_FAILURE:
|
||||
return handle_routing_failure(conn, daemon, msg);
|
||||
|
||||
case WIRE_GOSSIP_MARK_CHANNEL_UNROUTABLE:
|
||||
return handle_mark_channel_unroutable(conn, daemon, msg);
|
||||
|
||||
case WIRE_GOSSIP_OUTPOINT_SPENT:
|
||||
return handle_outpoint_spent(conn, daemon, msg);
|
||||
|
||||
|
@ -265,7 +265,6 @@ static void init_half_chan(struct routing_state *rstate,
|
||||
struct half_chan *c = &chan->half[channel_idx];
|
||||
|
||||
c->channel_update = NULL;
|
||||
c->unroutable_until = 0;
|
||||
|
||||
/* Set the channel direction */
|
||||
c->channel_flags = channel_idx;
|
||||
@ -438,11 +437,10 @@ static void bfg_one_edge(struct node *node,
|
||||
}
|
||||
|
||||
/* Determine if the given half_chan is routable */
|
||||
static bool hc_is_routable(const struct chan *chan, int idx, time_t now)
|
||||
static bool hc_is_routable(const struct chan *chan, int idx)
|
||||
{
|
||||
return !chan->local_disabled
|
||||
&& is_halfchan_enabled(&chan->half[idx])
|
||||
&& chan->half[idx].unroutable_until < now;
|
||||
&& is_halfchan_enabled(&chan->half[idx]);
|
||||
}
|
||||
|
||||
/* riskfactor is already scaled to per-block amount */
|
||||
@ -458,10 +456,6 @@ find_route(const tal_t *ctx, struct routing_state *rstate,
|
||||
struct node *n, *src, *dst;
|
||||
struct node_map_iter it;
|
||||
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. */
|
||||
@ -518,7 +512,7 @@ find_route(const tal_t *ctx, struct routing_state *rstate,
|
||||
&n->id),
|
||||
i, num_edges);
|
||||
|
||||
if (!hc_is_routable(chan, idx, now)) {
|
||||
if (!hc_is_routable(chan, idx)) {
|
||||
SUPERVERBOSE("...unroutable (local_disabled = %i, is_halfchan_enabled = %i, unroutable_until = %i",
|
||||
chan->local_disabled,
|
||||
is_halfchan_enabled(&chan->half[idx]),
|
||||
@ -1040,9 +1034,6 @@ static void set_connection_values(struct chan *chan,
|
||||
c->last_timestamp = timestamp;
|
||||
assert((c->channel_flags & ROUTING_FLAGS_DIRECTION) == idx);
|
||||
|
||||
/* If it was temporarily unroutable, re-enable */
|
||||
c->unroutable_until = 0;
|
||||
|
||||
SUPERVERBOSE("Channel %s/%d was updated.",
|
||||
type_to_string(tmpctx, struct short_channel_id, &chan->scid),
|
||||
idx);
|
||||
@ -1583,17 +1574,12 @@ static void routing_failure_channel_out(const tal_t *disposal_context,
|
||||
struct chan *chan,
|
||||
time_t now)
|
||||
{
|
||||
struct half_chan *hc = half_chan_from(node, chan);
|
||||
|
||||
/* BOLT #4:
|
||||
*
|
||||
* - if the PERM bit is NOT set:
|
||||
* - SHOULD restore the channels as it receives new `channel_update`s.
|
||||
*/
|
||||
if (!(failcode & PERM))
|
||||
/* Prevent it for 20 seconds. */
|
||||
hc->unroutable_until = now + 20;
|
||||
else
|
||||
if (failcode & PERM)
|
||||
/* Set it up to be pruned. */
|
||||
tal_steal(disposal_context, chan);
|
||||
}
|
||||
@ -1692,27 +1678,6 @@ void routing_failure(struct routing_state *rstate,
|
||||
}
|
||||
}
|
||||
|
||||
void mark_channel_unroutable(struct routing_state *rstate,
|
||||
const struct short_channel_id *channel)
|
||||
{
|
||||
struct chan *chan;
|
||||
time_t now = time_now().ts.tv_sec;
|
||||
const char *scid = type_to_string(tmpctx, struct short_channel_id,
|
||||
channel);
|
||||
|
||||
status_trace("Received mark_channel_unroutable channel %s",
|
||||
scid);
|
||||
|
||||
chan = get_channel(rstate, channel);
|
||||
if (!chan) {
|
||||
status_unusual("mark_channel_unroutable: "
|
||||
"channel %s not in routemap",
|
||||
scid);
|
||||
return;
|
||||
}
|
||||
chan->half[0].unroutable_until = now + 20;
|
||||
chan->half[1].unroutable_until = now + 20;
|
||||
}
|
||||
|
||||
void route_prune(struct routing_state *rstate)
|
||||
{
|
||||
|
@ -39,10 +39,6 @@ struct half_chan {
|
||||
/* Flags as specified by the `channel_update`s, indicates
|
||||
* optional fields. */
|
||||
u8 message_flags;
|
||||
|
||||
/* If greater than current time, this connection should not
|
||||
* be used for routing. */
|
||||
time_t unroutable_until;
|
||||
};
|
||||
|
||||
struct chan {
|
||||
@ -277,9 +273,6 @@ void routing_failure(struct routing_state *rstate,
|
||||
const struct short_channel_id *erring_channel,
|
||||
enum onion_type failcode,
|
||||
const u8 *channel_update);
|
||||
/* Disable specific channel from routing. */
|
||||
void mark_channel_unroutable(struct routing_state *rstate,
|
||||
const struct short_channel_id *channel);
|
||||
|
||||
void route_prune(struct routing_state *rstate);
|
||||
|
||||
|
@ -112,7 +112,6 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
|
||||
case WIRE_GOSSIP_GET_TXOUT_REPLY:
|
||||
case WIRE_GOSSIP_OUTPOINT_SPENT:
|
||||
case WIRE_GOSSIP_ROUTING_FAILURE:
|
||||
case WIRE_GOSSIP_MARK_CHANNEL_UNROUTABLE:
|
||||
case WIRE_GOSSIP_QUERY_SCIDS:
|
||||
case WIRE_GOSSIP_QUERY_CHANNEL_RANGE:
|
||||
case WIRE_GOSSIP_SEND_TIMESTAMP_FILTER:
|
||||
|
@ -394,31 +394,6 @@ remote_routing_failure(const tal_t *ctx,
|
||||
return routing_failure;
|
||||
}
|
||||
|
||||
static void random_mark_channel_unroutable(struct log *log,
|
||||
struct subd *gossip,
|
||||
struct short_channel_id *route_channels)
|
||||
{
|
||||
size_t num_channels = tal_count(route_channels);
|
||||
size_t i;
|
||||
const struct short_channel_id *channel;
|
||||
u8 *msg;
|
||||
assert(num_channels != 0);
|
||||
|
||||
/* Select one channel by random. */
|
||||
randombytes_buf(&i, sizeof(i));
|
||||
i = i % num_channels;
|
||||
channel = &route_channels[i];
|
||||
|
||||
log_debug(log,
|
||||
"Disable randomly %dth channel (%s) along route "
|
||||
"(guessing due to bad reply)",
|
||||
(int) i,
|
||||
type_to_string(tmpctx, struct short_channel_id,
|
||||
channel));
|
||||
msg = towire_gossip_mark_channel_unroutable(tmpctx, channel);
|
||||
subd_send_msg(gossip, msg);
|
||||
}
|
||||
|
||||
static void report_routing_failure(struct log *log,
|
||||
struct subd *gossip,
|
||||
struct routing_failure *fail)
|
||||
@ -535,10 +510,6 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
|
||||
tal_hex(tmpctx, hout->failuremsg));
|
||||
/* Cannot report failure. */
|
||||
fail = NULL;
|
||||
/* Select a channel to mark unroutable by random */
|
||||
random_mark_channel_unroutable(hout->key.channel->log,
|
||||
ld->gossip,
|
||||
payment->route_channels);
|
||||
/* Can now retry; we selected a channel to mark
|
||||
* unroutable by random */
|
||||
retry_plausible = true;
|
||||
|
Loading…
Reference in New Issue
Block a user