gossipd: add flag for locally disabling channel.

We used to just manually set ROUTING_FLAGS_DISABLED, but that means we
then suppressed the real channel_update because we thought it was a
duplicate!

So use a local flag: set it for the channel when the peer disconnects,
and clear it when channeld sends a local update.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2018-07-27 06:51:37 +09:30 committed by Christian Decker
parent 93cf28553d
commit 3c66d5fa03
6 changed files with 21 additions and 9 deletions

View file

@ -1188,6 +1188,8 @@ static void handle_local_channel_update(struct peer *peer, const u8 *msg)
return; return;
} }
/* channeld has reconnected, remove local disable. */
chan->local_disabled = false;
queue_local_update(peer->daemon, local_update); queue_local_update(peer->daemon, local_update);
} }
@ -1398,6 +1400,7 @@ static void append_half_channel(struct gossip_getchannels_entry **entries,
e->destination = chan->nodes[!idx]->id; e->destination = chan->nodes[!idx]->id;
e->satoshis = chan->satoshis; e->satoshis = chan->satoshis;
e->flags = c->flags; e->flags = c->flags;
e->local_disabled = chan->local_disabled;
e->public = is_chan_public(chan); e->public = is_chan_public(chan);
e->short_channel_id = chan->scid; e->short_channel_id = chan->scid;
e->last_update_timestamp = c->last_timestamp; e->last_update_timestamp = c->last_timestamp;
@ -1823,9 +1826,9 @@ static void gossip_disable_outgoing_halfchan(struct daemon *daemon,
* *
* Disables both directions of a local channel as a result of a close or lost * Disables both directions of a local channel as a result of a close or lost
* connection. A disabling `channel_update` will be queued for the outgoing * connection. A disabling `channel_update` will be queued for the outgoing
* direction as well. We can't do that for the incoming direction, so we just * direction as well, but that will be a little delayed. We can't do that for
* locally flip the flag, and the other endpoint should take care of publicly * the incoming direction, so we set local_disabled and the other endpoint
* disabling it with a `channel_update`. * should take care of publicly disabling it with a `channel_update`.
* *
* It is important to disable the incoming edge as well since we might otherwise * It is important to disable the incoming edge as well since we might otherwise
* return that edge as a `contact_point` as part of an invoice. * return that edge as a `contact_point` as part of an invoice.
@ -1838,8 +1841,7 @@ static void gossip_disable_local_channel(struct daemon *daemon,
assert(pubkey_eq(&rstate->local_id, &chan->nodes[0]->id) || assert(pubkey_eq(&rstate->local_id, &chan->nodes[0]->id) ||
pubkey_eq(&rstate->local_id, &chan->nodes[1]->id)); pubkey_eq(&rstate->local_id, &chan->nodes[1]->id));
chan->half[0].flags |= ROUTING_FLAGS_DISABLED; chan->local_disabled = true;
chan->half[1].flags |= ROUTING_FLAGS_DISABLED;
gossip_disable_outgoing_halfchan(daemon, chan); gossip_disable_outgoing_halfchan(daemon, chan);
} }

View file

@ -307,6 +307,7 @@ struct chan *new_chan(struct routing_state *rstate,
chan->channel_announce = NULL; chan->channel_announce = NULL;
chan->channel_announcement_index = 0; chan->channel_announcement_index = 0;
chan->satoshis = 0; chan->satoshis = 0;
chan->local_disabled = false;
n = tal_count(n2->chans); n = tal_count(n2->chans);
tal_resize(&n2->chans, n+1); tal_resize(&n2->chans, n+1);
@ -420,9 +421,11 @@ static void bfg_one_edge(struct node *node,
} }
/* Determine if the given half_chan is routable */ /* Determine if the given half_chan is routable */
static bool hc_is_routable(const struct half_chan *hc, time_t now) static bool hc_is_routable(const struct chan *chan, int idx, time_t now)
{ {
return is_halfchan_enabled(hc) && hc->unroutable_until < now; return !chan->local_disabled
&& is_halfchan_enabled(&chan->half[idx])
&& chan->half[idx].unroutable_until < now;
} }
/* riskfactor is already scaled to per-block amount */ /* riskfactor is already scaled to per-block amount */
@ -491,7 +494,7 @@ find_route(const tal_t *ctx, struct routing_state *rstate,
&n->id), &n->id),
i, num_edges); i, num_edges);
if (!hc_is_routable(&chan->half[idx], now)) { if (!hc_is_routable(chan, idx, now)) {
SUPERVERBOSE("...unroutable"); SUPERVERBOSE("...unroutable");
continue; continue;
} }

View file

@ -55,6 +55,9 @@ struct chan {
/* Index in broadcast map, if public (otherwise 0) */ /* Index in broadcast map, if public (otherwise 0) */
u64 channel_announcement_index; u64 channel_announcement_index;
/* Disabled locally (due to peer disconnect) */
bool local_disabled;
u64 satoshis; u64 satoshis;
}; };

View file

@ -359,7 +359,8 @@ static void json_listchannels_reply(struct subd *gossip UNUSED, const u8 *reply,
json_add_u64(response, "satoshis", entries[i].satoshis); json_add_u64(response, "satoshis", entries[i].satoshis);
json_add_num(response, "flags", entries[i].flags); json_add_num(response, "flags", entries[i].flags);
json_add_bool(response, "active", json_add_bool(response, "active",
!(entries[i].flags & ROUTING_FLAGS_DISABLED)); !(entries[i].flags & ROUTING_FLAGS_DISABLED)
&& !entries[i].local_disabled);
json_add_num(response, "last_update", json_add_num(response, "last_update",
entries[i].last_update_timestamp); entries[i].last_update_timestamp);
json_add_num(response, "base_fee_millisatoshi", json_add_num(response, "base_fee_millisatoshi",

View file

@ -85,6 +85,7 @@ void fromwire_gossip_getchannels_entry(const u8 **pptr, size_t *max,
entry->satoshis = fromwire_u64(pptr, max); entry->satoshis = fromwire_u64(pptr, max);
entry->flags = fromwire_u16(pptr, max); entry->flags = fromwire_u16(pptr, max);
entry->public = fromwire_bool(pptr, max); entry->public = fromwire_bool(pptr, max);
entry->local_disabled = fromwire_bool(pptr, max);
entry->last_update_timestamp = fromwire_u32(pptr, max); entry->last_update_timestamp = fromwire_u32(pptr, max);
entry->base_fee_msat = fromwire_u32(pptr, max); entry->base_fee_msat = fromwire_u32(pptr, max);
entry->fee_per_millionth = fromwire_u32(pptr, max); entry->fee_per_millionth = fromwire_u32(pptr, max);
@ -100,6 +101,7 @@ void towire_gossip_getchannels_entry(u8 **pptr,
towire_u64(pptr, entry->satoshis); towire_u64(pptr, entry->satoshis);
towire_u16(pptr, entry->flags); towire_u16(pptr, entry->flags);
towire_bool(pptr, entry->public); towire_bool(pptr, entry->public);
towire_bool(pptr, entry->local_disabled);
towire_u32(pptr, entry->last_update_timestamp); towire_u32(pptr, entry->last_update_timestamp);
towire_u32(pptr, entry->base_fee_msat); towire_u32(pptr, entry->base_fee_msat);
towire_u32(pptr, entry->fee_per_millionth); towire_u32(pptr, entry->fee_per_millionth);

View file

@ -24,6 +24,7 @@ struct gossip_getchannels_entry {
struct short_channel_id short_channel_id; struct short_channel_id short_channel_id;
u16 flags; u16 flags;
bool public; bool public;
bool local_disabled;
u32 last_update_timestamp; u32 last_update_timestamp;
u32 delay; u32 delay;
u32 base_fee_msat; u32 base_fee_msat;