Skip to content

Commit

Permalink
lightingd: do a local short_channel_id lookup for forwarding.
Browse files Browse the repository at this point in the history
Even without optimization, it's faster to walk all the channels than
ping another daemon and wait for the response.

Changelog-Changed: Forwarding messages is now much faster (less inter-daemon traffic)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
  • Loading branch information
rustyrussell committed Feb 27, 2020
1 parent 40e3566 commit f8a21f1
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 132 deletions.
9 changes: 0 additions & 9 deletions gossipd/gossip_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,6 @@ msgdata,gossip_ping_reply,totlen,u16,
msgtype,gossip_dev_set_max_scids_encode_size,3030
msgdata,gossip_dev_set_max_scids_encode_size,max,u32,

# Given a short_channel_id, return the other endpoint (or none if DNE)
msgtype,gossip_get_channel_peer,3009
msgdata,gossip_get_channel_peer,channel_id,short_channel_id,

msgtype,gossip_get_channel_peer_reply,3109
msgdata,gossip_get_channel_peer_reply,peer_id,?node_id,
msgdata,gossip_get_channel_peer_reply,stripped_update_len,u16,
msgdata,gossip_get_channel_peer_reply,stripped_update,u8,stripped_update_len

# Given a short_channel_id, return the latest (stripped) update for error msg.
msgtype,gossip_get_stripped_cupdate,3010
msgdata,gossip_get_stripped_cupdate,channel_id,short_channel_id,
Expand Down
46 changes: 0 additions & 46 deletions gossipd/gossipd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1335,48 +1335,6 @@ static struct io_plan *dev_gossip_set_time(struct io_conn *conn,
}
#endif /* DEVELOPER */

/*~ lightningd: so, tell me about this channel, so we can forward to it. */
static struct io_plan *get_channel_peer(struct io_conn *conn,
struct daemon *daemon, const u8 *msg)
{
struct short_channel_id scid;
struct local_chan *local_chan;
const struct node_id *key;
const u8 *stripped_update;

if (!fromwire_gossip_get_channel_peer(msg, &scid))
master_badmsg(WIRE_GOSSIP_GET_CHANNEL_PEER, msg);

local_chan = local_chan_map_get(&daemon->rstate->local_chan_map, &scid);
if (!local_chan) {
status_debug("Failed to resolve local channel %s",
type_to_string(tmpctx, struct short_channel_id, &scid));
key = NULL;
stripped_update = NULL;
} else {
const struct half_chan *hc;

key = &local_chan->chan->nodes[!local_chan->direction]->id;
/* Since we're going to use it, make sure it's up-to-date. */
refresh_local_channel(daemon, local_chan, false);

hc = &local_chan->chan->half[local_chan->direction];
if (is_halfchan_defined(hc)) {
const u8 *update;

update = gossip_store_get(tmpctx, daemon->rstate->gs,
hc->bcast.index);
stripped_update = tal_dup_arr(tmpctx, u8, update + 2,
tal_count(update) - 2, 0);
} else
stripped_update = NULL;
}
daemon_conn_send(daemon->master,
take(towire_gossip_get_channel_peer_reply(NULL, key,
stripped_update)));
return daemon_conn_read_next(conn, daemon->master);
}

/*~ lightningd: so, get me the latest update for this local channel,
* so I can include it in an error message. */
static struct io_plan *get_stripped_cupdate(struct io_conn *conn,
Expand Down Expand Up @@ -1611,9 +1569,6 @@ static struct io_plan *recv_req(struct io_conn *conn,
case WIRE_GOSSIP_GETCHANNELS_REQUEST:
return getchannels_req(conn, daemon, msg);

case WIRE_GOSSIP_GET_CHANNEL_PEER:
return get_channel_peer(conn, daemon, msg);

case WIRE_GOSSIP_GET_STRIPPED_CUPDATE:
return get_stripped_cupdate(conn, daemon, msg);

Expand Down Expand Up @@ -1663,7 +1618,6 @@ static struct io_plan *recv_req(struct io_conn *conn,
case WIRE_GOSSIP_GETROUTE_REPLY:
case WIRE_GOSSIP_GETCHANNELS_REPLY:
case WIRE_GOSSIP_PING_REPLY:
case WIRE_GOSSIP_GET_CHANNEL_PEER_REPLY:
case WIRE_GOSSIP_GET_STRIPPED_CUPDATE_REPLY:
case WIRE_GOSSIP_GET_INCOMING_CHANNELS_REPLY:
case WIRE_GOSSIP_GET_TXOUT:
Expand Down
16 changes: 16 additions & 0 deletions lightningd/channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,22 @@ struct channel *active_channel_by_id(struct lightningd *ld,
return peer_active_channel(peer);
}

struct channel *active_channel_by_scid(struct lightningd *ld,
const struct short_channel_id *scid)
{
struct peer *p;
struct channel *chan;
list_for_each(&ld->peers, p, list) {
list_for_each(&p->channels, chan, list) {
if (channel_active(chan)
&& chan->scid
&& short_channel_id_eq(scid, chan->scid))
return chan;
}
}
return NULL;
}

struct channel *channel_by_dbid(struct lightningd *ld, const u64 dbid)
{
struct peer *p;
Expand Down
3 changes: 3 additions & 0 deletions lightningd/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,9 @@ struct channel *active_channel_by_id(struct lightningd *ld,

struct channel *channel_by_dbid(struct lightningd *ld, const u64 dbid);

struct channel *active_channel_by_scid(struct lightningd *ld,
const struct short_channel_id *scid);

void channel_set_last_tx(struct channel *channel,
struct bitcoin_tx *tx,
const struct bitcoin_signature *sig,
Expand Down
2 changes: 0 additions & 2 deletions lightningd/gossip_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
case WIRE_GOSSIP_GETROUTE_REQUEST:
case WIRE_GOSSIP_GETCHANNELS_REQUEST:
case WIRE_GOSSIP_PING:
case WIRE_GOSSIP_GET_CHANNEL_PEER:
case WIRE_GOSSIP_GET_STRIPPED_CUPDATE:
case WIRE_GOSSIP_GET_TXOUT_REPLY:
case WIRE_GOSSIP_OUTPOINT_SPENT:
Expand All @@ -155,7 +154,6 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
case WIRE_GOSSIP_GETNODES_REPLY:
case WIRE_GOSSIP_GETROUTE_REPLY:
case WIRE_GOSSIP_GETCHANNELS_REPLY:
case WIRE_GOSSIP_GET_CHANNEL_PEER_REPLY:
case WIRE_GOSSIP_GET_INCOMING_CHANNELS_REPLY:
case WIRE_GOSSIP_DEV_MEMLEAK_REPLY:
case WIRE_GOSSIP_DEV_COMPACT_STORE_REPLY:
Expand Down
12 changes: 4 additions & 8 deletions lightningd/peer_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -1199,14 +1199,10 @@ command_find_channel(struct command *cmd,
tok->end - tok->start,
buffer + tok->start);
} else if (json_to_short_channel_id(buffer, tok, &scid)) {
list_for_each(&ld->peers, peer, list) {
*channel = peer_active_channel(peer);
if (!*channel)
continue;
if ((*channel)->scid
&& (*channel)->scid->u64 == scid.u64)
return NULL;
}
*channel = active_channel_by_scid(ld, &scid);
if (*channel)
return NULL;

return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Short channel ID not found: '%.*s'",
tok->end - tok->start,
Expand Down
68 changes: 7 additions & 61 deletions lightningd/peer_htlcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -657,13 +657,13 @@ static void forward_htlc(struct htlc_in *hin,
u32 cltv_expiry,
struct amount_msat amt_to_forward,
u32 outgoing_cltv_value,
const struct node_id *next_hop,
const struct short_channel_id *scid,
const u8 next_onion[TOTAL_PACKET_SIZE])
{
const u8 *failmsg;
struct amount_msat fee;
struct lightningd *ld = hin->key.channel->peer->ld;
struct channel *next = active_channel_by_id(ld, next_hop, NULL);
struct channel *next = active_channel_by_scid(ld, scid);
struct htlc_out *hout = NULL;
bool needs_update_appended;

Expand Down Expand Up @@ -769,50 +769,6 @@ static void forward_htlc(struct htlc_in *hin,
fromwire_peektype(failmsg));
}

/* Temporary information, while we resolve the next hop */
struct gossip_resolve {
struct short_channel_id next_channel;
struct amount_msat amt_to_forward;
struct amount_msat total_msat;
/* Only set if TLV specifies it */
const struct secret *payment_secret;
u32 outgoing_cltv_value;
u8 *next_onion;
struct htlc_in *hin;
};

/* We received a resolver reply, which gives us the node_ids of the
* channel we want to forward over */
static void channel_resolve_reply(struct subd *gossip, const u8 *msg,
const int *fds UNUSED, struct gossip_resolve *gr)
{
struct node_id *peer_id;
u8 *stripped_update;

if (!fromwire_gossip_get_channel_peer_reply(msg, msg, &peer_id,
&stripped_update)) {
log_broken(gossip->log,
"bad fromwire_gossip_get_channel_peer_reply %s",
tal_hex(msg, msg));
return;
}

if (!peer_id) {
local_fail_in_htlc(gr->hin, take(towire_unknown_next_peer(NULL)));
wallet_forwarded_payment_add(gr->hin->key.channel->peer->ld->wallet,
gr->hin, &gr->next_channel, NULL,
FORWARD_LOCAL_FAILED,
WIRE_UNKNOWN_NEXT_PEER);
tal_free(gr);
return;
}

forward_htlc(gr->hin, gr->hin->cltv_expiry,
gr->amt_to_forward, gr->outgoing_cltv_value, peer_id,
gr->next_onion);
tal_free(gr);
}

/**
* Data passed to the plugin, and as the context for the hook callback
*/
Expand Down Expand Up @@ -1014,7 +970,6 @@ htlc_accepted_hook_callback(struct htlc_accepted_hook_payload *request,
struct channel *channel = request->channel;
struct lightningd *ld = request->ld;
struct preimage payment_preimage;
u8 *req;
enum htlc_accepted_result result;
const u8 *failmsg;
result = htlc_accepted_hook_deserialize(request, ld, buffer, toks, &payment_preimage, &failmsg);
Expand All @@ -1027,20 +982,11 @@ htlc_accepted_hook_callback(struct htlc_accepted_hook_payload *request,
local_fail_in_htlc_badonion(hin,
WIRE_INVALID_ONION_PAYLOAD);
} else if (rs->nextcase == ONION_FORWARD) {
struct gossip_resolve *gr = tal(ld, struct gossip_resolve);

gr->next_onion = serialize_onionpacket(gr, rs->next);
gr->next_channel = *request->payload->forward_channel;
gr->amt_to_forward = request->payload->amt_to_forward;
gr->outgoing_cltv_value = request->payload->outgoing_cltv;
gr->hin = hin;

req = towire_gossip_get_channel_peer(tmpctx, &gr->next_channel);
log_debug(channel->log, "Asking gossip to resolve channel %s",
type_to_string(tmpctx, struct short_channel_id,
&gr->next_channel));
subd_req(hin, ld->gossip, req, -1, 0,
channel_resolve_reply, gr);
forward_htlc(hin, hin->cltv_expiry,
request->payload->amt_to_forward,
request->payload->outgoing_cltv,
request->payload->forward_channel,
serialize_onionpacket(tmpctx, rs->next));
} else
handle_localpay(hin,
request->payload->amt_to_forward,
Expand Down
6 changes: 0 additions & 6 deletions wallet/test/run-wallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,6 @@ bool fromwire_connect_peer_connected(const tal_t *ctx UNNEEDED, const void *p UN
/* Generated stub for fromwire_custommsg_in */
bool fromwire_custommsg_in(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **msg UNNEEDED)
{ fprintf(stderr, "fromwire_custommsg_in called!\n"); abort(); }
/* Generated stub for fromwire_gossip_get_channel_peer_reply */
bool fromwire_gossip_get_channel_peer_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id **peer_id UNNEEDED, u8 **stripped_update UNNEEDED)
{ fprintf(stderr, "fromwire_gossip_get_channel_peer_reply called!\n"); abort(); }
/* Generated stub for fromwire_gossip_get_stripped_cupdate_reply */
bool fromwire_gossip_get_stripped_cupdate_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **stripped_update UNNEEDED)
{ fprintf(stderr, "fromwire_gossip_get_stripped_cupdate_reply called!\n"); abort(); }
Expand Down Expand Up @@ -642,9 +639,6 @@ u8 *towire_final_incorrect_cltv_expiry(const tal_t *ctx UNNEEDED, u32 cltv_expir
/* Generated stub for towire_final_incorrect_htlc_amount */
u8 *towire_final_incorrect_htlc_amount(const tal_t *ctx UNNEEDED, struct amount_msat incoming_htlc_amt UNNEEDED)
{ fprintf(stderr, "towire_final_incorrect_htlc_amount called!\n"); abort(); }
/* Generated stub for towire_gossip_get_channel_peer */
u8 *towire_gossip_get_channel_peer(const tal_t *ctx UNNEEDED, const struct short_channel_id *channel_id UNNEEDED)
{ fprintf(stderr, "towire_gossip_get_channel_peer called!\n"); abort(); }
/* Generated stub for towire_gossip_get_stripped_cupdate */
u8 *towire_gossip_get_stripped_cupdate(const tal_t *ctx UNNEEDED, const struct short_channel_id *channel_id UNNEEDED)
{ fprintf(stderr, "towire_gossip_get_stripped_cupdate called!\n"); abort(); }
Expand Down

0 comments on commit f8a21f1

Please sign in to comment.