Skip to content

Commit 0440700

Browse files
committed
lightningd: move the state changes into struct channel.
And instead of loading them in listpeerchannels, use them. This means listpeerchannels no longer touches the db. Signed-off-by: Rusty Russell <[email protected]> Changelog-Fixed: JSONRPC: `listpeerchannels` (and thus, pay) sped up on very large nodes.
1 parent eb97998 commit 0440700

File tree

7 files changed

+39
-20
lines changed

7 files changed

+39
-20
lines changed

lightningd/channel.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ struct channel *new_unsaved_channel(struct peer *peer,
312312
channel->stable_conn_timer = NULL;
313313
/* Nothing happened yet */
314314
memset(&channel->stats, 0, sizeof(channel->stats));
315+
channel->state_changes = tal_arr(channel, struct state_change_entry, 0);
315316

316317
/* No shachain yet */
317318
channel->their_shachain.id = 0;
@@ -448,7 +449,8 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
448449
/* NULL or stolen */
449450
struct peer_update *peer_update STEALS,
450451
u64 last_stable_connection,
451-
const struct channel_stats *stats)
452+
const struct channel_stats *stats,
453+
struct state_change_entry *state_changes STEALS)
452454
{
453455
struct channel *channel = tal(peer->ld, struct channel);
454456
struct amount_msat htlc_min, htlc_max;
@@ -606,6 +608,8 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
606608
channel->last_stable_connection = last_stable_connection;
607609
channel->stable_conn_timer = NULL;
608610
channel->stats = *stats;
611+
channel->state_changes = tal_steal(channel, state_changes);
612+
609613
/* Populate channel->channel_gossip */
610614
channel_gossip_init(channel, take(peer_update));
611615

@@ -836,8 +840,6 @@ void channel_set_state(struct channel *channel,
836840
enum state_change reason,
837841
char *why)
838842
{
839-
struct timeabs timestamp;
840-
841843
/* set closer, if known */
842844
if (channel_state_closing(state) && channel->closer == NUM_SIDES) {
843845
if (reason == REASON_LOCAL) channel->closer = LOCAL;
@@ -865,10 +867,17 @@ void channel_set_state(struct channel *channel,
865867

866868
/* plugin notification channel_state_changed and DB entry */
867869
if (state != old_state) { /* see issue #4029 */
868-
timestamp = time_now();
870+
struct state_change_entry change;
871+
change.timestamp = time_now();
872+
change.old_state = old_state;
873+
change.new_state = state;
874+
change.cause = reason;
875+
change.message = tal_strdup(channel->state_changes, why);
876+
tal_arr_expand(&channel->state_changes, change);
877+
869878
wallet_state_change_add(channel->peer->ld->wallet,
870879
channel->dbid,
871-
timestamp,
880+
change.timestamp,
872881
old_state,
873882
state,
874883
reason,
@@ -877,7 +886,7 @@ void channel_set_state(struct channel *channel,
877886
&channel->peer->id,
878887
&channel->cid,
879888
channel->scid,
880-
timestamp,
889+
change.timestamp,
881890
old_state,
882891
state,
883892
reason,

lightningd/channel.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@ struct channel {
325325

326326
/* Our stats */
327327
struct channel_stats stats;
328+
329+
/* Our change history. */
330+
struct state_change_entry *state_changes;
328331
};
329332

330333
/* Is channel owned (and should be talking to peer) */
@@ -407,7 +410,8 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
407410
/* NULL or stolen */
408411
struct peer_update *peer_update STEALS,
409412
u64 last_stable_connection,
410-
const struct channel_stats *stats);
413+
const struct channel_stats *stats,
414+
struct state_change_entry *state_changes STEALS);
411415

412416
/* new_inflight - Create a new channel_inflight for a channel */
413417
struct channel_inflight *new_inflight(struct channel *channel,

lightningd/opening_control.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,8 @@ wallet_commit_channel(struct lightningd *ld,
220220
ld->config.ignore_fee_limits,
221221
NULL,
222222
0,
223-
&zero_channel_stats);
223+
&zero_channel_stats,
224+
tal_arr(NULL, struct state_change_entry, 0));
224225

225226
/* Now we finally put it in the database. */
226227
wallet_channel_insert(ld->wallet, channel);
@@ -1598,7 +1599,8 @@ static struct channel *stub_chan(struct command *cmd,
15981599
false,
15991600
NULL,
16001601
0,
1601-
&zero_channel_stats);
1602+
&zero_channel_stats,
1603+
tal_arr(NULL, struct state_change_entry, 0));
16021604

16031605
/* We don't want to gossip about this, ever. */
16041606
channel->channel_gossip = tal_free(channel->channel_gossip);

lightningd/peer_control.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,6 @@ static void NON_NULL_ARGS(1, 2, 4, 5) json_add_channel(struct command *cmd,
820820
struct lightningd *ld = cmd->ld;
821821
struct amount_msat funding_msat;
822822
struct amount_sat peer_funded_sats;
823-
struct state_change_entry *state_changes;
824823
const struct peer_update *peer_update;
825824
u32 feerate;
826825

@@ -1161,19 +1160,18 @@ static void NON_NULL_ARGS(1, 2, 4, 5) json_add_channel(struct command *cmd,
11611160
json_add_num(response, "max_accepted_htlcs",
11621161
channel->our_config.max_accepted_htlcs);
11631162

1164-
state_changes = wallet_state_change_get(tmpctx, ld->wallet, channel->dbid);
11651163
json_array_start(response, "state_changes");
1166-
for (size_t i = 0; i < tal_count(state_changes); i++) {
1164+
for (size_t i = 0; i < tal_count(channel->state_changes); i++) {
11671165
json_object_start(response, NULL);
11681166
json_add_timeiso(response, "timestamp",
1169-
state_changes[i].timestamp);
1167+
channel->state_changes[i].timestamp);
11701168
json_add_string(response, "old_state",
1171-
channel_state_str(state_changes[i].old_state));
1169+
channel_state_str(channel->state_changes[i].old_state));
11721170
json_add_string(response, "new_state",
1173-
channel_state_str(state_changes[i].new_state));
1171+
channel_state_str(channel->state_changes[i].new_state));
11741172
json_add_string(response, "cause",
1175-
channel_change_state_reason_str(state_changes[i].cause));
1176-
json_add_string(response, "message", state_changes[i].message);
1173+
channel_change_state_reason_str(channel->state_changes[i].cause));
1174+
json_add_string(response, "message", channel->state_changes[i].message);
11771175
json_object_end(response);
11781176
}
11791177
json_array_end(response);

wallet/test/run-db.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,8 @@ struct channel *new_channel(struct peer *peer UNNEEDED, u64 dbid UNNEEDED,
192192
/* NULL or stolen */
193193
struct peer_update *peer_update STEALS UNNEEDED,
194194
u64 last_stable_connection UNNEEDED,
195-
const struct channel_stats *stats UNNEEDED)
195+
const struct channel_stats *stats UNNEEDED,
196+
struct state_change_entry *state_changes STEALS UNNEEDED)
196197
{ fprintf(stderr, "new_channel called!\n"); abort(); }
197198
/* Generated stub for new_coin_wallet_deposit */
198199
struct chain_coin_mvt *new_coin_wallet_deposit(const tal_t *ctx UNNEEDED,

wallet/test/run-wallet.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1997,7 +1997,8 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx)
19971997
false,
19981998
NULL,
19991999
0,
2000-
stats);
2000+
stats,
2001+
tal_arr(NULL, struct state_change_entry, 0));
20012002
db_begin_transaction(w->db);
20022003
CHECK(!wallet_err);
20032004
wallet_channel_insert(w, chan);

wallet/wallet.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1522,6 +1522,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
15221522
bool ignore_fee_limits;
15231523
struct peer_update *remote_update;
15241524
struct channel_stats stats;
1525+
struct state_change_entry *state_changes;
15251526

15261527
peer_dbid = db_col_u64(stmt, "peer_id");
15271528
peer = find_peer_by_dbid(w->ld, peer_dbid);
@@ -1725,6 +1726,8 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
17251726
&stats.out_msatoshi_fulfilled,
17261727
AMOUNT_MSAT(0));
17271728

1729+
/* Stolen by new_channel */
1730+
state_changes = wallet_state_change_get(NULL, w, db_col_u64(stmt, "id"));
17281731
chan = new_channel(peer, db_col_u64(stmt, "id"),
17291732
&wshachain,
17301733
channel_state_in_db(db_col_int(stmt, "state")),
@@ -1787,7 +1790,8 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
17871790
ignore_fee_limits,
17881791
remote_update,
17891792
db_col_u64(stmt, "last_stable_connection"),
1790-
&stats);
1793+
&stats,
1794+
state_changes);
17911795

17921796
if (!wallet_channel_load_inflights(w, chan)) {
17931797
tal_free(chan);

0 commit comments

Comments
 (0)