Skip to content

Commit ab80345

Browse files
committed
lightningd: maintain a hash table of short_channel_id, for faster lookup.
This contains real scids, as well as aliases, and old scids. Signed-off-by: Rusty Russell <[email protected]>
1 parent d70fc13 commit ab80345

File tree

9 files changed

+115
-15
lines changed

9 files changed

+115
-15
lines changed

lightningd/channel.c

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,60 @@ struct channel_type *desired_channel_type(const tal_t *ctx,
254254
return channel_type_static_remotekey(ctx);
255255
}
256256

257+
static void chanmap_remove(struct lightningd *ld,
258+
const struct channel *channel,
259+
struct short_channel_id scid)
260+
{
261+
struct scid_to_channel *scc = channel_scid_map_get(ld->channels_by_scid, scid);
262+
assert(scc->channel == channel);
263+
tal_free(scc);
264+
}
265+
266+
static void destroy_scid_to_channel(struct scid_to_channel *scc,
267+
struct lightningd *ld)
268+
{
269+
if (!channel_scid_map_del(ld->channels_by_scid, scc))
270+
abort();
271+
}
272+
273+
static void chanmap_add(struct lightningd *ld,
274+
struct channel *channel,
275+
struct short_channel_id scid)
276+
{
277+
struct scid_to_channel *scc = tal(channel, struct scid_to_channel);
278+
scc->channel = channel;
279+
scc->scid = scid;
280+
channel_scid_map_add(ld->channels_by_scid, scc);
281+
tal_add_destructor2(scc, destroy_scid_to_channel, ld);
282+
}
283+
284+
static void channel_set_random_local_alias(struct channel *channel)
285+
{
286+
assert(channel->alias[LOCAL] == NULL);
287+
channel->alias[LOCAL] = tal(channel, struct short_channel_id);
288+
randombytes_buf(channel->alias[LOCAL], sizeof(struct short_channel_id));
289+
/* We don't check for uniqueness. We would crash on a clash, but your machine is
290+
* probably broken beyond repair if it gets two equal 64 bit numbers */
291+
chanmap_add(channel->peer->ld, channel, *channel->alias[LOCAL]);
292+
}
293+
294+
void channel_set_scid(struct channel *channel, const struct short_channel_id *new_scid)
295+
{
296+
struct lightningd *ld = channel->peer->ld;
297+
298+
/* Get rid of old one (if any) */
299+
if (channel->scid != NULL) {
300+
chanmap_remove(ld, channel, *channel->scid);
301+
channel->scid = tal_free(channel->scid);
302+
}
303+
304+
/* Add new one (if any) */
305+
if (new_scid) {
306+
channel->scid = tal_dup(channel, struct short_channel_id, new_scid);
307+
chanmap_add(ld, channel, *new_scid);
308+
}
309+
}
310+
257311
void channel_add_old_scid(struct channel *channel,
258312
struct short_channel_id old_scid)
259313
{
@@ -265,6 +319,8 @@ void channel_add_old_scid(struct channel *channel,
265319
channel->old_scids = tal_dup(channel, struct short_channel_id, &old_scid);
266320
else
267321
tal_arr_expand(&channel->old_scids, old_scid);
322+
323+
chanmap_add(channel->peer->ld, channel, old_scid);
268324
}
269325

270326
struct channel *new_unsaved_channel(struct peer *peer,
@@ -312,10 +368,8 @@ struct channel *new_unsaved_channel(struct peer *peer,
312368
= CLOSING_FEE_NEGOTIATION_STEP_UNIT_PERCENTAGE;
313369
channel->shutdown_wrong_funding = NULL;
314370
channel->closing_feerate_range = NULL;
315-
channel->alias[REMOTE] = NULL;
316-
/* We don't even bother checking for clashes. */
317-
channel->alias[LOCAL] = tal(channel, struct short_channel_id);
318-
randombytes_buf(channel->alias[LOCAL], sizeof(struct short_channel_id));
371+
channel->alias[REMOTE] = channel->alias[LOCAL] = NULL;
372+
channel_set_random_local_alias(channel);
319373

320374
channel->shutdown_scriptpubkey[REMOTE] = NULL;
321375
channel->last_was_revoke = false;
@@ -567,11 +621,19 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
567621
channel->scid = tal_steal(channel, scid);
568622
channel->old_scids = tal_dup_talarr(channel, struct short_channel_id, old_scids);
569623
channel->alias[LOCAL] = tal_dup_or_null(channel, struct short_channel_id, alias_local);
624+
/* All these possible short_channel_id variants go in the lookup table! */
625+
/* Stub channels all have the same scid though, *and* get loaded from db! */
626+
if (channel->scid && !is_stub_scid(*channel->scid))
627+
chanmap_add(peer->ld, channel, *channel->scid);
628+
if (channel->alias[LOCAL])
629+
chanmap_add(peer->ld, channel, *channel->alias[LOCAL]);
630+
for (size_t i = 0; i < tal_count(channel->old_scids); i++)
631+
chanmap_add(peer->ld, channel, channel->old_scids[i]);
632+
570633
/* We always make sure this is set (historical channels from db might not) */
571-
if (!channel->alias[LOCAL]) {
572-
channel->alias[LOCAL] = tal(channel, struct short_channel_id);
573-
randombytes_buf(channel->alias[LOCAL], sizeof(struct short_channel_id));
574-
}
634+
if (!channel->alias[LOCAL])
635+
channel_set_random_local_alias(channel);
636+
575637
channel->alias[REMOTE] = tal_steal(channel, alias_remote); /* Haven't gotten one yet. */
576638
channel->cid = *cid;
577639
channel->our_msat = our_msat;

lightningd/channel.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef LIGHTNING_LIGHTNINGD_CHANNEL_H
22
#define LIGHTNING_LIGHTNINGD_CHANNEL_H
33
#include "config.h"
4+
#include <ccan/htable/htable_type.h>
45
#include <common/channel_config.h>
56
#include <common/channel_id.h>
67
#include <common/channel_type.h>
@@ -844,6 +845,35 @@ struct channel *peer_any_channel_bystate(struct peer *peer,
844845

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

848+
struct scid_to_channel {
849+
struct short_channel_id scid;
850+
struct channel *channel;
851+
};
852+
853+
static inline const struct short_channel_id scid_to_channel_key(const struct scid_to_channel *scidchan)
854+
{
855+
return scidchan->scid;
856+
}
857+
858+
static inline bool scid_to_channel_eq_scid(const struct scid_to_channel *scidchan,
859+
struct short_channel_id scid)
860+
{
861+
return short_channel_id_eq(scidchan->scid, scid);
862+
}
863+
864+
/* Define channel_scid_map */
865+
HTABLE_DEFINE_NODUPS_TYPE(struct scid_to_channel,
866+
scid_to_channel_key,
867+
short_channel_id_hash,
868+
scid_to_channel_eq_scid,
869+
channel_scid_map);
870+
871+
/* The only allowed way to set channel->scid */
872+
void channel_set_scid(struct channel *channel, const struct short_channel_id *new_scid);
873+
874+
/* The only allowed way to set channel->alias[LOCAL] */
875+
void channel_set_local_alias(struct channel *channel, struct short_channel_id alias_scid);
876+
847877
/* Includes both real scids and aliases. If !privacy_leak_ok, then private
848878
* channels' real scids are not included. */
849879
struct channel *any_channel_by_scid(struct lightningd *ld,

lightningd/channel_control.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,7 @@ bool depthcb_update_scid(struct channel *channel,
803803
if (!channel->scid) {
804804
wallet_annotate_txout(ld->wallet, outpoint,
805805
TX_CHANNEL_FUNDING, channel->dbid);
806-
channel->scid = tal_dup(channel, struct short_channel_id, &scid);
806+
channel_set_scid(channel, &scid);
807807

808808
/* If we have a zeroconf channel, i.e., no scid yet
809809
* but have exchange `channel_ready` messages, then we
@@ -822,7 +822,7 @@ bool depthcb_update_scid(struct channel *channel,
822822
log_info(channel->log, "Short channel id changed from %s->%s",
823823
fmt_short_channel_id(tmpctx, *channel->scid),
824824
fmt_short_channel_id(tmpctx, scid));
825-
*channel->scid = scid;
825+
channel_set_scid(channel, &scid);
826826
/* In case we broadcast it before (e.g. splice!) */
827827
channel_add_old_scid(channel, old_scid);
828828
channel_gossip_scid_changed(channel);

lightningd/dual_open_control.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,15 +1038,15 @@ static enum watch_result opening_depth_cb(struct lightningd *ld,
10381038
if (!inflight->channel->scid) {
10391039
wallet_annotate_txout(ld->wallet, &inflight->funding->outpoint,
10401040
TX_CHANNEL_FUNDING, inflight->channel->dbid);
1041-
inflight->channel->scid = tal_dup(inflight->channel, struct short_channel_id, &scid);
1041+
channel_set_scid(inflight->channel, &scid);
10421042
wallet_channel_save(ld->wallet, inflight->channel);
10431043
} else if (!short_channel_id_eq(*inflight->channel->scid, scid)) {
10441044
/* We freaked out if required when original was
10451045
* removed, so just update now */
10461046
log_info(inflight->channel->log, "Short channel id changed from %s->%s",
10471047
fmt_short_channel_id(tmpctx, *inflight->channel->scid),
10481048
fmt_short_channel_id(tmpctx, scid));
1049-
*inflight->channel->scid = scid;
1049+
channel_set_scid(inflight->channel, &scid);
10501050
wallet_channel_save(ld->wallet, inflight->channel);
10511051
}
10521052

lightningd/lightningd.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ static struct lightningd *new_lightningd(const tal_t *ctx)
209209
ld->peers_by_dbid = tal(ld, struct peer_dbid_map);
210210
peer_dbid_map_init(ld->peers_by_dbid);
211211

212+
/*~ This speeds lookups for short_channel_ids to their channels. */
213+
ld->channels_by_scid = tal(ld, struct channel_scid_map);
214+
channel_scid_map_init(ld->channels_by_scid);
215+
212216
/*~ For multi-part payments, we need to keep some incoming payments
213217
* in limbo until we get all the parts, or we time them out. */
214218
ld->htlc_sets = tal(ld, struct htlc_set_map);

lightningd/lightningd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ struct lightningd {
215215
struct peer_node_id_map *peers;
216216
/* And those in database by dbid */
217217
struct peer_dbid_map *peers_by_dbid;
218+
/* Here are all our channels and their aliases */
219+
struct channel_scid_map *channels_by_scid;
218220

219221
/* Outstanding connect commands. */
220222
struct list_head connects;

lightningd/memdump.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <gossipd/gossipd_wiregen.h>
1212
#include <hsmd/hsmd_wiregen.h>
1313
#include <lightningd/chaintopology.h>
14+
#include <lightningd/channel.h>
1415
#include <lightningd/closed_channel.h>
1516
#include <lightningd/hsm_control.h>
1617
#include <lightningd/jsonrpc.h>
@@ -202,6 +203,7 @@ static bool lightningd_check_leaks(struct command *cmd)
202203
memleak_scan_htable(memtable, &ld->htlc_sets->raw);
203204
memleak_scan_htable(memtable, &ld->peers->raw);
204205
memleak_scan_htable(memtable, &ld->peers_by_dbid->raw);
206+
memleak_scan_htable(memtable, &ld->channels_by_scid->raw);
205207
memleak_scan_htable(memtable, &ld->closed_channels->raw);
206208
wallet_memleak_scan(memtable, ld->wallet);
207209

lightningd/opening_control.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,8 +1589,8 @@ static struct channel *stub_chan(struct command *cmd,
15891589
true, /* remote_channel_ready */
15901590
scid,
15911591
NULL,
1592-
scid,
1593-
scid,
1592+
NULL,
1593+
NULL,
15941594
&cid,
15951595
/* The three arguments below are msatoshi_to_us,
15961596
* msatoshi_to_us_min, and msatoshi_to_us_max.

lightningd/peer_control.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2225,7 +2225,7 @@ static enum watch_result funding_depth_cb(struct lightningd *ld,
22252225
/* That's not entirely unexpected in early states */
22262226
log_debug(channel->log, "Funding tx %s reorganized out!",
22272227
fmt_bitcoin_txid(tmpctx, txid));
2228-
channel->scid = tal_free(channel->scid);
2228+
channel_set_scid(channel, NULL);
22292229
return KEEP_WATCHING;
22302230

22312231
/* But it's often Bad News in later states */

0 commit comments

Comments
 (0)