diff --git a/common/gossip_store.h b/common/gossip_store.h index ef6394dd7..f1a8525df 100644 --- a/common/gossip_store.h +++ b/common/gossip_store.h @@ -15,7 +15,7 @@ struct gossip_rcvd_filter; /* First byte of file is the version. * * Top three bits mean incompatible change. - * As of this writing, major == 0, minor == 11. + * As of this writing, major == 0, minor == 13. */ #define GOSSIP_STORE_MAJOR_VERSION_MASK 0xE0 #define GOSSIP_STORE_MINOR_VERSION_MASK 0x1F diff --git a/devtools/dump-gossipstore.c b/devtools/dump-gossipstore.c index 3df77a926..09c6f3a1e 100644 --- a/devtools/dump-gossipstore.c +++ b/devtools/dump-gossipstore.c @@ -113,12 +113,12 @@ int main(int argc, char *argv[]) printf("t=%u node_announcement: %s\n", be32_to_cpu(hdr.timestamp), tal_hex(msg, msg)); - } else if (fromwire_gossip_store_private_channel(msg, msg, &sat, + } else if (fromwire_gossip_store_private_channel_obs(msg, msg, &sat, &inner)) { printf("private channel_announcement: %s %s\n", type_to_string(tmpctx, struct amount_sat, &sat), tal_hex(msg, inner)); - } else if (fromwire_gossip_store_private_update(msg, msg, + } else if (fromwire_gossip_store_private_update_obs(msg, msg, &inner)) { printf("private channel_update: %s\n", tal_hex(msg, inner)); diff --git a/gossipd/gossip_generation.c b/gossipd/gossip_generation.c index 84532bc19..29787231e 100644 --- a/gossipd/gossip_generation.c +++ b/gossipd/gossip_generation.c @@ -720,7 +720,7 @@ static u8 *prev_update(const tal_t *ctx, chan->half[direction].bcast.index)); /* If it's a private update, unwrap */ - if (!fromwire_gossip_store_private_update(ctx, prev, &prev)) + if (!fromwire_gossip_store_private_update_obs(ctx, prev, &prev)) tal_steal(ctx, prev); return prev; } diff --git a/gossipd/gossip_store.c b/gossipd/gossip_store.c index 5130cc6bf..ed33de947 100644 --- a/gossipd/gossip_store.c +++ b/gossipd/gossip_store.c @@ -17,8 +17,8 @@ #include #define GOSSIP_STORE_TEMP_FILENAME "gossip_store.tmp" -/* We write it as major version 0, minor version 12 */ -#define GOSSIP_STORE_VER ((0 << 5) | 12) +/* We write it as major version 0, minor version 13 */ +#define GOSSIP_STORE_VER ((0 << 5) | 13) struct gossip_store { /* This is false when we're loading */ @@ -107,25 +107,85 @@ static bool append_msg(int fd, const u8 *msg, u32 timestamp, * v10 removed any remaining non-htlc-max channel_update. * v11 mandated channel_updates use the htlc_maximum_msat field * v12 added the zombie flag for expired channel updates + * v13 removed private gossip entries */ static bool can_upgrade(u8 oldversion) { - return oldversion >= 9 && oldversion <= 11; + return oldversion >= 9 && oldversion <= 12; +} + +/* On upgrade, do best effort on private channels: hand them to + * lightningd as if we just receive them, before removing from the + * store */ +static void give_lightningd_canned_private_update(struct routing_state *rstate, + const u8 *msg) +{ + u8 *update; + secp256k1_ecdsa_signature signature; + struct bitcoin_blkid chain_hash; + struct short_channel_id short_channel_id; + u32 timestamp; + u8 message_flags, channel_flags; + u16 cltv_expiry_delta; + struct amount_msat htlc_minimum_msat, htlc_maximum_msat; + u32 fee_base_msat, fee_proportional_millionths; + + if (!fromwire_gossip_store_private_update_obs(tmpctx, msg, &update)) { + status_broken("Could not parse private update %s", + tal_hex(tmpctx, msg)); + return; + } + if (!fromwire_channel_update(update, + &signature, + &chain_hash, + &short_channel_id, + ×tamp, + &message_flags, + &channel_flags, + &cltv_expiry_delta, + &htlc_minimum_msat, + &fee_base_msat, + &fee_proportional_millionths, + &htlc_maximum_msat)) { + status_broken("Could not parse inner private update %s", + tal_hex(tmpctx, msg)); + return; + } + + /* From NULL source (i.e. trust us!) */ + tell_lightningd_peer_update(rstate, + NULL, + short_channel_id, + fee_base_msat, + fee_proportional_millionths, + cltv_expiry_delta, + htlc_minimum_msat, + htlc_maximum_msat); } static bool upgrade_field(u8 oldversion, struct routing_state *rstate, u8 **msg) { + int type = fromwire_peektype(*msg); assert(can_upgrade(oldversion)); - if (oldversion == 10) { + if (oldversion <= 10) { /* Remove old channel_update with no htlc_maximum_msat */ - if (fromwire_peektype(*msg) == WIRE_CHANNEL_UPDATE + if (type == WIRE_CHANNEL_UPDATE && tal_bytelen(*msg) == 130) { *msg = tal_free(*msg); } } + if (oldversion <= 12) { + /* Remove private entries */ + if (type == WIRE_GOSSIP_STORE_PRIVATE_CHANNEL_OBS) { + *msg = tal_free(*msg); + } else if (type == WIRE_GOSSIP_STORE_PRIVATE_UPDATE_OBS) { + give_lightningd_canned_private_update(rstate, *msg); + *msg = tal_free(*msg); + } + } return true; } @@ -468,9 +528,7 @@ bool gossip_store_compact(struct gossip_store *gs) goto unlink_disable; /* We track location of all these message types. */ - if (msgtype == WIRE_GOSSIP_STORE_PRIVATE_CHANNEL - || msgtype == WIRE_GOSSIP_STORE_PRIVATE_UPDATE - || msgtype == WIRE_CHANNEL_ANNOUNCEMENT + if (msgtype == WIRE_CHANNEL_ANNOUNCEMENT || msgtype == WIRE_CHANNEL_UPDATE || msgtype == WIRE_NODE_ANNOUNCEMENT) { omap = tal(offmap, struct offset_map); @@ -579,7 +637,7 @@ u64 gossip_store_add_private_update(struct gossip_store *gs, const u8 *update) { /* A local update for an unannounced channel: not broadcastable, but * otherwise the same as a normal channel_update */ - const u8 *pupdate = towire_gossip_store_private_update(tmpctx, update); + const u8 *pupdate = towire_gossip_store_private_update_obs(tmpctx, update); return gossip_store_add(gs, pupdate, 0, false, false, false, NULL); } @@ -785,7 +843,7 @@ const u8 *gossip_store_get_private_update(const tal_t *ctx, const u8 *pmsg = gossip_store_get(tmpctx, gs, offset); u8 *msg; - if (!fromwire_gossip_store_private_update(ctx, pmsg, &msg)) + if (!fromwire_gossip_store_private_update_obs(ctx, pmsg, &msg)) status_failed(STATUS_FAIL_INTERNAL_ERROR, "Failed to decode private update @%"PRIu64": %s", offset, tal_hex(tmpctx, pmsg)); @@ -845,25 +903,6 @@ u32 gossip_store_load(struct routing_state *rstate, struct gossip_store *gs) spam = (be16_to_cpu(hdr.flags) & GOSSIP_STORE_RATELIMIT_BIT); switch (fromwire_peektype(msg)) { - case WIRE_GOSSIP_STORE_PRIVATE_CHANNEL: { - u8 *priv_chan_ann; - struct amount_sat sat; - if (!fromwire_gossip_store_private_channel(msg, msg, - &sat, - &priv_chan_ann)) { - bad = "Bad private_channel"; - goto badmsg; - } - - if (!routing_add_private_channel(rstate, NULL, - sat, priv_chan_ann, - gs->len)) { - bad = "Bad add_private_channel"; - goto badmsg; - } - stats[0]++; - break; - } case WIRE_GOSSIP_STORE_CHANNEL_AMOUNT: if (!fromwire_gossip_store_channel_amount(msg, &satoshis)) { @@ -904,12 +943,6 @@ u32 gossip_store_load(struct routing_state *rstate, struct gossip_store *gs) remember_chan_dying(rstate, &scid, deadline, gs->len); break; } - case WIRE_GOSSIP_STORE_PRIVATE_UPDATE: - if (!fromwire_gossip_store_private_update(tmpctx, msg, &msg)) { - bad = "invalid gossip_store_private_update"; - goto badmsg; - } - /* fall thru */ case WIRE_CHANNEL_UPDATE: if (!routing_add_channel_update(rstate, take(msg), gs->len, @@ -930,6 +963,10 @@ u32 gossip_store_load(struct routing_state *rstate, struct gossip_store *gs) } stats[2]++; break; + /* FIXME: Don't actually put these in! */ + case WIRE_GOSSIP_STORE_PRIVATE_CHANNEL_OBS: + case WIRE_GOSSIP_STORE_PRIVATE_UPDATE_OBS: + break; default: bad = "Unknown message"; goto badmsg; diff --git a/gossipd/gossip_store_wire.csv b/gossipd/gossip_store_wire.csv index 55e62c3bd..b0f81c371 100644 --- a/gossipd/gossip_store_wire.csv +++ b/gossipd/gossip_store_wire.csv @@ -9,14 +9,14 @@ msgtype,gossip_store_channel_amount,4101 msgdata,gossip_store_channel_amount,satoshis,amount_sat, # Mimics a channel_announce, except signatures are all-zero -msgtype,gossip_store_private_channel,4104 -msgdata,gossip_store_private_channel,satoshis,amount_sat, -msgdata,gossip_store_private_channel,len,u16, -msgdata,gossip_store_private_channel,announcement,u8,len +msgtype,gossip_store_private_channel_obs,4104 +msgdata,gossip_store_private_channel_obs,satoshis,amount_sat, +msgdata,gossip_store_private_channel_obs,len,u16, +msgdata,gossip_store_private_channel_obs,announcement,u8,len -msgtype,gossip_store_private_update,4102 -msgdata,gossip_store_private_update,len,u16, -msgdata,gossip_store_private_update,update,u8,len +msgtype,gossip_store_private_update_obs,4102 +msgdata,gossip_store_private_update_obs,len,u16, +msgdata,gossip_store_private_update_obs,update,u8,len msgtype,gossip_store_delete_chan,4103 msgdata,gossip_store_delete_chan,scid,short_channel_id, diff --git a/gossipd/routing.c b/gossipd/routing.c index a236a102a..47b9aa800 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -883,8 +883,8 @@ static void delete_chan_messages_from_store(struct routing_state *rstate, update_type = WIRE_CHANNEL_UPDATE; announcment_type = WIRE_CHANNEL_ANNOUNCEMENT; } else { - update_type = WIRE_GOSSIP_STORE_PRIVATE_UPDATE; - announcment_type = WIRE_GOSSIP_STORE_PRIVATE_CHANNEL; + update_type = WIRE_GOSSIP_STORE_PRIVATE_UPDATE_OBS; + announcment_type = WIRE_GOSSIP_STORE_PRIVATE_CHANNEL_OBS; } /* If these aren't in the store, these are noops. */ @@ -1333,7 +1333,7 @@ static void delete_spam_update(struct routing_state *rstate, gossip_store_delete(rstate->gs, &hc->rgraph, update_is_public ? WIRE_CHANNEL_UPDATE - : WIRE_GOSSIP_STORE_PRIVATE_UPDATE); + : WIRE_GOSSIP_STORE_PRIVATE_UPDATE_OBS); hc->rgraph.index = hc->bcast.index; hc->rgraph.timestamp = hc->bcast.timestamp; } @@ -1348,14 +1348,14 @@ static bool is_chan_dying(struct routing_state *rstate, return false; } -static void tell_lightningd_peer_update(struct routing_state *rstate, - const struct node_id *source_peer, - struct short_channel_id scid, - u32 fee_base_msat, - u32 fee_ppm, - u16 cltv_delta, - struct amount_msat htlc_minimum, - struct amount_msat htlc_maximum) +void tell_lightningd_peer_update(struct routing_state *rstate, + const struct node_id *source_peer, + struct short_channel_id scid, + u32 fee_base_msat, + u32 fee_ppm, + u16 cltv_delta, + struct amount_msat htlc_minimum, + struct amount_msat htlc_maximum) { struct peer_update remote_update; u8* msg; @@ -1532,7 +1532,7 @@ bool routing_add_channel_update(struct routing_state *rstate, gossip_store_delete(rstate->gs, &hc->bcast, is_chan_public(chan) ? WIRE_CHANNEL_UPDATE - : WIRE_GOSSIP_STORE_PRIVATE_UPDATE); + : WIRE_GOSSIP_STORE_PRIVATE_UPDATE_OBS); /* Update timestamp(s) */ hc->rgraph.timestamp = timestamp; @@ -1609,7 +1609,7 @@ bool routing_add_channel_update(struct routing_state *rstate, gossip_store_delete(rstate->gs, &chan->bcast, is_chan_public(chan) ? WIRE_CHANNEL_ANNOUNCEMENT - : WIRE_GOSSIP_STORE_PRIVATE_CHANNEL); + : WIRE_GOSSIP_STORE_PRIVATE_CHANNEL_OBS); chan->bcast.index = gossip_store_add(rstate->gs, zombie_announcement, chan->bcast.timestamp, @@ -1627,12 +1627,12 @@ bool routing_add_channel_update(struct routing_state *rstate, gossip_store_delete(rstate->gs, &chan->half[!direction].rgraph, is_chan_public(chan) ? WIRE_CHANNEL_UPDATE - : WIRE_GOSSIP_STORE_PRIVATE_UPDATE); + : WIRE_GOSSIP_STORE_PRIVATE_UPDATE_OBS); } gossip_store_delete(rstate->gs, &chan->half[!direction].bcast, is_chan_public(chan) ? WIRE_CHANNEL_UPDATE - : WIRE_GOSSIP_STORE_PRIVATE_UPDATE); + : WIRE_GOSSIP_STORE_PRIVATE_UPDATE_OBS); chan->half[!direction].bcast.index = gossip_store_add(rstate->gs, zombie_update[0], chan->half[!direction].bcast.timestamp, @@ -2219,7 +2219,7 @@ bool routing_add_private_channel(struct routing_state *rstate, /* Create new (unannounced) channel */ chan = new_chan(rstate, &scid, &node_id[0], &node_id[1], capacity); if (!index) { - u8 *msg = towire_gossip_store_private_channel(tmpctx, + u8 *msg = towire_gossip_store_private_channel_obs(tmpctx, capacity, chan_ann); index = gossip_store_add(rstate->gs, msg, 0, false, false, false, diff --git a/gossipd/routing.h b/gossipd/routing.h index b2c2dd5f3..baef0d116 100644 --- a/gossipd/routing.h +++ b/gossipd/routing.h @@ -435,4 +435,14 @@ bool node_has_broadcastable_channels(const struct node *node); const char *unfinalized_entries(const tal_t *ctx, struct routing_state *rstate); void remove_all_gossip(struct routing_state *rstate); + +/* We have an update for one of our channels (or unknown). */ +void tell_lightningd_peer_update(struct routing_state *rstate, + const struct node_id *source_peer, + struct short_channel_id scid, + u32 fee_base_msat, + u32 fee_ppm, + u16 cltv_delta, + struct amount_msat htlc_minimum, + struct amount_msat htlc_maximum); #endif /* LIGHTNING_GOSSIPD_ROUTING_H */ diff --git a/plugins/sql.c b/plugins/sql.c index b56b45479..b427d876f 100644 --- a/plugins/sql.c +++ b/plugins/sql.c @@ -743,7 +743,7 @@ static bool extract_scid(int gosstore_fd, size_t off, u16 type, /* For delete_chan scid immediately follows type */ if (type == WIRE_GOSSIP_STORE_DELETE_CHAN) off += 2; - else if (type == WIRE_GOSSIP_STORE_PRIVATE_UPDATE) + else if (type == WIRE_GOSSIP_STORE_PRIVATE_UPDATE_OBS) /* Prepend header */ off += 2 + 2 + update_scid_off; else if (type == WIRE_CHANNEL_UPDATE) @@ -841,7 +841,7 @@ static struct command_result *channels_refresh(struct command *cmd, /* If we see a channel_announcement, we don't care until we * see the channel_update */ if (type == WIRE_CHANNEL_UPDATE - || type == WIRE_GOSSIP_STORE_PRIVATE_UPDATE) { + || type == WIRE_GOSSIP_STORE_PRIVATE_UPDATE_OBS) { /* This can fail if entry not fully written yet. */ if (!extract_scid(gosstore_fd, off, type, &scid)) { gosstore_channels_off = off;