From e841e69b1b4ba77d97595143e8eef3d5af78c61b Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 25 Jan 2022 06:33:52 +1030 Subject: [PATCH] channeld: send channel updates and announcements via lightningd. We're weaning per-peer daemons off having a direct gossipd connection. Signed-off-by: Rusty Russell --- channeld/channeld.c | 34 ++++--- channeld/channeld_wire.csv | 21 ++++ gossipd/gossip_generation.c | 29 +++--- gossipd/gossip_generation.h | 6 +- gossipd/gossip_store.c | 15 ++- gossipd/gossipd.c | 95 +++++++++++-------- gossipd/gossipd_peerd_wire.csv | 14 --- gossipd/gossipd_wire.csv | 26 +++++ gossipd/routing.c | 58 +++++++---- gossipd/routing.h | 5 +- gossipd/test/run-check_channel_announcement.c | 4 + gossipd/test/run-check_node_announcement.c | 2 +- gossipd/test/run-crc32_of_update.c | 2 +- gossipd/test/run-onion_message.c | 24 +++-- gossipd/test/run-txout_failure.c | 4 + lightningd/channel_control.c | 27 ++++++ lightningd/gossip_control.c | 83 ++++++++++++++++ lightningd/gossip_control.h | 13 +++ 18 files changed, 335 insertions(+), 127 deletions(-) diff --git a/channeld/channeld.c b/channeld/channeld.c index 0c2727915..a3d9fa113 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -392,7 +392,9 @@ static void maybe_send_stfu(struct peer *peer) } #endif -/* Create and send channel_update to gossipd (and maybe peer) */ +/* Tell gossipd to create channel_update (then it goes into + * gossip_store, then streams out to peers, or sends it directly if + * it's a private channel) */ static void send_channel_update(struct peer *peer, int disable_flag) { u8 *msg; @@ -405,7 +407,7 @@ static void send_channel_update(struct peer *peer, int disable_flag) assert(peer->short_channel_ids[LOCAL].u64); - msg = towire_gossipd_local_channel_update(NULL, + msg = towire_channeld_local_channel_update(NULL, &peer->short_channel_ids[LOCAL], disable_flag == ROUTING_FLAGS_DISABLED, @@ -414,7 +416,7 @@ static void send_channel_update(struct peer *peer, int disable_flag) peer->fee_base, peer->fee_per_satoshi, advertized_htlc_max(peer->channel)); - wire_sync_write(peer->pps->gossip_fd, take(msg)); + wire_sync_write(MASTER_FD, take(msg)); } /** @@ -430,22 +432,15 @@ static void send_channel_update(struct peer *peer, int disable_flag) static void make_channel_local_active(struct peer *peer) { u8 *msg; - const u8 *ann; const u8 *annfeatures = get_agreed_channelfeatures(tmpctx, peer->our_features, peer->their_features); - ann = private_channel_announcement(tmpctx, - &peer->short_channel_ids[LOCAL], - &peer->node_ids[LOCAL], - &peer->node_ids[REMOTE], - annfeatures); - - /* Tell gossipd about local channel. */ - msg = towire_gossip_store_private_channel(NULL, - peer->channel->funding_sats, - ann); - wire_sync_write(peer->pps->gossip_fd, take(msg)); + /* Tell lightningd to tell gossipd about local channel. */ + msg = towire_channeld_local_private_channel(NULL, + peer->channel->funding_sats, + annfeatures); + wire_sync_write(MASTER_FD, take(msg)); /* Tell gossipd and the other side what parameters we expect should * they route through us */ @@ -560,9 +555,9 @@ static void announce_channel(struct peer *peer) cannounce = create_channel_announcement(tmpctx, peer); - wire_sync_write(peer->pps->gossip_fd, - take(towire_gossipd_local_channel_announcement(NULL, - cannounce))); + wire_sync_write(MASTER_FD, + take(towire_channeld_local_channel_announcement(NULL, + cannounce))); send_channel_update(peer, 0); } @@ -3795,6 +3790,9 @@ static void req_in(struct peer *peer, const u8 *msg) case WIRE_CHANNELD_UPGRADED: case WIRE_CHANNELD_PING_REPLY: case WIRE_CHANNELD_USED_CHANNEL_UPDATE: + case WIRE_CHANNELD_LOCAL_CHANNEL_UPDATE: + case WIRE_CHANNELD_LOCAL_CHANNEL_ANNOUNCEMENT: + case WIRE_CHANNELD_LOCAL_PRIVATE_CHANNEL: break; } diff --git a/channeld/channeld_wire.csv b/channeld/channeld_wire.csv index 00d9784b7..4770aea3d 100644 --- a/channeld/channeld_wire.csv +++ b/channeld/channeld_wire.csv @@ -234,6 +234,27 @@ msgdata,channeld_channel_update,msg,u8,len # Tell lightningd we used the latest channel_update for an error. msgtype,channeld_used_channel_update,1102 +# Channeld: tell gossipd to make this channel_update. +msgtype,channeld_local_channel_update,1013 +msgdata,channeld_local_channel_update,short_channel_id,short_channel_id, +msgdata,channeld_local_channel_update,disable,bool, +msgdata,channeld_local_channel_update,cltv_expiry_delta,u16, +msgdata,channeld_local_channel_update,htlc_minimum_msat,amount_msat, +msgdata,channeld_local_channel_update,fee_base_msat,u32, +msgdata,channeld_local_channel_update,fee_proportional_millionths,u32, +msgdata,channeld_local_channel_update,htlc_maximum_msat,amount_msat, + +# Channeld: tell gossipd about our channel_announcement +msgtype,channeld_local_channel_announcement,1014 +msgdata,channeld_local_channel_announcement,len,u16, +msgdata,channeld_local_channel_announcement,cannounce,u8,len + +# Channeld: tell gossipd about this (as-yet) unannounced channel +msgtype,channeld_local_private_channel,1015 +msgdata,channeld_local_private_channel,capacity,amount_sat, +msgdata,channeld_local_private_channel,len,u16, +msgdata,channeld_local_private_channel,features,u8,len + # Ask channeld to quiesce. msgtype,channeld_dev_quiesce,1009 msgtype,channeld_dev_quiesce_reply,1109 diff --git a/gossipd/gossip_generation.c b/gossipd/gossip_generation.c index adef74e5e..faf01bb72 100644 --- a/gossipd/gossip_generation.c +++ b/gossipd/gossip_generation.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -695,11 +694,10 @@ void refresh_local_channel(struct daemon *daemon, sign_timestamp_and_apply_update(daemon, chan, direction, take(update)); } -/* channeld asks us to update the local channel. */ -bool handle_local_channel_update(struct daemon *daemon, - const struct node_id *src, - const u8 *msg) +/* channeld (via lightningd) asks us to update the local channel. */ +void handle_local_channel_update(struct daemon *daemon, const u8 *msg) { + struct node_id id; struct short_channel_id scid; bool disable; u16 cltv_expiry_delta; @@ -710,10 +708,8 @@ bool handle_local_channel_update(struct daemon *daemon, u8 *unsigned_update; const struct half_chan *hc; - /* FIXME: We should get scid from lightningd when setting up the - * connection, so no per-peer daemon can mess with channels other than - * its own! */ if (!fromwire_gossipd_local_channel_update(msg, + &id, &scid, &disable, &cltv_expiry_delta, @@ -721,26 +717,24 @@ bool handle_local_channel_update(struct daemon *daemon, &fee_base_msat, &fee_proportional_millionths, &htlc_maximum)) { - status_peer_broken(src, "bad local_channel_update %s", - tal_hex(tmpctx, msg)); - return false; + master_badmsg(WIRE_GOSSIPD_LOCAL_CHANNEL_UPDATE, msg); } chan = get_channel(daemon->rstate, &scid); /* Can theoretically happen if channel just closed. */ if (!chan) { - status_peer_debug(src, "local_channel_update for unknown %s", + status_peer_debug(&id, "local_channel_update for unknown %s", type_to_string(tmpctx, struct short_channel_id, &scid)); - return true; + return; } if (!local_direction(daemon->rstate, chan, &direction)) { - status_peer_broken(src, "bad local_channel_update chan %s", + status_peer_broken(&id, "bad local_channel_update chan %s", type_to_string(tmpctx, struct short_channel_id, &scid)); - return false; + return; } unsigned_update = create_unsigned_update(tmpctx, &scid, direction, @@ -754,7 +748,7 @@ bool handle_local_channel_update(struct daemon *daemon, /* Ignore duplicates. */ if (is_halfchan_defined(hc) && !cupdate_different(daemon->rstate->gs, hc, unsigned_update)) - return true; + return; /* Too early? Defer (don't worry if it's unannounced). */ if (hc && is_chan_public(chan)) { @@ -764,13 +758,12 @@ bool handle_local_channel_update(struct daemon *daemon, if (now < next_time) { defer_update(daemon, next_time - now, chan, direction, take(unsigned_update)); - return true; + return; } } sign_timestamp_and_apply_update(daemon, chan, direction, take(unsigned_update)); - return true; } /* Take update, set/unset disabled flag (and update timestamp). diff --git a/gossipd/gossip_generation.h b/gossipd/gossip_generation.h index 3d8f257ab..b39cc158b 100644 --- a/gossipd/gossip_generation.h +++ b/gossipd/gossip_generation.h @@ -45,10 +45,8 @@ void local_enable_chan(struct daemon *daemon, const struct chan *chan, int direc void refresh_local_channel(struct daemon *daemon, struct chan *chan, int direction); -/* channeld asks us to update the local channel. */ -bool handle_local_channel_update(struct daemon *daemon, - const struct node_id *src, - const u8 *msg); +/* channeld (via lightningd) asks us to update the local channel. */ +void handle_local_channel_update(struct daemon *daemon, const u8 *msg); /* lightningd tells us it used the last channel_update we sent. */ void handle_used_local_channel_update(struct daemon *daemon, const u8 *msg); diff --git a/gossipd/gossip_store.c b/gossipd/gossip_store.c index 408e79adf..f06c5a876 100644 --- a/gossipd/gossip_store.c +++ b/gossipd/gossip_store.c @@ -782,14 +782,25 @@ u32 gossip_store_load(struct routing_state *rstate, struct gossip_store *gs) } switch (fromwire_peektype(msg)) { - case WIRE_GOSSIP_STORE_PRIVATE_CHANNEL: - if (!routing_add_private_channel(rstate, NULL, msg, + case WIRE_GOSSIP_STORE_PRIVATE_CHANNEL: { + u8 *chan_ann; + struct amount_sat sat; + if (!fromwire_gossip_store_private_channel(msg, msg, + &sat, + &chan_ann)) { + bad = "Bad private_channel"; + goto badmsg; + } + + if (!routing_add_private_channel(rstate, NULL, + sat, 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)) { diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index 77c484e80..a27e6ccb8 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -289,31 +290,60 @@ static u8 *handle_node_announce(struct peer *peer, const u8 *msg) return err; } -static bool handle_local_channel_announcement(struct daemon *daemon, - struct peer *peer, - const u8 *msg) +static void handle_local_channel_announcement(struct daemon *daemon, const u8 *msg) { u8 *cannouncement; const u8 *err; + struct node_id id; + struct peer *peer; if (!fromwire_gossipd_local_channel_announcement(msg, msg, - &cannouncement)) { - status_broken("peer %s bad local_channel_announcement %s", - type_to_string(tmpctx, struct node_id, &peer->id), - tal_hex(tmpctx, msg)); - return false; - } + &id, + &cannouncement)) + master_badmsg(WIRE_GOSSIPD_LOCAL_CHANNEL_ANNOUNCEMENT, msg); + + /* We treat it OK even if peer has disconnected since (unlikely though!) */ + peer = find_peer(daemon, &id); + if (!peer) + status_broken("Unknown peer %s for local_channel_announcement", + type_to_string(tmpctx, struct node_id, &id)); err = handle_channel_announcement_msg(daemon, peer, cannouncement); if (err) { status_broken("peer %s invalid local_channel_announcement %s (%s)", - type_to_string(tmpctx, struct node_id, &peer->id), + type_to_string(tmpctx, struct node_id, &id), tal_hex(tmpctx, msg), tal_hex(tmpctx, err)); - return false; } +} - return true; + +/* channeld (via lightningd) tells us about (as-yet?) unannounce channel. + * It needs us to put it in gossip_store. */ +static void handle_local_private_channel(struct daemon *daemon, const u8 *msg) +{ + struct node_id id; + struct amount_sat capacity; + u8 *features; + struct short_channel_id scid; + const u8 *cannounce; + + if (!fromwire_gossipd_local_private_channel(msg, msg, + &id, &capacity, &scid, + &features)) + master_badmsg(WIRE_GOSSIPD_LOCAL_PRIVATE_CHANNEL, msg); + + cannounce = private_channel_announcement(tmpctx, + &scid, + &daemon->id, + &id, + features); + + if (!routing_add_private_channel(daemon->rstate, &id, capacity, + cannounce, 0)) { + status_peer_broken(&id, "bad add_private_channel %s", + tal_hex(tmpctx, cannounce)); + } } /* Peer sends obsolete onion msg. */ @@ -645,7 +675,6 @@ static struct io_plan *peer_msg_in(struct io_conn *conn, struct peer *peer) { const u8 *err; - bool ok; /* These are messages relayed from peer */ switch ((enum peer_wire)fromwire_peektype(msg)) { @@ -720,40 +749,17 @@ static struct io_plan *peer_msg_in(struct io_conn *conn, return io_close(conn); } - /* Must be a gossipd_peerd_wire_type asking us to do something. */ - switch ((enum gossipd_peerd_wire)fromwire_peektype(msg)) { - case WIRE_GOSSIPD_LOCAL_CHANNEL_UPDATE: - ok = handle_local_channel_update(peer->daemon, &peer->id, msg); - goto handled_cmd; - case WIRE_GOSSIPD_LOCAL_CHANNEL_ANNOUNCEMENT: - ok = handle_local_channel_announcement(peer->daemon, peer, msg); - goto handled_cmd; - } - - if (fromwire_peektype(msg) == WIRE_GOSSIP_STORE_PRIVATE_CHANNEL) { - ok = routing_add_private_channel(peer->daemon->rstate, peer, - msg, 0); - goto handled_cmd; - } - /* Anything else should not have been sent to us: close on it */ - status_peer_broken(&peer->id, "unexpected cmd of type %i %s", - fromwire_peektype(msg), - gossipd_peerd_wire_name(fromwire_peektype(msg))); + status_peer_broken(&peer->id, "unexpected cmd of type %i", + fromwire_peektype(msg)); return io_close(conn); - /* Commands should always be OK. */ -handled_cmd: - if (!ok) - return io_close(conn); - goto done; - /* Forwarded messages may be bad, so we have error which the per-peer * daemon will forward to the peer. */ handled_relay: if (err) queue_peer_msg(peer, take(err)); -done: + return daemon_conn_read_next(conn, peer->dc); } @@ -1297,6 +1303,17 @@ static struct io_plan *recv_req(struct io_conn *conn, handle_used_local_channel_update(daemon, msg); goto done; + case WIRE_GOSSIPD_LOCAL_CHANNEL_UPDATE: + handle_local_channel_update(daemon, msg); + goto done; + + case WIRE_GOSSIPD_LOCAL_CHANNEL_ANNOUNCEMENT: + handle_local_channel_announcement(daemon, msg); + goto done; + + case WIRE_GOSSIPD_LOCAL_PRIVATE_CHANNEL: + handle_local_private_channel(daemon, msg); + goto done; #if DEVELOPER case WIRE_GOSSIPD_DEV_SET_MAX_SCIDS_ENCODE_SIZE: dev_set_max_scids_encode_size(daemon, msg); diff --git a/gossipd/gossipd_peerd_wire.csv b/gossipd/gossipd_peerd_wire.csv index 9b86cbf27..282712beb 100644 --- a/gossipd/gossipd_peerd_wire.csv +++ b/gossipd/gossipd_peerd_wire.csv @@ -2,17 +2,3 @@ #include #include -# Send this channel_update. -msgtype,gossipd_local_channel_update,3504 -msgdata,gossipd_local_channel_update,short_channel_id,short_channel_id, -msgdata,gossipd_local_channel_update,disable,bool, -msgdata,gossipd_local_channel_update,cltv_expiry_delta,u16, -msgdata,gossipd_local_channel_update,htlc_minimum_msat,amount_msat, -msgdata,gossipd_local_channel_update,fee_base_msat,u32, -msgdata,gossipd_local_channel_update,fee_proportional_millionths,u32, -msgdata,gossipd_local_channel_update,htlc_maximum_msat,amount_msat, - -# Send this channel_announcement -msgtype,gossipd_local_channel_announcement,3506 -msgdata,gossipd_local_channel_announcement,len,u16, -msgdata,gossipd_local_channel_announcement,cannount,u8,len diff --git a/gossipd/gossipd_wire.csv b/gossipd/gossipd_wire.csv index 7dba19620..eaec7643c 100644 --- a/gossipd/gossipd_wire.csv +++ b/gossipd/gossipd_wire.csv @@ -115,6 +115,32 @@ msgdata,gossipd_got_local_channel_update,scid,short_channel_id, msgdata,gossipd_got_local_channel_update,len,u16, msgdata,gossipd_got_local_channel_update,channel_update,u8,len +# Send this channel_update. +msgtype,gossipd_local_channel_update,3004 +msgdata,gossipd_local_channel_update,id,node_id, +msgdata,gossipd_local_channel_update,short_channel_id,short_channel_id, +msgdata,gossipd_local_channel_update,disable,bool, +msgdata,gossipd_local_channel_update,cltv_expiry_delta,u16, +msgdata,gossipd_local_channel_update,htlc_minimum_msat,amount_msat, +msgdata,gossipd_local_channel_update,fee_base_msat,u32, +msgdata,gossipd_local_channel_update,fee_proportional_millionths,u32, +msgdata,gossipd_local_channel_update,htlc_maximum_msat,amount_msat, + +# Send this channel_announcement +msgtype,gossipd_local_channel_announcement,3006 +msgdata,gossipd_local_channel_announcement,id,node_id, +msgdata,gossipd_local_channel_announcement,len,u16, +msgdata,gossipd_local_channel_announcement,cannounce,u8,len + +# Tell gossipd about a private channel (to put it in the store) +# cannounce has same structure, dummy sigs. +msgtype,gossipd_local_private_channel,3008 +msgdata,gossipd_local_private_channel,id,node_id, +msgdata,gossipd_local_private_channel,capacity,amount_sat, +msgdata,gossipd_local_private_channel,scid,short_channel_id, +msgdata,gossipd_local_private_channel,len,u16, +msgdata,gossipd_local_private_channel,features,u8,len + # Tell gossipd we used the channel update (in case it was deferred) msgtype,gossipd_used_local_channel_update,3052 msgdata,gossipd_used_local_channel_update,scid,short_channel_id, diff --git a/gossipd/routing.c b/gossipd/routing.c index c52d68bc3..c95834d02 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -1820,23 +1820,18 @@ void route_prune(struct routing_state *rstate) } bool routing_add_private_channel(struct routing_state *rstate, - const struct peer *peer, - const u8 *msg, u64 index) + const struct node_id *id, + struct amount_sat capacity, + const u8 *chan_ann, u64 index) { struct short_channel_id scid; struct node_id node_id[2]; struct pubkey ignorekey; - struct amount_sat sat; struct chan *chan; - u8 *features, *chan_ann; + u8 *features; secp256k1_ecdsa_signature ignoresig; struct bitcoin_blkid chain_hash; - if (!fromwire_gossip_store_private_channel(tmpctx, msg, - &sat, &chan_ann)) - return false; - - if (!fromwire_channel_announcement(tmpctx, chan_ann, &ignoresig, &ignoresig, @@ -1851,21 +1846,46 @@ bool routing_add_private_channel(struct routing_state *rstate, &ignorekey)) return false; - /* Can happen on channeld restart. */ - if (get_channel(rstate, &scid)) { - status_peer_debug(peer ? &peer->id : NULL, - "Attempted to local_add_channel a known channel"); + /* Happens on channeld restart. */ + if (get_channel(rstate, &scid)) return true; + + /* Make sure this id (if any) was allowed to create this */ + if (id) { + struct node_id expected[2]; + int cmp = node_id_cmp(&rstate->local_id, id); + + if (cmp < 0) { + expected[0] = rstate->local_id; + expected[1] = *id; + } else if (cmp > 0) { + expected[0] = *id; + expected[1] = rstate->local_id; + } else { + /* lightningd sets id, so this is fatal */ + status_failed(STATUS_FAIL_MASTER_IO, + "private_channel peer was us?"); + } + + if (!node_id_eq(&node_id[0], &expected[0]) + || !node_id_eq(&node_id[1], &expected[1])) { + status_peer_broken(id, "private channel %s<->%s invalid", + type_to_string(tmpctx, struct node_id, + &node_id[0]), + type_to_string(tmpctx, struct node_id, + &node_id[1])); + return false; + } } - status_peer_debug(peer ? &peer->id : NULL, - "local_add_channel %s", - type_to_string(tmpctx, struct short_channel_id, &scid)); - /* Create new (unannounced) channel */ - chan = new_chan(rstate, &scid, &node_id[0], &node_id[1], sat); - if (!index) + chan = new_chan(rstate, &scid, &node_id[0], &node_id[1], capacity); + if (!index) { + u8 *msg = towire_gossip_store_private_channel(tmpctx, + capacity, + chan_ann); index = gossip_store_add(rstate->gs, msg, 0, false, NULL); + } chan->bcast.index = index; return true; } diff --git a/gossipd/routing.h b/gossipd/routing.h index e33d63061..1641284bb 100644 --- a/gossipd/routing.h +++ b/gossipd/routing.h @@ -378,8 +378,9 @@ bool routing_add_node_announcement(struct routing_state *rstate, * `announce_depth`. */ bool routing_add_private_channel(struct routing_state *rstate, - const struct peer *peer, - const u8 *msg, u64 index); + const struct node_id *id, + struct amount_sat sat, + const u8 *chan_ann, u64 index); /** * Get the local time. diff --git a/gossipd/test/run-check_channel_announcement.c b/gossipd/test/run-check_channel_announcement.c index 28b29a341..827bbdd63 100644 --- a/gossipd/test/run-check_channel_announcement.c +++ b/gossipd/test/run-check_channel_announcement.c @@ -144,6 +144,10 @@ void *notleak_(void *ptr UNNEEDED, bool plus_children UNNEEDED) /* Generated stub for peer_supplied_good_gossip */ void peer_supplied_good_gossip(struct peer *peer UNNEEDED, size_t amount UNNEEDED) { fprintf(stderr, "peer_supplied_good_gossip called!\n"); abort(); } +/* Generated stub for status_failed */ +void status_failed(enum status_failreason code UNNEEDED, + const char *fmt UNNEEDED, ...) +{ fprintf(stderr, "status_failed called!\n"); abort(); } /* Generated stub for status_fmt */ void status_fmt(enum log_level level UNNEEDED, const struct node_id *peer UNNEEDED, diff --git a/gossipd/test/run-check_node_announcement.c b/gossipd/test/run-check_node_announcement.c index 4104556fa..25fcdda7a 100644 --- a/gossipd/test/run-check_node_announcement.c +++ b/gossipd/test/run-check_node_announcement.c @@ -37,7 +37,7 @@ struct peer *find_peer(struct daemon *daemon UNNEEDED, const struct node_id *id char *fmt_wireaddr_without_port(const tal_t *ctx UNNEEDED, const struct wireaddr *a UNNEEDED) { fprintf(stderr, "fmt_wireaddr_without_port called!\n"); abort(); } /* Generated stub for fromwire_gossipd_local_channel_update */ -bool fromwire_gossipd_local_channel_update(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED, bool *disable UNNEEDED, u16 *cltv_expiry_delta UNNEEDED, struct amount_msat *htlc_minimum_msat UNNEEDED, u32 *fee_base_msat UNNEEDED, u32 *fee_proportional_millionths UNNEEDED, struct amount_msat *htlc_maximum_msat UNNEEDED) +bool fromwire_gossipd_local_channel_update(const void *p UNNEEDED, struct node_id *id UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED, bool *disable UNNEEDED, u16 *cltv_expiry_delta UNNEEDED, struct amount_msat *htlc_minimum_msat UNNEEDED, u32 *fee_base_msat UNNEEDED, u32 *fee_proportional_millionths UNNEEDED, struct amount_msat *htlc_maximum_msat UNNEEDED) { fprintf(stderr, "fromwire_gossipd_local_channel_update called!\n"); abort(); } /* Generated stub for fromwire_gossipd_used_local_channel_update */ bool fromwire_gossipd_used_local_channel_update(const void *p UNNEEDED, struct short_channel_id *scid UNNEEDED) diff --git a/gossipd/test/run-crc32_of_update.c b/gossipd/test/run-crc32_of_update.c index 7d9b64037..47a1250a3 100644 --- a/gossipd/test/run-crc32_of_update.c +++ b/gossipd/test/run-crc32_of_update.c @@ -58,7 +58,7 @@ char *fmt_wireaddr_without_port(const tal_t *ctx UNNEEDED, const struct wireaddr bool fromwire_gossipd_dev_set_max_scids_encode_size(const void *p UNNEEDED, u32 *max UNNEEDED) { fprintf(stderr, "fromwire_gossipd_dev_set_max_scids_encode_size called!\n"); abort(); } /* Generated stub for fromwire_gossipd_local_channel_update */ -bool fromwire_gossipd_local_channel_update(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED, bool *disable UNNEEDED, u16 *cltv_expiry_delta UNNEEDED, struct amount_msat *htlc_minimum_msat UNNEEDED, u32 *fee_base_msat UNNEEDED, u32 *fee_proportional_millionths UNNEEDED, struct amount_msat *htlc_maximum_msat UNNEEDED) +bool fromwire_gossipd_local_channel_update(const void *p UNNEEDED, struct node_id *id UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED, bool *disable UNNEEDED, u16 *cltv_expiry_delta UNNEEDED, struct amount_msat *htlc_minimum_msat UNNEEDED, u32 *fee_base_msat UNNEEDED, u32 *fee_proportional_millionths UNNEEDED, struct amount_msat *htlc_maximum_msat UNNEEDED) { fprintf(stderr, "fromwire_gossipd_local_channel_update called!\n"); abort(); } /* Generated stub for fromwire_gossipd_used_local_channel_update */ bool fromwire_gossipd_used_local_channel_update(const void *p UNNEEDED, struct short_channel_id *scid UNNEEDED) diff --git a/gossipd/test/run-onion_message.c b/gossipd/test/run-onion_message.c index 5babc51c9..2ad7a2f3e 100644 --- a/gossipd/test/run-onion_message.c +++ b/gossipd/test/run-onion_message.c @@ -92,11 +92,14 @@ bool fromwire_gossipd_get_txout_reply(const tal_t *ctx UNNEEDED, const void *p U bool fromwire_gossipd_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct feature_set **our_features UNNEEDED, struct node_id *id UNNEEDED, u8 rgb[3] UNNEEDED, u8 alias[32] UNNEEDED, struct wireaddr **announcable UNNEEDED, u32 **dev_gossip_time UNNEEDED, bool *dev_fast_gossip UNNEEDED, bool *dev_fast_gossip_prune UNNEEDED) { fprintf(stderr, "fromwire_gossipd_init called!\n"); abort(); } /* Generated stub for fromwire_gossipd_local_channel_announcement */ -bool fromwire_gossipd_local_channel_announcement(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **cannount UNNEEDED) +bool fromwire_gossipd_local_channel_announcement(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, u8 **cannounce UNNEEDED) { fprintf(stderr, "fromwire_gossipd_local_channel_announcement called!\n"); abort(); } /* Generated stub for fromwire_gossipd_local_channel_close */ bool fromwire_gossipd_local_channel_close(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED) { fprintf(stderr, "fromwire_gossipd_local_channel_close called!\n"); abort(); } +/* Generated stub for fromwire_gossipd_local_private_channel */ +bool fromwire_gossipd_local_private_channel(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, struct amount_sat *capacity UNNEEDED, struct short_channel_id *scid UNNEEDED, u8 **features UNNEEDED) +{ fprintf(stderr, "fromwire_gossipd_local_private_channel called!\n"); abort(); } /* Generated stub for fromwire_gossipd_new_blockheight */ bool fromwire_gossipd_new_blockheight(const void *p UNNEEDED, u32 *blockheight UNNEEDED) { fprintf(stderr, "fromwire_gossipd_new_blockheight called!\n"); abort(); } @@ -133,9 +136,6 @@ u32 gossip_store_load(struct routing_state *rstate UNNEEDED, struct gossip_store /* Generated stub for gossip_time_now */ struct timeabs gossip_time_now(const struct routing_state *rstate UNNEEDED) { fprintf(stderr, "gossip_time_now called!\n"); abort(); } -/* Generated stub for gossipd_peerd_wire_name */ -const char *gossipd_peerd_wire_name(int e UNNEEDED) -{ fprintf(stderr, "gossipd_peerd_wire_name called!\n"); abort(); } /* Generated stub for handle_channel_announcement */ u8 *handle_channel_announcement(struct routing_state *rstate UNNEEDED, const u8 *announce TAKES UNNEEDED, @@ -150,9 +150,7 @@ u8 *handle_channel_update(struct routing_state *rstate UNNEEDED, const u8 *updat bool force UNNEEDED) { fprintf(stderr, "handle_channel_update called!\n"); abort(); } /* Generated stub for handle_local_channel_update */ -bool handle_local_channel_update(struct daemon *daemon UNNEEDED, - const struct node_id *src UNNEEDED, - const u8 *msg UNNEEDED) +void handle_local_channel_update(struct daemon *daemon UNNEEDED, const u8 *msg UNNEEDED) { fprintf(stderr, "handle_local_channel_update called!\n"); abort(); } /* Generated stub for handle_node_announcement */ u8 *handle_node_announcement(struct routing_state *rstate UNNEEDED, const u8 *node UNNEEDED, @@ -247,6 +245,13 @@ struct chan *next_chan(const struct node *node UNNEEDED, struct chan_map_iter *i /* Generated stub for notleak_ */ void *notleak_(void *ptr UNNEEDED, bool plus_children UNNEEDED) { fprintf(stderr, "notleak_ called!\n"); abort(); } +/* Generated stub for private_channel_announcement */ +const u8 *private_channel_announcement(const tal_t *ctx UNNEEDED, + const struct short_channel_id *scid UNNEEDED, + const struct node_id *local_node_id UNNEEDED, + const struct node_id *remote_node_id UNNEEDED, + const u8 *features UNNEEDED) +{ fprintf(stderr, "private_channel_announcement called!\n"); abort(); } /* Generated stub for query_unknown_channel */ void query_unknown_channel(struct daemon *daemon UNNEEDED, struct peer *peer UNNEEDED, @@ -273,8 +278,9 @@ void route_prune(struct routing_state *rstate UNNEEDED) { fprintf(stderr, "route_prune called!\n"); abort(); } /* Generated stub for routing_add_private_channel */ bool routing_add_private_channel(struct routing_state *rstate UNNEEDED, - const struct peer *peer UNNEEDED, - const u8 *msg UNNEEDED, u64 index UNNEEDED) + const struct node_id *id UNNEEDED, + struct amount_sat sat UNNEEDED, + const u8 *chan_ann UNNEEDED, u64 index UNNEEDED) { fprintf(stderr, "routing_add_private_channel called!\n"); abort(); } /* Generated stub for sanitize_error */ char *sanitize_error(const tal_t *ctx UNNEEDED, const u8 *errmsg UNNEEDED, diff --git a/gossipd/test/run-txout_failure.c b/gossipd/test/run-txout_failure.c index ba7791c32..1acfd534d 100644 --- a/gossipd/test/run-txout_failure.c +++ b/gossipd/test/run-txout_failure.c @@ -109,6 +109,10 @@ void peer_supplied_good_gossip(struct peer *peer UNNEEDED, size_t amount UNNEEDE char *sanitize_error(const tal_t *ctx UNNEEDED, const u8 *errmsg UNNEEDED, struct channel_id *channel_id UNNEEDED) { fprintf(stderr, "sanitize_error called!\n"); abort(); } +/* Generated stub for status_failed */ +void status_failed(enum status_failreason code UNNEEDED, + const char *fmt UNNEEDED, ...) +{ fprintf(stderr, "status_failed called!\n"); abort(); } /* Generated stub for status_fmt */ void status_fmt(enum log_level level UNNEEDED, const struct node_id *peer UNNEEDED, diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index d8333673f..030b15b5e 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -412,6 +413,23 @@ static void handle_error_channel(struct channel *channel, forget(channel); } +static void handle_local_private_channel(struct channel *channel, const u8 *msg) +{ + struct amount_sat capacity; + u8 *features; + + if (!fromwire_channeld_local_private_channel(msg, msg, &capacity, + &features)) { + channel_internal_error(channel, + "bad channeld_local_private_channel %s", + tal_hex(channel, msg)); + return; + } + + tell_gossipd_local_private_channel(channel->peer->ld, channel, + capacity, features); +} + static void forget_channel(struct channel *channel, const char *why) { channel->error = towire_errorfmt(channel, &channel->cid, "%s", why); @@ -508,6 +526,15 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds) /* This tells gossipd we used it. */ get_channel_update(sd->channel); break; + case WIRE_CHANNELD_LOCAL_CHANNEL_UPDATE: + tell_gossipd_local_channel_update(sd->ld, sd->channel, msg); + break; + case WIRE_CHANNELD_LOCAL_CHANNEL_ANNOUNCEMENT: + tell_gossipd_local_channel_announce(sd->ld, sd->channel, msg); + break; + case WIRE_CHANNELD_LOCAL_PRIVATE_CHANNEL: + handle_local_private_channel(sd->channel, msg); + break; #if EXPERIMENTAL_FEATURES case WIRE_CHANNELD_UPGRADED: handle_channel_upgrade(sd->channel, msg); diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 33038d3e3..3b13a1021 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -1,6 +1,7 @@ #include "config.h" #include #include +#include #include #include #include @@ -167,6 +168,9 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) case WIRE_GOSSIPD_ADDGOSSIP: case WIRE_GOSSIPD_GET_ADDRS: case WIRE_GOSSIPD_USED_LOCAL_CHANNEL_UPDATE: + case WIRE_GOSSIPD_LOCAL_CHANNEL_UPDATE: + case WIRE_GOSSIPD_LOCAL_CHANNEL_ANNOUNCEMENT: + case WIRE_GOSSIPD_LOCAL_PRIVATE_CHANNEL: /* This is a reply, so never gets through to here. */ case WIRE_GOSSIPD_INIT_REPLY: case WIRE_GOSSIPD_DEV_MEMLEAK_REPLY: @@ -278,6 +282,85 @@ void gossipd_notify_spend(struct lightningd *ld, subd_send_msg(ld->gossip, msg); } +/* We unwrap, add the peer id, and send to gossipd. */ +void tell_gossipd_local_channel_update(struct lightningd *ld, + struct channel *channel, + const u8 *msg) +{ + struct short_channel_id scid; + bool disable; + u16 cltv_expiry_delta; + struct amount_msat htlc_minimum_msat; + u32 fee_base_msat, fee_proportional_millionths; + struct amount_msat htlc_maximum_msat; + + if (!fromwire_channeld_local_channel_update(msg, &scid, &disable, + &cltv_expiry_delta, + &htlc_minimum_msat, + &fee_base_msat, + &fee_proportional_millionths, + &htlc_maximum_msat)) { + channel_internal_error(channel, + "bad channeld_local_channel_update %s", + tal_hex(channel, msg)); + return; + } + + /* As we're shutting down, ignore */ + if (!ld->gossip) + return; + + subd_send_msg(ld->gossip, + take(towire_gossipd_local_channel_update + (NULL, + &channel->peer->id, + &scid, + disable, + cltv_expiry_delta, + htlc_minimum_msat, + fee_base_msat, + fee_proportional_millionths, htlc_maximum_msat))); +} + +void tell_gossipd_local_channel_announce(struct lightningd *ld, + struct channel *channel, + const u8 *msg) +{ + u8 *ann; + if (!fromwire_channeld_local_channel_announcement(msg, msg, &ann)) { + channel_internal_error(channel, + "bad channeld_local_channel_announcement" + " %s", + tal_hex(channel, msg)); + return; + } + + /* As we're shutting down, ignore */ + if (!ld->gossip) + return; + + subd_send_msg(ld->gossip, + take(towire_gossipd_local_channel_announcement + (NULL, &channel->peer->id, ann))); +} + +void tell_gossipd_local_private_channel(struct lightningd *ld, + struct channel *channel, + struct amount_sat capacity, + const u8 *features) +{ + /* As we're shutting down, ignore */ + if (!ld->gossip) + return; + + subd_send_msg(ld->gossip, + take(towire_gossipd_local_private_channel + (NULL, &channel->peer->id, + capacity, + channel->scid, + features))); +} + static struct command_result *json_setleaserates(struct command *cmd, const char *buffer, const jsmntok_t *obj UNNEEDED, diff --git a/lightningd/gossip_control.h b/lightningd/gossip_control.h index 7d6254e29..c1d587902 100644 --- a/lightningd/gossip_control.h +++ b/lightningd/gossip_control.h @@ -5,6 +5,7 @@ #include #include +struct channel; struct lightningd; void gossip_init(struct lightningd *ld, int connectd_fd); @@ -14,4 +15,16 @@ void gossipd_notify_spend(struct lightningd *ld, void gossip_notify_new_block(struct lightningd *ld, u32 blockheight); +/* channeld tells us stuff, we tell gossipd. */ +void tell_gossipd_local_channel_update(struct lightningd *ld, + struct channel *channel, + const u8 *msg); +void tell_gossipd_local_channel_announce(struct lightningd *ld, + struct channel *channel, + const u8 *msg); +void tell_gossipd_local_private_channel(struct lightningd *ld, + struct channel *channel, + struct amount_sat capacity, + const u8 *features); + #endif /* LIGHTNING_LIGHTNINGD_GOSSIP_CONTROL_H */