Skip to content

Commit 0fb91f8

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 30afa74 commit 0fb91f8

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
@@ -242,6 +242,60 @@ struct open_attempt *new_channel_open_attempt(struct channel *channel)
242242
return oa;
243243
}
244244

245+
static void chanmap_remove(struct lightningd *ld,
246+
const struct channel *channel,
247+
struct short_channel_id scid)
248+
{
249+
struct scid_to_channel *scc = channel_scid_map_get(ld->channels_by_scid, scid);
250+
assert(scc->channel == channel);
251+
tal_free(scc);
252+
}
253+
254+
static void destroy_scid_to_channel(struct scid_to_channel *scc,
255+
struct lightningd *ld)
256+
{
257+
if (!channel_scid_map_del(ld->channels_by_scid, scc))
258+
abort();
259+
}
260+
261+
static void chanmap_add(struct lightningd *ld,
262+
struct channel *channel,
263+
struct short_channel_id scid)
264+
{
265+
struct scid_to_channel *scc = tal(channel, struct scid_to_channel);
266+
scc->channel = channel;
267+
scc->scid = scid;
268+
channel_scid_map_add(ld->channels_by_scid, scc);
269+
tal_add_destructor2(scc, destroy_scid_to_channel, ld);
270+
}
271+
272+
static void channel_set_random_local_alias(struct channel *channel)
273+
{
274+
assert(channel->alias[LOCAL] == NULL);
275+
channel->alias[LOCAL] = tal(channel, struct short_channel_id);
276+
randombytes_buf(channel->alias[LOCAL], sizeof(struct short_channel_id));
277+
/* We don't check for uniqueness. We would crash on a clash, but your machine is
278+
* probably broken beyond repair if it gets two equal 64 bit numbers */
279+
chanmap_add(channel->peer->ld, channel, *channel->alias[LOCAL]);
280+
}
281+
282+
void channel_set_scid(struct channel *channel, const struct short_channel_id *new_scid)
283+
{
284+
struct lightningd *ld = channel->peer->ld;
285+
286+
/* Get rid of old one (if any) */
287+
if (channel->scid != NULL) {
288+
chanmap_remove(ld, channel, *channel->scid);
289+
channel->scid = tal_free(channel->scid);
290+
}
291+
292+
/* Add new one (if any) */
293+
if (new_scid) {
294+
channel->scid = tal_dup(channel, struct short_channel_id, new_scid);
295+
chanmap_add(ld, channel, *new_scid);
296+
}
297+
}
298+
245299
void channel_add_old_scid(struct channel *channel,
246300
struct short_channel_id old_scid)
247301
{
@@ -253,6 +307,8 @@ void channel_add_old_scid(struct channel *channel,
253307
channel->old_scids = tal_dup(channel, struct short_channel_id, &old_scid);
254308
else
255309
tal_arr_expand(&channel->old_scids, old_scid);
310+
311+
chanmap_add(channel->peer->ld, channel, old_scid);
256312
}
257313

258314
struct channel *new_unsaved_channel(struct peer *peer,
@@ -300,10 +356,8 @@ struct channel *new_unsaved_channel(struct peer *peer,
300356
= CLOSING_FEE_NEGOTIATION_STEP_UNIT_PERCENTAGE;
301357
channel->shutdown_wrong_funding = NULL;
302358
channel->closing_feerate_range = NULL;
303-
channel->alias[REMOTE] = NULL;
304-
/* We don't even bother checking for clashes. */
305-
channel->alias[LOCAL] = tal(channel, struct short_channel_id);
306-
randombytes_buf(channel->alias[LOCAL], sizeof(struct short_channel_id));
359+
channel->alias[REMOTE] = channel->alias[LOCAL] = NULL;
360+
channel_set_random_local_alias(channel);
307361

308362
channel->shutdown_scriptpubkey[REMOTE] = NULL;
309363
channel->last_was_revoke = false;
@@ -555,11 +609,19 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
555609
channel->scid = tal_steal(channel, scid);
556610
channel->old_scids = tal_dup_talarr(channel, struct short_channel_id, old_scids);
557611
channel->alias[LOCAL] = tal_dup_or_null(channel, struct short_channel_id, alias_local);
612+
/* All these possible short_channel_id variants go in the lookup table! */
613+
/* Stub channels all have the same scid though, *and* get loaded from db! */
614+
if (channel->scid && !is_stub_scid(*channel->scid))
615+
chanmap_add(peer->ld, channel, *channel->scid);
616+
if (channel->alias[LOCAL])
617+
chanmap_add(peer->ld, channel, *channel->alias[LOCAL]);
618+
for (size_t i = 0; i < tal_count(channel->old_scids); i++)
619+
chanmap_add(peer->ld, channel, channel->old_scids[i]);
620+
558621
/* We always make sure this is set (historical channels from db might not) */
559-
if (!channel->alias[LOCAL]) {
560-
channel->alias[LOCAL] = tal(channel, struct short_channel_id);
561-
randombytes_buf(channel->alias[LOCAL], sizeof(struct short_channel_id));
562-
}
622+
if (!channel->alias[LOCAL])
623+
channel_set_random_local_alias(channel);
624+
563625
channel->alias[REMOTE] = tal_steal(channel, alias_remote); /* Haven't gotten one yet. */
564626
channel->cid = *cid;
565627
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>
@@ -840,6 +841,35 @@ struct channel *peer_any_channel_bystate(struct peer *peer,
840841

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

844+
struct scid_to_channel {
845+
struct short_channel_id scid;
846+
struct channel *channel;
847+
};
848+
849+
static inline const struct short_channel_id scid_to_channel_key(const struct scid_to_channel *scidchan)
850+
{
851+
return scidchan->scid;
852+
}
853+
854+
static inline bool scid_to_channel_eq_scid(const struct scid_to_channel *scidchan,
855+
struct short_channel_id scid)
856+
{
857+
return short_channel_id_eq(scidchan->scid, scid);
858+
}
859+
860+
/* Define channel_scid_map */
861+
HTABLE_DEFINE_NODUPS_TYPE(struct scid_to_channel,
862+
scid_to_channel_key,
863+
short_channel_id_hash,
864+
scid_to_channel_eq_scid,
865+
channel_scid_map);
866+
867+
/* The only allowed way to set channel->scid */
868+
void channel_set_scid(struct channel *channel, const struct short_channel_id *new_scid);
869+
870+
/* The only allowed way to set channel->alias[LOCAL] */
871+
void channel_set_local_alias(struct channel *channel, struct short_channel_id alias_scid);
872+
843873
/* Includes both real scids and aliases. If !privacy_leak_ok, then private
844874
* channels' real scids are not included. */
845875
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
@@ -1581,8 +1581,8 @@ static struct channel *stub_chan(struct command *cmd,
15811581
true, /* remote_channel_ready */
15821582
scid,
15831583
NULL,
1584-
scid,
1585-
scid,
1584+
NULL,
1585+
NULL,
15861586
&cid,
15871587
/* The three arguments below are msatoshi_to_us,
15881588
* 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)