From 933c1794a10aab5c37570020ae74e1e9b9576abb Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 29 Nov 2017 09:22:32 +1030 Subject: [PATCH] gossipd: gossip_get_update / gossip_get_update_reply from channeld. Signed-off-by: Rusty Russell --- gossipd/gossip.c | 49 +++++++++++++++++++++++++++++++++++++ gossipd/gossip_wire.csv | 11 +++++++++ lightningd/gossip_control.c | 2 ++ 3 files changed, 62 insertions(+) diff --git a/gossipd/gossip.c b/gossipd/gossip.c index 64f6e019f..43d9b4309 100644 --- a/gossipd/gossip.c +++ b/gossipd/gossip.c @@ -599,6 +599,51 @@ static struct io_plan *peer_start_gossip(struct io_conn *conn, struct peer *peer peer_pkt_out(conn, peer)); } +static void handle_get_update(struct peer *peer, const u8 *msg) +{ + struct short_channel_id schanid; + struct node *us; + size_t i; + const u8 *update; + + if (!fromwire_gossip_get_update(msg, NULL, &schanid)) { + status_trace("peer %s sent bad gossip_get_update %s", + type_to_string(trc, struct pubkey, &peer->id), + tal_hex(trc, msg)); + return; + } + + /* We want update than comes from our end. */ + us = node_map_get(peer->daemon->rstate->nodes, &peer->daemon->id.pubkey); + if (!us) { + status_trace("peer %s schanid %s but can't find ourselves", + type_to_string(trc, struct pubkey, &peer->id), + type_to_string(trc, struct short_channel_id, + &schanid)); + update = NULL; + goto reply; + } + + for (i = 0; i < tal_count(us->out); i++) { + if (!short_channel_id_eq(&us->out[i]->short_channel_id, + &schanid)) + continue; + + update = us->out[i]->channel_update; + status_trace("peer %s schanid %s: %s update", + type_to_string(trc, struct pubkey, &peer->id), + type_to_string(trc, struct short_channel_id, + &schanid), + update ? "got" : "no"); + goto reply; + } + update = NULL; + +reply: + msg = towire_gossip_get_update_reply(msg, update); + msg_enqueue(&peer->peer_out, take(msg)); +} + /** * owner_msg_in - Called by the `peer->owner_conn` upon receiving a * message @@ -613,6 +658,8 @@ static struct io_plan *owner_msg_in(struct io_conn *conn, if (type == WIRE_CHANNEL_ANNOUNCEMENT || type == WIRE_CHANNEL_UPDATE || type == WIRE_NODE_ANNOUNCEMENT) { handle_gossip_msg(peer->daemon->rstate, dc->msg_in); + } else if (type == WIRE_GOSSIP_GET_UPDATE) { + handle_get_update(peer, dc->msg_in); } return daemon_conn_read_next(conn, dc); } @@ -1380,6 +1427,8 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master case WIRE_GOSSIP_RESOLVE_CHANNEL_REPLY: case WIRE_GOSSIP_PEER_CONNECTED: case WIRE_GOSSIP_PEER_NONGOSSIP: + case WIRE_GOSSIP_GET_UPDATE: + case WIRE_GOSSIP_GET_UPDATE_REPLY: break; } diff --git a/gossipd/gossip_wire.csv b/gossipd/gossip_wire.csv index f151ecf9d..a0c59a66f 100644 --- a/gossipd/gossip_wire.csv +++ b/gossipd/gossip_wire.csv @@ -131,3 +131,14 @@ gossip_getpeers_reply,3111 gossip_getpeers_reply,,num,u16 gossip_getpeers_reply,,id,num*struct pubkey gossip_getpeers_reply,,addr,num*struct wireaddr + +# Channel daemon can ask for updates for a specific channel, for sending +# errors. Must be distinct from WIRE_CHANNEL_ANNOUNCEMENT etc. gossip msgs! +gossip_get_update,3012 +gossip_get_update,,short_channel_id,struct short_channel_id + +# If channel isn't known, update will be empty. +gossip_get_update_reply,3112 +gossip_get_update_reply,,len,u16 +gossip_get_update_reply,,update,len*u8 + diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index c2e5c006b..95830efe8 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -68,7 +68,9 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) case WIRE_GOSSIPCTL_HANDLE_PEER: case WIRE_GOSSIPCTL_RELEASE_PEER: case WIRE_GOSSIPCTL_PEER_ADDRHINT: + case WIRE_GOSSIP_GET_UPDATE: /* This is a reply, so never gets through to here. */ + case WIRE_GOSSIP_GET_UPDATE_REPLY: case WIRE_GOSSIP_GETNODES_REPLY: case WIRE_GOSSIP_GETROUTE_REPLY: case WIRE_GOSSIP_GETCHANNELS_REPLY: