mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-02 18:35:00 +01:00
lightingd: do a local short_channel_id lookup for forwarding.
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>
This commit is contained in:
parent
40e3566e9a
commit
f8a21f16c9
8 changed files with 30 additions and 132 deletions
|
@ -73,15 +73,6 @@ msgdata,gossip_ping_reply,totlen,u16,
|
||||||
msgtype,gossip_dev_set_max_scids_encode_size,3030
|
msgtype,gossip_dev_set_max_scids_encode_size,3030
|
||||||
msgdata,gossip_dev_set_max_scids_encode_size,max,u32,
|
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.
|
# Given a short_channel_id, return the latest (stripped) update for error msg.
|
||||||
msgtype,gossip_get_stripped_cupdate,3010
|
msgtype,gossip_get_stripped_cupdate,3010
|
||||||
msgdata,gossip_get_stripped_cupdate,channel_id,short_channel_id,
|
msgdata,gossip_get_stripped_cupdate,channel_id,short_channel_id,
|
||||||
|
|
Can't render this file because it has a wrong number of fields in line 6.
|
|
@ -1335,48 +1335,6 @@ static struct io_plan *dev_gossip_set_time(struct io_conn *conn,
|
||||||
}
|
}
|
||||||
#endif /* DEVELOPER */
|
#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,
|
/*~ lightningd: so, get me the latest update for this local channel,
|
||||||
* so I can include it in an error message. */
|
* so I can include it in an error message. */
|
||||||
static struct io_plan *get_stripped_cupdate(struct io_conn *conn,
|
static struct io_plan *get_stripped_cupdate(struct io_conn *conn,
|
||||||
|
@ -1611,9 +1569,6 @@ static struct io_plan *recv_req(struct io_conn *conn,
|
||||||
case WIRE_GOSSIP_GETCHANNELS_REQUEST:
|
case WIRE_GOSSIP_GETCHANNELS_REQUEST:
|
||||||
return getchannels_req(conn, daemon, msg);
|
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:
|
case WIRE_GOSSIP_GET_STRIPPED_CUPDATE:
|
||||||
return get_stripped_cupdate(conn, daemon, msg);
|
return get_stripped_cupdate(conn, daemon, msg);
|
||||||
|
|
||||||
|
@ -1663,7 +1618,6 @@ static struct io_plan *recv_req(struct io_conn *conn,
|
||||||
case WIRE_GOSSIP_GETROUTE_REPLY:
|
case WIRE_GOSSIP_GETROUTE_REPLY:
|
||||||
case WIRE_GOSSIP_GETCHANNELS_REPLY:
|
case WIRE_GOSSIP_GETCHANNELS_REPLY:
|
||||||
case WIRE_GOSSIP_PING_REPLY:
|
case WIRE_GOSSIP_PING_REPLY:
|
||||||
case WIRE_GOSSIP_GET_CHANNEL_PEER_REPLY:
|
|
||||||
case WIRE_GOSSIP_GET_STRIPPED_CUPDATE_REPLY:
|
case WIRE_GOSSIP_GET_STRIPPED_CUPDATE_REPLY:
|
||||||
case WIRE_GOSSIP_GET_INCOMING_CHANNELS_REPLY:
|
case WIRE_GOSSIP_GET_INCOMING_CHANNELS_REPLY:
|
||||||
case WIRE_GOSSIP_GET_TXOUT:
|
case WIRE_GOSSIP_GET_TXOUT:
|
||||||
|
|
|
@ -328,6 +328,22 @@ struct channel *active_channel_by_id(struct lightningd *ld,
|
||||||
return peer_active_channel(peer);
|
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 channel *channel_by_dbid(struct lightningd *ld, const u64 dbid)
|
||||||
{
|
{
|
||||||
struct peer *p;
|
struct peer *p;
|
||||||
|
|
|
@ -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 *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,
|
void channel_set_last_tx(struct channel *channel,
|
||||||
struct bitcoin_tx *tx,
|
struct bitcoin_tx *tx,
|
||||||
const struct bitcoin_signature *sig,
|
const struct bitcoin_signature *sig,
|
||||||
|
|
|
@ -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_GETROUTE_REQUEST:
|
||||||
case WIRE_GOSSIP_GETCHANNELS_REQUEST:
|
case WIRE_GOSSIP_GETCHANNELS_REQUEST:
|
||||||
case WIRE_GOSSIP_PING:
|
case WIRE_GOSSIP_PING:
|
||||||
case WIRE_GOSSIP_GET_CHANNEL_PEER:
|
|
||||||
case WIRE_GOSSIP_GET_STRIPPED_CUPDATE:
|
case WIRE_GOSSIP_GET_STRIPPED_CUPDATE:
|
||||||
case WIRE_GOSSIP_GET_TXOUT_REPLY:
|
case WIRE_GOSSIP_GET_TXOUT_REPLY:
|
||||||
case WIRE_GOSSIP_OUTPOINT_SPENT:
|
case WIRE_GOSSIP_OUTPOINT_SPENT:
|
||||||
|
@ -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_GETNODES_REPLY:
|
||||||
case WIRE_GOSSIP_GETROUTE_REPLY:
|
case WIRE_GOSSIP_GETROUTE_REPLY:
|
||||||
case WIRE_GOSSIP_GETCHANNELS_REPLY:
|
case WIRE_GOSSIP_GETCHANNELS_REPLY:
|
||||||
case WIRE_GOSSIP_GET_CHANNEL_PEER_REPLY:
|
|
||||||
case WIRE_GOSSIP_GET_INCOMING_CHANNELS_REPLY:
|
case WIRE_GOSSIP_GET_INCOMING_CHANNELS_REPLY:
|
||||||
case WIRE_GOSSIP_DEV_MEMLEAK_REPLY:
|
case WIRE_GOSSIP_DEV_MEMLEAK_REPLY:
|
||||||
case WIRE_GOSSIP_DEV_COMPACT_STORE_REPLY:
|
case WIRE_GOSSIP_DEV_COMPACT_STORE_REPLY:
|
||||||
|
|
|
@ -1199,14 +1199,10 @@ command_find_channel(struct command *cmd,
|
||||||
tok->end - tok->start,
|
tok->end - tok->start,
|
||||||
buffer + tok->start);
|
buffer + tok->start);
|
||||||
} else if (json_to_short_channel_id(buffer, tok, &scid)) {
|
} else if (json_to_short_channel_id(buffer, tok, &scid)) {
|
||||||
list_for_each(&ld->peers, peer, list) {
|
*channel = active_channel_by_scid(ld, &scid);
|
||||||
*channel = peer_active_channel(peer);
|
if (*channel)
|
||||||
if (!*channel)
|
|
||||||
continue;
|
|
||||||
if ((*channel)->scid
|
|
||||||
&& (*channel)->scid->u64 == scid.u64)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Short channel ID not found: '%.*s'",
|
"Short channel ID not found: '%.*s'",
|
||||||
tok->end - tok->start,
|
tok->end - tok->start,
|
||||||
|
|
|
@ -657,13 +657,13 @@ static void forward_htlc(struct htlc_in *hin,
|
||||||
u32 cltv_expiry,
|
u32 cltv_expiry,
|
||||||
struct amount_msat amt_to_forward,
|
struct amount_msat amt_to_forward,
|
||||||
u32 outgoing_cltv_value,
|
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 next_onion[TOTAL_PACKET_SIZE])
|
||||||
{
|
{
|
||||||
const u8 *failmsg;
|
const u8 *failmsg;
|
||||||
struct amount_msat fee;
|
struct amount_msat fee;
|
||||||
struct lightningd *ld = hin->key.channel->peer->ld;
|
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;
|
struct htlc_out *hout = NULL;
|
||||||
bool needs_update_appended;
|
bool needs_update_appended;
|
||||||
|
|
||||||
|
@ -769,50 +769,6 @@ fail:
|
||||||
fromwire_peektype(failmsg));
|
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
|
* Data passed to the plugin, and as the context for the hook callback
|
||||||
*/
|
*/
|
||||||
|
@ -1014,7 +970,6 @@ htlc_accepted_hook_callback(struct htlc_accepted_hook_payload *request,
|
||||||
struct channel *channel = request->channel;
|
struct channel *channel = request->channel;
|
||||||
struct lightningd *ld = request->ld;
|
struct lightningd *ld = request->ld;
|
||||||
struct preimage payment_preimage;
|
struct preimage payment_preimage;
|
||||||
u8 *req;
|
|
||||||
enum htlc_accepted_result result;
|
enum htlc_accepted_result result;
|
||||||
const u8 *failmsg;
|
const u8 *failmsg;
|
||||||
result = htlc_accepted_hook_deserialize(request, ld, buffer, toks, &payment_preimage, &failmsg);
|
result = htlc_accepted_hook_deserialize(request, ld, buffer, toks, &payment_preimage, &failmsg);
|
||||||
|
@ -1027,20 +982,11 @@ htlc_accepted_hook_callback(struct htlc_accepted_hook_payload *request,
|
||||||
local_fail_in_htlc_badonion(hin,
|
local_fail_in_htlc_badonion(hin,
|
||||||
WIRE_INVALID_ONION_PAYLOAD);
|
WIRE_INVALID_ONION_PAYLOAD);
|
||||||
} else if (rs->nextcase == ONION_FORWARD) {
|
} else if (rs->nextcase == ONION_FORWARD) {
|
||||||
struct gossip_resolve *gr = tal(ld, struct gossip_resolve);
|
forward_htlc(hin, hin->cltv_expiry,
|
||||||
|
request->payload->amt_to_forward,
|
||||||
gr->next_onion = serialize_onionpacket(gr, rs->next);
|
request->payload->outgoing_cltv,
|
||||||
gr->next_channel = *request->payload->forward_channel;
|
request->payload->forward_channel,
|
||||||
gr->amt_to_forward = request->payload->amt_to_forward;
|
serialize_onionpacket(tmpctx, rs->next));
|
||||||
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);
|
|
||||||
} else
|
} else
|
||||||
handle_localpay(hin,
|
handle_localpay(hin,
|
||||||
request->payload->amt_to_forward,
|
request->payload->amt_to_forward,
|
||||||
|
|
|
@ -120,9 +120,6 @@ bool fromwire_connect_peer_connected(const tal_t *ctx UNNEEDED, const void *p UN
|
||||||
/* Generated stub for fromwire_custommsg_in */
|
/* Generated stub for fromwire_custommsg_in */
|
||||||
bool fromwire_custommsg_in(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **msg UNNEEDED)
|
bool fromwire_custommsg_in(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **msg UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire_custommsg_in called!\n"); abort(); }
|
{ 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 */
|
/* 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)
|
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(); }
|
{ fprintf(stderr, "fromwire_gossip_get_stripped_cupdate_reply called!\n"); abort(); }
|
||||||
|
@ -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 */
|
/* 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)
|
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(); }
|
{ 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 */
|
/* 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)
|
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(); }
|
{ fprintf(stderr, "towire_gossip_get_stripped_cupdate called!\n"); abort(); }
|
||||||
|
|
Loading…
Add table
Reference in a new issue