diff --git a/gossipd/Makefile b/gossipd/Makefile index 834ef400e..bdc50f6d1 100644 --- a/gossipd/Makefile +++ b/gossipd/Makefile @@ -15,10 +15,12 @@ LIGHTNINGD_GOSSIP_CONTROL_OBJS := $(LIGHTNINGD_GOSSIP_CONTROL_SRC:.c=.o) LIGHTNINGD_GOSSIP_HEADERS_WSRC := gossipd/gen_gossip_wire.h \ gossipd/gen_gossip_peerd_wire.h \ gossipd/gen_gossip_store.h \ + gossipd/gossipd.h \ gossipd/gossip_store.h \ + gossipd/make_gossip.h \ gossipd/routing.h LIGHTNINGD_GOSSIP_HEADERS := $(LIGHTNINGD_GOSSIP_HEADERS_WSRC) gossipd/broadcast.h -LIGHTNINGD_GOSSIP_SRC := $(LIGHTNINGD_GOSSIP_HEADERS_WSRC:.h=.c) gossipd/gossipd.c +LIGHTNINGD_GOSSIP_SRC := $(LIGHTNINGD_GOSSIP_HEADERS_WSRC:.h=.c) LIGHTNINGD_GOSSIP_OBJS := $(LIGHTNINGD_GOSSIP_SRC:.c=.o) # Make sure these depend on everything. diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index 6f2d1f684..26385444e 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -53,8 +52,9 @@ #include #include #include +#include +#include #include -#include #include #include #include @@ -71,11 +71,6 @@ #include #include -/* We talk to `hsmd` to sign our gossip messages with the node key */ -#define HSM_FD 3 -/* connectd asks us for help finding nodes, and gossip fds for new peers */ -#define CONNECTD_FD 4 - /* In developer mode we provide hooks for whitebox testing */ #if DEVELOPER static u32 max_encoding_bytes = -1U; @@ -110,52 +105,6 @@ static void towire_channel_update_timestamps(u8 **p, } #endif -/*~ The core daemon structure: */ -struct daemon { - /* Who am I? Helps us find ourself in the routing map. */ - struct node_id id; - - /* Peers we are gossiping to: id is unique */ - struct list_head peers; - - /* Connection to lightningd. */ - struct daemon_conn *master; - - /* Connection to connect daemon. */ - struct daemon_conn *connectd; - - /* Routing information */ - struct routing_state *rstate; - - /* chainhash for checking/making gossip msgs */ - struct bitcoin_blkid chain_hash; - - /* Timers: we batch gossip, and also refresh announcements */ - struct timers timers; - - /* Minimum interval for generating updated gossip */ - u32 gossip_min_interval; - - /* Global features to list in node_announcement. */ - u8 *globalfeatures; - - /* Alias (not NUL terminated) and favorite color for node_announcement */ - u8 alias[32]; - u8 rgb[3]; - - /* What addresses we can actually announce. */ - struct wireaddr *announcable; - - /* Do we think we're missing gossip? Contains timer to re-check */ - struct oneshot *gossip_missing; - - /* Channels we've heard about, but don't know. */ - struct short_channel_id *unknown_scids; - - /* Timer until we can send a new node_announcement */ - struct oneshot *node_announce_timer; -}; - /*~ How gossipy do we ask a peer to be? */ enum gossip_level { /* Give us everything since epoch */ @@ -264,7 +213,7 @@ static void destroy_peer(struct peer *peer) } /* Search for a peer. */ -static struct peer *find_peer(struct daemon *daemon, const struct node_id *id) +struct peer *find_peer(struct daemon *daemon, const struct node_id *id) { struct peer *peer; @@ -276,7 +225,7 @@ static struct peer *find_peer(struct daemon *daemon, const struct node_id *id) /* Queue a gossip message for the peer: the subdaemon on the other end simply * forwards it to the peer. */ -static void queue_peer_msg(struct peer *peer, const u8 *msg TAKES) +void queue_peer_msg(struct peer *peer, const u8 *msg TAKES) { daemon_conn_send(peer->dc, msg); } @@ -459,194 +408,6 @@ static void setup_gossip_range(struct peer *peer) queue_peer_msg(peer, take(msg)); } -/*~ Create a node_announcement with the given signature. It may be NULL in the - * case we need to create a provisional announcement for the HSM to sign. - * This is called twice: once with the dummy signature to get it signed and a - * second time to build the full packet with the signature. The timestamp is - * handed in rather than using time_now() internally, since that could change - * between the dummy creation and the call with a signature. */ -static u8 *create_node_announcement(const tal_t *ctx, struct daemon *daemon, - const secp256k1_ecdsa_signature *sig, - u32 timestamp) -{ - u8 *addresses = tal_arr(tmpctx, u8, 0); - u8 *announcement; - size_t i; - - if (!sig) - sig = talz(tmpctx, secp256k1_ecdsa_signature); - - for (i = 0; i < tal_count(daemon->announcable); i++) - towire_wireaddr(&addresses, &daemon->announcable[i]); - - announcement = - towire_node_announcement(ctx, sig, daemon->globalfeatures, timestamp, - &daemon->id, daemon->rgb, daemon->alias, - addresses); - return announcement; -} - -/* Helper to get non-signature, non-timestamp parts of (valid!) channel_update */ -static void get_cupdate_parts(const u8 *channel_update, - const u8 *parts[2], - size_t sizes[2]) -{ - /* BOLT #7: - * - * 1. type: 258 (`channel_update`) - * 2. data: - * * [`signature`:`signature`] - * * [`chain_hash`:`chain_hash`] - * * [`short_channel_id`:`short_channel_id`] - * * [`u32`:`timestamp`] - *... - */ - /* Note: 2 bytes for `type` field */ - /* We already checked it's valid before accepting */ - assert(tal_count(channel_update) > 2 + 64 + 32 + 8 + 4); - parts[0] = channel_update + 2 + 64; - sizes[0] = 32 + 8; - parts[1] = channel_update + 2 + 64 + 32 + 8 + 4; - sizes[1] = tal_count(channel_update) - (64 + 2 + 32 + 8 + 4); -} - -/*~ Is this channel_update different from prev (not sigs and timestamps)? */ -static bool cupdate_different(struct gossip_store *gs, - const struct half_chan *hc, - const u8 *cupdate) -{ - const u8 *oparts[2], *nparts[2]; - size_t osizes[2], nsizes[2]; - const u8 *orig; - - /* Get last one we have. */ - orig = gossip_store_get(tmpctx, gs, hc->bcast.index); - get_cupdate_parts(orig, oparts, osizes); - get_cupdate_parts(cupdate, nparts, nsizes); - - return !memeq(oparts[0], osizes[0], nparts[0], nsizes[0]) - || !memeq(oparts[1], osizes[1], nparts[1], nsizes[1]); -} - -/* Get non-signature, non-timestamp parts of (valid!) node_announcement */ -static void get_nannounce_parts(const u8 *node_announcement, - const u8 *parts[2], - size_t sizes[2]) -{ - size_t len; - const u8 *flen; - - /* BOLT #7: - * - * 1. type: 257 (`node_announcement`) - * 2. data: - * * [`signature`:`signature`] - * * [`u16`:`flen`] - * * [`flen*byte`:`features`] - * * [`u32`:`timestamp`] - *... - */ - /* Note: 2 bytes for `type` field */ - /* We already checked it's valid before accepting */ - assert(tal_count(node_announcement) > 2 + 64); - parts[0] = node_announcement + 2 + 64; - - /* Read flen to get size */ - flen = parts[0]; - len = tal_count(node_announcement) - (2 + 64); - sizes[0] = 2 + fromwire_u16(&flen, &len); - assert(flen != NULL && len >= 4); - - parts[1] = node_announcement + 2 + 64 + sizes[0] + 4; - sizes[1] = tal_count(node_announcement) - (2 + 64 + sizes[0] + 4); -} - -/*~ Is this node_announcement different from prev (not sigs and timestamps)? */ -static bool nannounce_different(struct gossip_store *gs, - const struct node *node, - const u8 *nannounce) -{ - const u8 *oparts[2], *nparts[2]; - size_t osizes[2], nsizes[2]; - const u8 *orig; - - /* Get last one we have. */ - orig = gossip_store_get(tmpctx, gs, node->bcast.index); - get_nannounce_parts(orig, oparts, osizes); - get_nannounce_parts(nannounce, nparts, nsizes); - - return !memeq(oparts[0], osizes[0], nparts[0], nsizes[0]) - || !memeq(oparts[1], osizes[1], nparts[1], nsizes[1]); -} - -/*~ This routine created a `node_announcement` for our node, and hands it to - * the routing.c code like any other `node_announcement`. Such announcements - * are only accepted if there is an announced channel associated with that node - * (to prevent spam), so we only call this once we've announced a channel. */ -static void update_own_node_announcement(struct daemon *daemon) -{ - u32 timestamp = gossip_time_now(daemon->rstate).ts.tv_sec; - secp256k1_ecdsa_signature sig; - u8 *msg, *nannounce, *err; - struct node *self = get_node(daemon->rstate, &daemon->id); - - /* Discard existing timer. */ - daemon->node_announce_timer = tal_free(daemon->node_announce_timer); - - /* Make unsigned announcement. */ - nannounce = create_node_announcement(tmpctx, daemon, NULL, timestamp); - - /* If it's the same as the previous, nothing to do. */ - if (self && self->bcast.index) { - u32 next; - - if (!nannounce_different(daemon->rstate->gs, self, nannounce)) - return; - - /* BOLT #7: - * - * The origin node: - * - MUST set `timestamp` to be greater than that of any - * previous `node_announcement` it has previously created. - */ - /* We do better: never send them within more than 5 minutes. */ - next = self->bcast.timestamp + daemon->gossip_min_interval; - - if (timestamp < next) { - status_debug("node_announcement: delaying %u secs", - next - timestamp); - daemon->node_announce_timer - = new_reltimer(&daemon->timers, - daemon, - time_from_sec(next - timestamp), - update_own_node_announcement, - daemon); - return; - } - } - - /* Ask hsmd to sign it (synchronous) */ - if (!wire_sync_write(HSM_FD, take(towire_hsm_node_announcement_sig_req(NULL, nannounce)))) - status_failed(STATUS_FAIL_MASTER_IO, "Could not write to HSM: %s", strerror(errno)); - - msg = wire_sync_read(tmpctx, HSM_FD); - if (!fromwire_hsm_node_announcement_sig_reply(msg, &sig)) - status_failed(STATUS_FAIL_MASTER_IO, "HSM returned an invalid node_announcement sig"); - - /* We got the signature for our provisional node_announcement back - * from the HSM, create the real announcement and forward it to - * gossipd so it can take care of forwarding it. */ - nannounce = create_node_announcement(NULL, daemon, &sig, timestamp); - - /* This injects it into the routing code in routing.c; it should not - * reject it! */ - err = handle_node_announcement(daemon->rstate, take(nannounce)); - if (err) - status_failed(STATUS_FAIL_INTERNAL_ERROR, - "rejected own node announcement: %s", - tal_hex(tmpctx, err)); -} - /*~ We don't actually keep node_announcements in memory; we keep them in * a file called `gossip_store`. If we need some node details, we reload * and reparse. It's slow, but generally rare. */ @@ -714,20 +475,6 @@ static bool get_node_announcement_by_id(const tal_t *ctx, features, wireaddrs); } -/* Should we announce our own node? Called at strategic places. */ -static void maybe_send_own_node_announce(struct daemon *daemon) -{ - /* We keep an internal flag in the routing code to say we've announced - * a local channel. The alternative would be to have it make a - * callback, but when we start up we don't want to make multiple - * announcments, so we use this approach for now. */ - if (!daemon->rstate->local_channel_announced) - return; - - update_own_node_announcement(daemon); - daemon->rstate->local_channel_announced = false; -} - /* Query this peer for these short-channel-ids. */ static bool query_short_channel_ids(struct daemon *daemon, struct peer *peer, @@ -1702,198 +1449,6 @@ static void dump_gossip(struct peer *peer) maybe_create_next_scid_reply(peer); } -/*~ Our timer callbacks take a single argument, so we marshall everything - * we need into this structure: */ -struct local_cupdate { - struct daemon *daemon; - struct local_chan *local_chan; - - bool disable; - bool even_if_identical; - - u16 cltv_expiry_delta; - struct amount_msat htlc_minimum, htlc_maximum; - u32 fee_base_msat, fee_proportional_millionths; -}; - -/*~ This generates a `channel_update` message for one of our channels. We do - * this here, rather than in `channeld` because we (may) need to do it - * ourselves anyway if channeld dies, or when we refresh it once a week, - * and so we can avoid creating redundant ones. */ -static void update_local_channel(struct local_cupdate *lc /* frees! */) -{ - struct daemon *daemon = lc->daemon; - secp256k1_ecdsa_signature dummy_sig; - u8 *update, *msg; - u32 timestamp = gossip_time_now(daemon->rstate).ts.tv_sec, next; - u8 message_flags, channel_flags; - struct chan *chan = lc->local_chan->chan; - struct half_chan *hc; - const int direction = lc->local_chan->direction; - - /* Discard existing timer. */ - lc->local_chan->channel_update_timer - = tal_free(lc->local_chan->channel_update_timer); - - /* So valgrind doesn't complain */ - memset(&dummy_sig, 0, sizeof(dummy_sig)); - - /* Create an unsigned channel_update: we backdate enables, so - * we can always send a disable in an emergency. */ - if (!lc->disable) - timestamp -= daemon->gossip_min_interval; - - /* BOLT #7: - * - * The `channel_flags` bitfield is used to indicate the direction of - * the channel: it identifies the node that this update originated - * from and signals various options concerning the channel. The - * following table specifies the meaning of its individual bits: - * - * | Bit Position | Name | Meaning | - * | ------------- | ----------- | -------------------------------- | - * | 0 | `direction` | Direction this update refers to. | - * | 1 | `disable` | Disable the channel. | - */ - channel_flags = direction; - if (lc->disable) - channel_flags |= ROUTING_FLAGS_DISABLED; - - /* BOLT #7: - * - * The `message_flags` bitfield is used to indicate the presence of - * optional fields in the `channel_update` message: - * - *| Bit Position | Name | Field | - *... - *| 0 | `option_channel_htlc_max` | `htlc_maximum_msat` | - */ - message_flags = 0 | ROUTING_OPT_HTLC_MAX_MSAT; - - /* We create an update with a dummy signature, and hand to hsmd to get - * it signed. */ - update = towire_channel_update_option_channel_htlc_max(tmpctx, &dummy_sig, - &daemon->chain_hash, - &chan->scid, - timestamp, - message_flags, channel_flags, - lc->cltv_expiry_delta, - lc->htlc_minimum, - lc->fee_base_msat, - lc->fee_proportional_millionths, - lc->htlc_maximum); - - hc = &chan->half[direction]; - if (is_halfchan_defined(hc)) { - /* Suppress duplicates. */ - if (!lc->even_if_identical - && !cupdate_different(daemon->rstate->gs, hc, update)) { - tal_free(lc); - return; - } - - /* Is it too soon to send another update? */ - next = hc->bcast.timestamp + daemon->gossip_min_interval; - - if (timestamp < next) { - status_debug("channel_update %s/%u: delaying %u secs", - type_to_string(tmpctx, - struct short_channel_id, - &chan->scid), - direction, - next - timestamp); - lc->local_chan->channel_update_timer - = new_reltimer(&daemon->timers, lc, - time_from_sec(next - timestamp), - update_local_channel, - lc); - /* If local chan vanishes, so does update, and timer. */ - notleak(tal_steal(lc->local_chan, lc)); - return; - } - } - - /* Note that we treat the hsmd as synchronous. This is simple (no - * callback hell)!, but may need to change to async if we ever want - * remote HSMs */ - if (!wire_sync_write(HSM_FD, - towire_hsm_cupdate_sig_req(tmpctx, update))) { - status_failed(STATUS_FAIL_HSM_IO, "Writing cupdate_sig_req: %s", - strerror(errno)); - } - - msg = wire_sync_read(tmpctx, HSM_FD); - if (!msg || !fromwire_hsm_cupdate_sig_reply(NULL, msg, &update)) { - status_failed(STATUS_FAIL_HSM_IO, - "Reading cupdate_sig_req: %s", - strerror(errno)); - } - - /* BOLT #7: - * - * The origin node: - * - MAY create a `channel_update` to communicate the channel parameters to the - * channel peer, even though the channel has not yet been announced (i.e. the - * `announce_channel` bit was not set). - */ - if (!is_chan_public(chan)) { - /* handle_channel_update will not put private updates in the - * broadcast list, but we send it direct to the peer (if we - * have one connected) now */ - struct peer *peer = find_peer(daemon, - &chan->nodes[!direction]->id); - if (peer) - queue_peer_msg(peer, update); - } - - /* We feed it into routing.c like any other channel_update; it may - * discard it (eg. non-public channel), but it should not complain - * about it being invalid! __func__ is a magic C constant which - * expands to this function name. */ - msg = handle_channel_update(daemon->rstate, take(update), __func__, - NULL); - if (msg) - status_failed(STATUS_FAIL_INTERNAL_ERROR, - "%s: rejected local channel update %s: %s", - __func__, - /* Normally we must not touch something taken() - * but we're in deep trouble anyway, and - * handle_channel_update only tal_steals onto - * tmpctx, so it's actually OK. */ - tal_hex(tmpctx, update), - tal_hex(tmpctx, msg)); - tal_free(lc); -} - -/*~ This is a refresh of a local channel: sends an update if one is needed. */ -static void refresh_local_channel(struct daemon *daemon, - struct local_chan *local_chan, - bool even_if_identical) -{ - const struct half_chan *hc; - struct local_cupdate *lc; - - hc = &local_chan->chan->half[local_chan->direction]; - - /* Don't generate a channel_update for an uninitialized channel. */ - if (!is_halfchan_defined(hc)) - return; - - lc = tal(NULL, struct local_cupdate); - lc->daemon = daemon; - lc->local_chan = local_chan; - lc->even_if_identical = even_if_identical; - lc->disable = (hc->channel_flags & ROUTING_FLAGS_DISABLED) - || local_chan->local_disabled; - lc->cltv_expiry_delta = hc->delay; - lc->htlc_minimum = hc->htlc_minimum; - lc->htlc_maximum = hc->htlc_maximum; - lc->fee_base_msat = hc->base_fee; - lc->fee_proportional_millionths = hc->proportional_fee; - - update_local_channel(lc); -} - /*~ This is when channeld asks us for a channel_update for a local channel. * It does that to fill in the error field when lightningd fails an HTLC and * sets the UPDATE bit in the error type. lightningd is too important to @@ -1948,52 +1503,6 @@ out: return true; } -/*~ channeld asks us to update the local channel. */ -static bool handle_local_channel_update(struct peer *peer, const u8 *msg) -{ - struct short_channel_id scid; - struct local_cupdate *lc = tal(tmpctx, struct local_cupdate); - - lc->daemon = peer->daemon; - lc->even_if_identical = false; - - /* 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, - &scid, - &lc->disable, - &lc->cltv_expiry_delta, - &lc->htlc_minimum, - &lc->fee_base_msat, - &lc->fee_proportional_millionths, - &lc->htlc_maximum)) { - status_broken("peer %s bad local_channel_update %s", - type_to_string(tmpctx, struct node_id, &peer->id), - tal_hex(tmpctx, msg)); - return false; - } - - lc->local_chan = local_chan_map_get(&peer->daemon->rstate->local_chan_map, - &scid); - /* Can theoretically happen if channel just closed. */ - if (!lc->local_chan) { - status_debug("peer %s local_channel_update for unknown %s", - type_to_string(tmpctx, struct node_id, &peer->id), - type_to_string(tmpctx, struct short_channel_id, - &scid)); - return true; - } - - /* Remove soft local_disabled flag, if they're marking it enabled. */ - if (!lc->disable) - local_enable_chan(peer->daemon->rstate, lc->local_chan->chan); - - /* Apply the update they told us */ - update_local_channel(tal_steal(NULL, lc)); - return true; -} - /*~ This is where the per-peer daemons send us messages. It's either forwarded * gossip, or a request for information. We deliberately use non-overlapping * message types so we can distinguish them. */ @@ -2069,7 +1578,7 @@ static struct io_plan *peer_msg_in(struct io_conn *conn, ok = handle_local_add_channel(peer->daemon->rstate, msg, 0); goto handled_cmd; case WIRE_GOSSIPD_LOCAL_CHANNEL_UPDATE: - ok = handle_local_channel_update(peer, msg); + ok = handle_local_channel_update(peer->daemon, &peer->id, msg); goto handled_cmd; /* These are the ones we send, not them */ diff --git a/gossipd/gossipd.h b/gossipd/gossipd.h new file mode 100644 index 000000000..fd11609f5 --- /dev/null +++ b/gossipd/gossipd.h @@ -0,0 +1,65 @@ +#ifndef LIGHTNING_GOSSIPD_GOSSIPD_H +#define LIGHTNING_GOSSIPD_GOSSIPD_H +#include "config.h" +#include +#include +#include + +/* We talk to `hsmd` to sign our gossip messages with the node key */ +#define HSM_FD 3 +/* connectd asks us for help finding nodes, and gossip fds for new peers */ +#define CONNECTD_FD 4 + +/*~ The core daemon structure: */ +struct daemon { + /* Who am I? Helps us find ourself in the routing map. */ + struct node_id id; + + /* Peers we are gossiping to: id is unique */ + struct list_head peers; + + /* Connection to lightningd. */ + struct daemon_conn *master; + + /* Connection to connect daemon. */ + struct daemon_conn *connectd; + + /* Routing information */ + struct routing_state *rstate; + + /* chainhash for checking/making gossip msgs */ + struct bitcoin_blkid chain_hash; + + /* Timers: we batch gossip, and also refresh announcements */ + struct timers timers; + + /* Minimum interval for generating updated gossip */ + u32 gossip_min_interval; + + /* Global features to list in node_announcement. */ + u8 *globalfeatures; + + /* Alias (not NUL terminated) and favorite color for node_announcement */ + u8 alias[32]; + u8 rgb[3]; + + /* What addresses we can actually announce. */ + struct wireaddr *announcable; + + /* Do we think we're missing gossip? Contains timer to re-check */ + struct oneshot *gossip_missing; + + /* Channels we've heard about, but don't know. */ + struct short_channel_id *unknown_scids; + + /* Timer until we can send a new node_announcement */ + struct oneshot *node_announce_timer; +}; + +/* Search for a peer. */ +struct peer *find_peer(struct daemon *daemon, const struct node_id *id); + +/* Queue a gossip message for the peer: the subdaemon on the other end simply + * forwards it to the peer. */ +void queue_peer_msg(struct peer *peer, const u8 *msg TAKES); +#endif /* LIGHTNING_GOSSIPD_GOSSIPD_H */ diff --git a/gossipd/make_gossip.c b/gossipd/make_gossip.c new file mode 100644 index 000000000..c308a18c9 --- /dev/null +++ b/gossipd/make_gossip.c @@ -0,0 +1,456 @@ +/* Routines to make our own gossip messages */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Create a node_announcement with the given signature. It may be NULL in the + * case we need to create a provisional announcement for the HSM to sign. + * This is called twice: once with the dummy signature to get it signed and a + * second time to build the full packet with the signature. The timestamp is + * handed in rather than using time_now() internally, since that could change + * between the dummy creation and the call with a signature. */ +static u8 *create_node_announcement(const tal_t *ctx, struct daemon *daemon, + const secp256k1_ecdsa_signature *sig, + u32 timestamp) +{ + u8 *addresses = tal_arr(tmpctx, u8, 0); + u8 *announcement; + size_t i; + + if (!sig) + sig = talz(tmpctx, secp256k1_ecdsa_signature); + + for (i = 0; i < tal_count(daemon->announcable); i++) + towire_wireaddr(&addresses, &daemon->announcable[i]); + + announcement = + towire_node_announcement(ctx, sig, daemon->globalfeatures, timestamp, + &daemon->id, daemon->rgb, daemon->alias, + addresses); + return announcement; +} + +/* Helper to get non-signature, non-timestamp parts of (valid!) channel_update */ +void get_cupdate_parts(const u8 *channel_update, + const u8 *parts[2], + size_t sizes[2]) +{ + /* BOLT #7: + * + * 1. type: 258 (`channel_update`) + * 2. data: + * * [`signature`:`signature`] + * * [`chain_hash`:`chain_hash`] + * * [`short_channel_id`:`short_channel_id`] + * * [`u32`:`timestamp`] + *... + */ + /* Note: 2 bytes for `type` field */ + /* We already checked it's valid before accepting */ + assert(tal_count(channel_update) > 2 + 64 + 32 + 8 + 4); + parts[0] = channel_update + 2 + 64; + sizes[0] = 32 + 8; + parts[1] = channel_update + 2 + 64 + 32 + 8 + 4; + sizes[1] = tal_count(channel_update) - (64 + 2 + 32 + 8 + 4); +} + +/* Is this channel_update different from prev (not sigs and timestamps)? */ +bool cupdate_different(struct gossip_store *gs, + const struct half_chan *hc, + const u8 *cupdate) +{ + const u8 *oparts[2], *nparts[2]; + size_t osizes[2], nsizes[2]; + const u8 *orig; + + /* Get last one we have. */ + orig = gossip_store_get(tmpctx, gs, hc->bcast.index); + get_cupdate_parts(orig, oparts, osizes); + get_cupdate_parts(cupdate, nparts, nsizes); + + return !memeq(oparts[0], osizes[0], nparts[0], nsizes[0]) + || !memeq(oparts[1], osizes[1], nparts[1], nsizes[1]); +} + +/* Get non-signature, non-timestamp parts of (valid!) node_announcement */ +static void get_nannounce_parts(const u8 *node_announcement, + const u8 *parts[2], + size_t sizes[2]) +{ + size_t len; + const u8 *flen; + + /* BOLT #7: + * + * 1. type: 257 (`node_announcement`) + * 2. data: + * * [`signature`:`signature`] + * * [`u16`:`flen`] + * * [`flen*byte`:`features`] + * * [`u32`:`timestamp`] + *... + */ + /* Note: 2 bytes for `type` field */ + /* We already checked it's valid before accepting */ + assert(tal_count(node_announcement) > 2 + 64); + parts[0] = node_announcement + 2 + 64; + + /* Read flen to get size */ + flen = parts[0]; + len = tal_count(node_announcement) - (2 + 64); + sizes[0] = 2 + fromwire_u16(&flen, &len); + assert(flen != NULL && len >= 4); + + parts[1] = node_announcement + 2 + 64 + sizes[0] + 4; + sizes[1] = tal_count(node_announcement) - (2 + 64 + sizes[0] + 4); +} + +/* Is this node_announcement different from prev (not sigs and timestamps)? */ +bool nannounce_different(struct gossip_store *gs, + const struct node *node, + const u8 *nannounce) +{ + const u8 *oparts[2], *nparts[2]; + size_t osizes[2], nsizes[2]; + const u8 *orig; + + /* Get last one we have. */ + orig = gossip_store_get(tmpctx, gs, node->bcast.index); + get_nannounce_parts(orig, oparts, osizes); + get_nannounce_parts(nannounce, nparts, nsizes); + + return !memeq(oparts[0], osizes[0], nparts[0], nsizes[0]) + || !memeq(oparts[1], osizes[1], nparts[1], nsizes[1]); +} + +/* This routine created a `node_announcement` for our node, and hands it to + * the routing.c code like any other `node_announcement`. Such announcements + * are only accepted if there is an announced channel associated with that node + * (to prevent spam), so we only call this once we've announced a channel. */ +static void update_own_node_announcement(struct daemon *daemon) +{ + u32 timestamp = gossip_time_now(daemon->rstate).ts.tv_sec; + secp256k1_ecdsa_signature sig; + u8 *msg, *nannounce, *err; + struct node *self = get_node(daemon->rstate, &daemon->id); + + /* Discard existing timer. */ + daemon->node_announce_timer = tal_free(daemon->node_announce_timer); + + /* Make unsigned announcement. */ + nannounce = create_node_announcement(tmpctx, daemon, NULL, timestamp); + + /* If it's the same as the previous, nothing to do. */ + if (self && self->bcast.index) { + u32 next; + + if (!nannounce_different(daemon->rstate->gs, self, nannounce)) + return; + + /* BOLT #7: + * + * The origin node: + * - MUST set `timestamp` to be greater than that of any + * previous `node_announcement` it has previously created. + */ + /* We do better: never send them within more than 5 minutes. */ + next = self->bcast.timestamp + daemon->gossip_min_interval; + + if (timestamp < next) { + status_debug("node_announcement: delaying %u secs", + next - timestamp); + daemon->node_announce_timer + = new_reltimer(&daemon->timers, + daemon, + time_from_sec(next - timestamp), + update_own_node_announcement, + daemon); + return; + } + } + + /* Ask hsmd to sign it (synchronous) */ + if (!wire_sync_write(HSM_FD, take(towire_hsm_node_announcement_sig_req(NULL, nannounce)))) + status_failed(STATUS_FAIL_MASTER_IO, "Could not write to HSM: %s", strerror(errno)); + + msg = wire_sync_read(tmpctx, HSM_FD); + if (!fromwire_hsm_node_announcement_sig_reply(msg, &sig)) + status_failed(STATUS_FAIL_MASTER_IO, "HSM returned an invalid node_announcement sig"); + + /* We got the signature for our provisional node_announcement back + * from the HSM, create the real announcement and forward it to + * gossipd so it can take care of forwarding it. */ + nannounce = create_node_announcement(NULL, daemon, &sig, timestamp); + + /* This injects it into the routing code in routing.c; it should not + * reject it! */ + err = handle_node_announcement(daemon->rstate, take(nannounce)); + if (err) + status_failed(STATUS_FAIL_INTERNAL_ERROR, + "rejected own node announcement: %s", + tal_hex(tmpctx, err)); +} + +/* Should we announce our own node? Called at strategic places. */ +void maybe_send_own_node_announce(struct daemon *daemon) +{ + /* We keep an internal flag in the routing code to say we've announced + * a local channel. The alternative would be to have it make a + * callback, but when we start up we don't want to make multiple + * announcments, so we use this approach for now. */ + if (!daemon->rstate->local_channel_announced) + return; + + update_own_node_announcement(daemon); + daemon->rstate->local_channel_announced = false; +} + +/* Our timer callbacks take a single argument, so we marshall everything + * we need into this structure: */ +struct local_cupdate { + struct daemon *daemon; + struct local_chan *local_chan; + + bool disable; + bool even_if_identical; + + u16 cltv_expiry_delta; + struct amount_msat htlc_minimum, htlc_maximum; + u32 fee_base_msat, fee_proportional_millionths; +}; + +/* This generates a `channel_update` message for one of our channels. We do + * this here, rather than in `channeld` because we (may) need to do it + * ourselves anyway if channeld dies, or when we refresh it once a week, + * and so we can avoid creating redundant ones. */ +static void update_local_channel(struct local_cupdate *lc /* frees! */) +{ + struct daemon *daemon = lc->daemon; + secp256k1_ecdsa_signature dummy_sig; + u8 *update, *msg; + u32 timestamp = gossip_time_now(daemon->rstate).ts.tv_sec, next; + u8 message_flags, channel_flags; + struct chan *chan = lc->local_chan->chan; + struct half_chan *hc; + const int direction = lc->local_chan->direction; + + /* Discard existing timer. */ + lc->local_chan->channel_update_timer + = tal_free(lc->local_chan->channel_update_timer); + + /* So valgrind doesn't complain */ + memset(&dummy_sig, 0, sizeof(dummy_sig)); + + /* Create an unsigned channel_update: we backdate enables, so + * we can always send a disable in an emergency. */ + if (!lc->disable) + timestamp -= daemon->gossip_min_interval; + + /* BOLT #7: + * + * The `channel_flags` bitfield is used to indicate the direction of + * the channel: it identifies the node that this update originated + * from and signals various options concerning the channel. The + * following table specifies the meaning of its individual bits: + * + * | Bit Position | Name | Meaning | + * | ------------- | ----------- | -------------------------------- | + * | 0 | `direction` | Direction this update refers to. | + * | 1 | `disable` | Disable the channel. | + */ + channel_flags = direction; + if (lc->disable) + channel_flags |= ROUTING_FLAGS_DISABLED; + + /* BOLT #7: + * + * The `message_flags` bitfield is used to indicate the presence of + * optional fields in the `channel_update` message: + * + *| Bit Position | Name | Field | + *... + *| 0 | `option_channel_htlc_max` | `htlc_maximum_msat` | + */ + message_flags = 0 | ROUTING_OPT_HTLC_MAX_MSAT; + + /* We create an update with a dummy signature, and hand to hsmd to get + * it signed. */ + update = towire_channel_update_option_channel_htlc_max(tmpctx, &dummy_sig, + &daemon->chain_hash, + &chan->scid, + timestamp, + message_flags, channel_flags, + lc->cltv_expiry_delta, + lc->htlc_minimum, + lc->fee_base_msat, + lc->fee_proportional_millionths, + lc->htlc_maximum); + + hc = &chan->half[direction]; + if (is_halfchan_defined(hc)) { + /* Suppress duplicates. */ + if (!lc->even_if_identical + && !cupdate_different(daemon->rstate->gs, hc, update)) { + tal_free(lc); + return; + } + + /* Is it too soon to send another update? */ + next = hc->bcast.timestamp + daemon->gossip_min_interval; + + if (timestamp < next) { + status_debug("channel_update %s/%u: delaying %u secs", + type_to_string(tmpctx, + struct short_channel_id, + &chan->scid), + direction, + next - timestamp); + lc->local_chan->channel_update_timer + = new_reltimer(&daemon->timers, lc, + time_from_sec(next - timestamp), + update_local_channel, + lc); + /* If local chan vanishes, so does update, and timer. */ + notleak(tal_steal(lc->local_chan, lc)); + return; + } + } + + /* Note that we treat the hsmd as synchronous. This is simple (no + * callback hell)!, but may need to change to async if we ever want + * remote HSMs */ + if (!wire_sync_write(HSM_FD, + towire_hsm_cupdate_sig_req(tmpctx, update))) { + status_failed(STATUS_FAIL_HSM_IO, "Writing cupdate_sig_req: %s", + strerror(errno)); + } + + msg = wire_sync_read(tmpctx, HSM_FD); + if (!msg || !fromwire_hsm_cupdate_sig_reply(NULL, msg, &update)) { + status_failed(STATUS_FAIL_HSM_IO, + "Reading cupdate_sig_req: %s", + strerror(errno)); + } + + /* BOLT #7: + * + * The origin node: + * - MAY create a `channel_update` to communicate the channel parameters to the + * channel peer, even though the channel has not yet been announced (i.e. the + * `announce_channel` bit was not set). + */ + if (!is_chan_public(chan)) { + /* handle_channel_update will not put private updates in the + * broadcast list, but we send it direct to the peer (if we + * have one connected) now */ + struct peer *peer = find_peer(daemon, + &chan->nodes[!direction]->id); + if (peer) + queue_peer_msg(peer, update); + } + + /* We feed it into routing.c like any other channel_update; it may + * discard it (eg. non-public channel), but it should not complain + * about it being invalid! __func__ is a magic C constant which + * expands to this function name. */ + msg = handle_channel_update(daemon->rstate, take(update), __func__, + NULL); + if (msg) + status_failed(STATUS_FAIL_INTERNAL_ERROR, + "%s: rejected local channel update %s: %s", + __func__, + /* Normally we must not touch something taken() + * but we're in deep trouble anyway, and + * handle_channel_update only tal_steals onto + * tmpctx, so it's actually OK. */ + tal_hex(tmpctx, update), + tal_hex(tmpctx, msg)); + tal_free(lc); +} + +/* This is a refresh of a local channel: sends an update if one is needed. */ +void refresh_local_channel(struct daemon *daemon, + struct local_chan *local_chan, + bool even_if_identical) +{ + const struct half_chan *hc; + struct local_cupdate *lc; + + hc = &local_chan->chan->half[local_chan->direction]; + + /* Don't generate a channel_update for an uninitialized channel. */ + if (!is_halfchan_defined(hc)) + return; + + lc = tal(NULL, struct local_cupdate); + lc->daemon = daemon; + lc->local_chan = local_chan; + lc->even_if_identical = even_if_identical; + lc->disable = (hc->channel_flags & ROUTING_FLAGS_DISABLED) + || local_chan->local_disabled; + lc->cltv_expiry_delta = hc->delay; + lc->htlc_minimum = hc->htlc_minimum; + lc->htlc_maximum = hc->htlc_maximum; + lc->fee_base_msat = hc->base_fee; + lc->fee_proportional_millionths = hc->proportional_fee; + + update_local_channel(lc); +} + +/* channeld asks us to update the local channel. */ +bool handle_local_channel_update(struct daemon *daemon, + const struct node_id *src, + const u8 *msg) +{ + struct short_channel_id scid; + struct local_cupdate *lc = tal(tmpctx, struct local_cupdate); + + lc->daemon = daemon; + lc->even_if_identical = false; + + /* 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, + &scid, + &lc->disable, + &lc->cltv_expiry_delta, + &lc->htlc_minimum, + &lc->fee_base_msat, + &lc->fee_proportional_millionths, + &lc->htlc_maximum)) { + status_broken("peer %s bad local_channel_update %s", + type_to_string(tmpctx, struct node_id, src), + tal_hex(tmpctx, msg)); + return false; + } + + lc->local_chan = local_chan_map_get(&daemon->rstate->local_chan_map, + &scid); + /* Can theoretically happen if channel just closed. */ + if (!lc->local_chan) { + status_debug("peer %s local_channel_update for unknown %s", + type_to_string(tmpctx, struct node_id, src), + type_to_string(tmpctx, struct short_channel_id, + &scid)); + return true; + } + + /* Remove soft local_disabled flag, if they're marking it enabled. */ + if (!lc->disable) + local_enable_chan(daemon->rstate, lc->local_chan->chan); + + /* Apply the update they told us */ + update_local_channel(tal_steal(NULL, lc)); + return true; +} diff --git a/gossipd/make_gossip.h b/gossipd/make_gossip.h new file mode 100644 index 000000000..88faca7d0 --- /dev/null +++ b/gossipd/make_gossip.h @@ -0,0 +1,47 @@ +#ifndef LIGHTNING_GOSSIPD_MAKE_GOSSIP_H +#define LIGHTNING_GOSSIPD_MAKE_GOSSIP_H +#include "config.h" +#include +#include +#include + +struct chan; +struct daemon; +struct half_chan; +struct local_chan; +struct gossip_store; +struct peer; +struct node; + +/* Helper to get non-signature, non-timestamp parts of (valid!) channel_update */ +void get_cupdate_parts(const u8 *channel_update, + const u8 *parts[2], + size_t sizes[2]); + + +/* Is this channel_update different from prev (not sigs and timestamps)? + * is_halfchan_defined(hc) must be true! */ +bool cupdate_different(struct gossip_store *gs, + const struct half_chan *hc, + const u8 *cupdate); + +/* Is this node_announcement different from prev (not sigs and timestamps)? + * node->bcast.index must be non-zero! */ +bool nannounce_different(struct gossip_store *gs, + const struct node *node, + const u8 *nannounce); + +/* Should we announce our own node? Called at strategic places. */ +void maybe_send_own_node_announce(struct daemon *daemon); + +/* This is a refresh of a local channel: sends an update if one is needed. */ +void refresh_local_channel(struct daemon *daemon, + struct local_chan *local_chan, + bool even_if_identical); + +/* channeld asks us to update the local channel. */ +bool handle_local_channel_update(struct daemon *daemon, + const struct node_id *src, + const u8 *msg); + +#endif /* LIGHTNING_GOSSIPD_MAKE_GOSSIP_H */ diff --git a/gossipd/test/run-crc32_of_update.c b/gossipd/test/run-crc32_of_update.c index 3bd067666..5d87a8e01 100644 --- a/gossipd/test/run-crc32_of_update.c +++ b/gossipd/test/run-crc32_of_update.c @@ -68,9 +68,6 @@ bool fromwire_gossip_dev_suppress(const void *p UNNEEDED) /* Generated stub for fromwire_gossipd_get_update */ bool fromwire_gossipd_get_update(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED) { fprintf(stderr, "fromwire_gossipd_get_update 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) -{ fprintf(stderr, "fromwire_gossipd_local_channel_update called!\n"); abort(); } /* Generated stub for fromwire_gossip_get_addrs */ bool fromwire_gossip_get_addrs(const void *p UNNEEDED, struct node_id *id UNNEEDED) { fprintf(stderr, "fromwire_gossip_get_addrs called!\n"); abort(); } @@ -116,18 +113,17 @@ bool fromwire_gossip_query_scids(const tal_t *ctx UNNEEDED, const void *p UNNEED /* Generated stub for fromwire_gossip_send_timestamp_filter */ bool fromwire_gossip_send_timestamp_filter(const void *p UNNEEDED, struct node_id *id UNNEEDED, u32 *first_timestamp UNNEEDED, u32 *timestamp_range UNNEEDED) { fprintf(stderr, "fromwire_gossip_send_timestamp_filter called!\n"); abort(); } -/* Generated stub for fromwire_hsm_cupdate_sig_reply */ -bool fromwire_hsm_cupdate_sig_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **cu UNNEEDED) -{ fprintf(stderr, "fromwire_hsm_cupdate_sig_reply called!\n"); abort(); } -/* Generated stub for fromwire_hsm_node_announcement_sig_reply */ -bool fromwire_hsm_node_announcement_sig_reply(const void *p UNNEEDED, secp256k1_ecdsa_signature *signature UNNEEDED) -{ fprintf(stderr, "fromwire_hsm_node_announcement_sig_reply called!\n"); abort(); } /* Generated stub for fromwire_incorrect_cltv_expiry */ bool fromwire_incorrect_cltv_expiry(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u32 *cltv_expiry UNNEEDED, u8 **channel_update UNNEEDED) { fprintf(stderr, "fromwire_incorrect_cltv_expiry called!\n"); abort(); } /* Generated stub for fromwire_temporary_channel_failure */ bool fromwire_temporary_channel_failure(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **channel_update UNNEEDED) { fprintf(stderr, "fromwire_temporary_channel_failure called!\n"); abort(); } +/* Generated stub for get_cupdate_parts */ +void get_cupdate_parts(const u8 *channel_update UNNEEDED, + const u8 *parts[2] UNNEEDED, + size_t sizes[2]) +{ fprintf(stderr, "get_cupdate_parts called!\n"); abort(); } /* Generated stub for get_node */ struct node *get_node(struct routing_state *rstate UNNEEDED, const struct node_id *id UNNEEDED) @@ -180,6 +176,11 @@ u8 *handle_channel_update(struct routing_state *rstate UNNEEDED, const u8 *updat bool handle_local_add_channel(struct routing_state *rstate UNNEEDED, const u8 *msg UNNEEDED, u64 index UNNEEDED) { fprintf(stderr, "handle_local_add_channel 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) +{ 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) { fprintf(stderr, "handle_node_announcement called!\n"); abort(); } @@ -195,6 +196,9 @@ u8 *make_ping(const tal_t *ctx UNNEEDED, u16 num_pong_bytes UNNEEDED, u16 padlen /* Generated stub for master_badmsg */ void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg) { fprintf(stderr, "master_badmsg called!\n"); abort(); } +/* Generated stub for maybe_send_own_node_announce */ +void maybe_send_own_node_announce(struct daemon *daemon UNNEEDED) +{ fprintf(stderr, "maybe_send_own_node_announce called!\n"); abort(); } /* Generated stub for memleak_enter_allocations */ struct htable *memleak_enter_allocations(const tal_t *ctx UNNEEDED, const void *exclude1 UNNEEDED, @@ -215,7 +219,7 @@ struct routing_state *new_routing_state(const tal_t *ctx UNNEEDED, const struct node_id *local_id UNNEEDED, u32 prune_timeout UNNEEDED, struct list_head *peers UNNEEDED, - const u32 *dev_gossip_time UNNEEDED) + const u32 *dev_gossip_time TAKES UNNEEDED) { fprintf(stderr, "new_routing_state called!\n"); abort(); } /* Generated stub for next_chan */ struct chan *next_chan(const struct node *node UNNEEDED, struct chan_map_iter *i UNNEEDED) @@ -226,6 +230,11 @@ void *notleak_(const void *ptr UNNEEDED, bool plus_children UNNEEDED) /* Generated stub for read_addresses */ struct wireaddr *read_addresses(const tal_t *ctx UNNEEDED, const u8 *ser UNNEEDED) { fprintf(stderr, "read_addresses called!\n"); abort(); } +/* Generated stub for refresh_local_channel */ +void refresh_local_channel(struct daemon *daemon UNNEEDED, + struct local_chan *local_chan UNNEEDED, + bool even_if_identical UNNEEDED) +{ fprintf(stderr, "refresh_local_channel called!\n"); abort(); } /* Generated stub for remove_channel_from_store */ void remove_channel_from_store(struct routing_state *rstate UNNEEDED, struct chan *chan UNNEEDED) @@ -308,21 +317,6 @@ u8 *towire_gossip_query_channel_range_reply(const tal_t *ctx UNNEEDED, u32 final /* Generated stub for towire_gossip_scids_reply */ u8 *towire_gossip_scids_reply(const tal_t *ctx UNNEEDED, bool ok UNNEEDED, bool complete UNNEEDED) { fprintf(stderr, "towire_gossip_scids_reply called!\n"); abort(); } -/* Generated stub for towire_hsm_cupdate_sig_req */ -u8 *towire_hsm_cupdate_sig_req(const tal_t *ctx UNNEEDED, const u8 *cu UNNEEDED) -{ fprintf(stderr, "towire_hsm_cupdate_sig_req called!\n"); abort(); } -/* Generated stub for towire_hsm_node_announcement_sig_req */ -u8 *towire_hsm_node_announcement_sig_req(const tal_t *ctx UNNEEDED, const u8 *announcement UNNEEDED) -{ fprintf(stderr, "towire_hsm_node_announcement_sig_req called!\n"); abort(); } -/* Generated stub for towire_wireaddr */ -void towire_wireaddr(u8 **pptr UNNEEDED, const struct wireaddr *addr UNNEEDED) -{ fprintf(stderr, "towire_wireaddr called!\n"); abort(); } -/* Generated stub for wire_sync_read */ -u8 *wire_sync_read(const tal_t *ctx UNNEEDED, int fd UNNEEDED) -{ fprintf(stderr, "wire_sync_read called!\n"); abort(); } -/* Generated stub for wire_sync_write */ -bool wire_sync_write(int fd UNNEEDED, const void *msg TAKES UNNEEDED) -{ fprintf(stderr, "wire_sync_write called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ #if EXPERIMENTAL_FEATURES diff --git a/gossipd/test/run-extended-info.c b/gossipd/test/run-extended-info.c index 65a7d661b..af0339461 100644 --- a/gossipd/test/run-extended-info.c +++ b/gossipd/test/run-extended-info.c @@ -91,9 +91,6 @@ bool fromwire_gossip_dev_suppress(const void *p UNNEEDED) /* Generated stub for fromwire_gossipd_get_update */ bool fromwire_gossipd_get_update(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED) { fprintf(stderr, "fromwire_gossipd_get_update 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) -{ fprintf(stderr, "fromwire_gossipd_local_channel_update called!\n"); abort(); } /* Generated stub for fromwire_gossip_get_addrs */ bool fromwire_gossip_get_addrs(const void *p UNNEEDED, struct node_id *id UNNEEDED) { fprintf(stderr, "fromwire_gossip_get_addrs called!\n"); abort(); } @@ -139,18 +136,17 @@ bool fromwire_gossip_query_scids(const tal_t *ctx UNNEEDED, const void *p UNNEED /* Generated stub for fromwire_gossip_send_timestamp_filter */ bool fromwire_gossip_send_timestamp_filter(const void *p UNNEEDED, struct node_id *id UNNEEDED, u32 *first_timestamp UNNEEDED, u32 *timestamp_range UNNEEDED) { fprintf(stderr, "fromwire_gossip_send_timestamp_filter called!\n"); abort(); } -/* Generated stub for fromwire_hsm_cupdate_sig_reply */ -bool fromwire_hsm_cupdate_sig_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **cu UNNEEDED) -{ fprintf(stderr, "fromwire_hsm_cupdate_sig_reply called!\n"); abort(); } -/* Generated stub for fromwire_hsm_node_announcement_sig_reply */ -bool fromwire_hsm_node_announcement_sig_reply(const void *p UNNEEDED, secp256k1_ecdsa_signature *signature UNNEEDED) -{ fprintf(stderr, "fromwire_hsm_node_announcement_sig_reply called!\n"); abort(); } /* Generated stub for fromwire_incorrect_cltv_expiry */ bool fromwire_incorrect_cltv_expiry(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u32 *cltv_expiry UNNEEDED, u8 **channel_update UNNEEDED) { fprintf(stderr, "fromwire_incorrect_cltv_expiry called!\n"); abort(); } /* Generated stub for fromwire_temporary_channel_failure */ bool fromwire_temporary_channel_failure(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **channel_update UNNEEDED) { fprintf(stderr, "fromwire_temporary_channel_failure called!\n"); abort(); } +/* Generated stub for get_cupdate_parts */ +void get_cupdate_parts(const u8 *channel_update UNNEEDED, + const u8 *parts[2] UNNEEDED, + size_t sizes[2]) +{ fprintf(stderr, "get_cupdate_parts called!\n"); abort(); } /* Generated stub for get_node */ struct node *get_node(struct routing_state *rstate UNNEEDED, const struct node_id *id UNNEEDED) @@ -203,6 +199,11 @@ u8 *handle_channel_update(struct routing_state *rstate UNNEEDED, const u8 *updat bool handle_local_add_channel(struct routing_state *rstate UNNEEDED, const u8 *msg UNNEEDED, u64 index UNNEEDED) { fprintf(stderr, "handle_local_add_channel 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) +{ 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) { fprintf(stderr, "handle_node_announcement called!\n"); abort(); } @@ -218,6 +219,9 @@ u8 *make_ping(const tal_t *ctx UNNEEDED, u16 num_pong_bytes UNNEEDED, u16 padlen /* Generated stub for master_badmsg */ void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg) { fprintf(stderr, "master_badmsg called!\n"); abort(); } +/* Generated stub for maybe_send_own_node_announce */ +void maybe_send_own_node_announce(struct daemon *daemon UNNEEDED) +{ fprintf(stderr, "maybe_send_own_node_announce called!\n"); abort(); } /* Generated stub for memleak_enter_allocations */ struct htable *memleak_enter_allocations(const tal_t *ctx UNNEEDED, const void *exclude1 UNNEEDED, @@ -238,7 +242,7 @@ struct routing_state *new_routing_state(const tal_t *ctx UNNEEDED, const struct node_id *local_id UNNEEDED, u32 prune_timeout UNNEEDED, struct list_head *peers UNNEEDED, - const u32 *dev_gossip_time UNNEEDED) + const u32 *dev_gossip_time TAKES UNNEEDED) { fprintf(stderr, "new_routing_state called!\n"); abort(); } /* Generated stub for next_chan */ struct chan *next_chan(const struct node *node UNNEEDED, struct chan_map_iter *i UNNEEDED) @@ -249,6 +253,11 @@ void *notleak_(const void *ptr UNNEEDED, bool plus_children UNNEEDED) /* Generated stub for read_addresses */ struct wireaddr *read_addresses(const tal_t *ctx UNNEEDED, const u8 *ser UNNEEDED) { fprintf(stderr, "read_addresses called!\n"); abort(); } +/* Generated stub for refresh_local_channel */ +void refresh_local_channel(struct daemon *daemon UNNEEDED, + struct local_chan *local_chan UNNEEDED, + bool even_if_identical UNNEEDED) +{ fprintf(stderr, "refresh_local_channel called!\n"); abort(); } /* Generated stub for remove_channel_from_store */ void remove_channel_from_store(struct routing_state *rstate UNNEEDED, struct chan *chan UNNEEDED) @@ -327,21 +336,6 @@ u8 *towire_gossip_query_channel_range_reply(const tal_t *ctx UNNEEDED, u32 final /* Generated stub for towire_gossip_scids_reply */ u8 *towire_gossip_scids_reply(const tal_t *ctx UNNEEDED, bool ok UNNEEDED, bool complete UNNEEDED) { fprintf(stderr, "towire_gossip_scids_reply called!\n"); abort(); } -/* Generated stub for towire_hsm_cupdate_sig_req */ -u8 *towire_hsm_cupdate_sig_req(const tal_t *ctx UNNEEDED, const u8 *cu UNNEEDED) -{ fprintf(stderr, "towire_hsm_cupdate_sig_req called!\n"); abort(); } -/* Generated stub for towire_hsm_node_announcement_sig_req */ -u8 *towire_hsm_node_announcement_sig_req(const tal_t *ctx UNNEEDED, const u8 *announcement UNNEEDED) -{ fprintf(stderr, "towire_hsm_node_announcement_sig_req called!\n"); abort(); } -/* Generated stub for towire_wireaddr */ -void towire_wireaddr(u8 **pptr UNNEEDED, const struct wireaddr *addr UNNEEDED) -{ fprintf(stderr, "towire_wireaddr called!\n"); abort(); } -/* Generated stub for wire_sync_read */ -u8 *wire_sync_read(const tal_t *ctx UNNEEDED, int fd UNNEEDED) -{ fprintf(stderr, "wire_sync_read called!\n"); abort(); } -/* Generated stub for wire_sync_write */ -bool wire_sync_write(int fd UNNEEDED, const void *msg TAKES UNNEEDED) -{ fprintf(stderr, "wire_sync_write called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ #if DEVELOPER