Skip to content

Commit

Permalink
lightningd: move the state changes into struct channel.
Browse files Browse the repository at this point in the history
And instead of loading them in listpeerchannels, use them.  This means
listpeerchannels no longer touches the db.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: JSONRPC: `listpeerchannels` (and thus, pay) sped up on very large nodes.
  • Loading branch information
rustyrussell committed Sep 20, 2024
1 parent eb97998 commit 0440700
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 20 deletions.
21 changes: 15 additions & 6 deletions lightningd/channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ struct channel *new_unsaved_channel(struct peer *peer,
channel->stable_conn_timer = NULL;
/* Nothing happened yet */
memset(&channel->stats, 0, sizeof(channel->stats));
channel->state_changes = tal_arr(channel, struct state_change_entry, 0);

/* No shachain yet */
channel->their_shachain.id = 0;
Expand Down Expand Up @@ -448,7 +449,8 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
/* NULL or stolen */
struct peer_update *peer_update STEALS,
u64 last_stable_connection,
const struct channel_stats *stats)
const struct channel_stats *stats,
struct state_change_entry *state_changes STEALS)
{
struct channel *channel = tal(peer->ld, struct channel);
struct amount_msat htlc_min, htlc_max;
Expand Down Expand Up @@ -606,6 +608,8 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
channel->last_stable_connection = last_stable_connection;
channel->stable_conn_timer = NULL;
channel->stats = *stats;
channel->state_changes = tal_steal(channel, state_changes);

/* Populate channel->channel_gossip */
channel_gossip_init(channel, take(peer_update));

Expand Down Expand Up @@ -836,8 +840,6 @@ void channel_set_state(struct channel *channel,
enum state_change reason,
char *why)
{
struct timeabs timestamp;

/* set closer, if known */
if (channel_state_closing(state) && channel->closer == NUM_SIDES) {
if (reason == REASON_LOCAL) channel->closer = LOCAL;
Expand Down Expand Up @@ -865,10 +867,17 @@ void channel_set_state(struct channel *channel,

/* plugin notification channel_state_changed and DB entry */
if (state != old_state) { /* see issue #4029 */
timestamp = time_now();
struct state_change_entry change;
change.timestamp = time_now();
change.old_state = old_state;
change.new_state = state;
change.cause = reason;
change.message = tal_strdup(channel->state_changes, why);
tal_arr_expand(&channel->state_changes, change);

wallet_state_change_add(channel->peer->ld->wallet,
channel->dbid,
timestamp,
change.timestamp,
old_state,
state,
reason,
Expand All @@ -877,7 +886,7 @@ void channel_set_state(struct channel *channel,
&channel->peer->id,
&channel->cid,
channel->scid,
timestamp,
change.timestamp,
old_state,
state,
reason,
Expand Down
6 changes: 5 additions & 1 deletion lightningd/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,9 @@ struct channel {

/* Our stats */
struct channel_stats stats;

/* Our change history. */
struct state_change_entry *state_changes;
};

/* Is channel owned (and should be talking to peer) */
Expand Down Expand Up @@ -407,7 +410,8 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
/* NULL or stolen */
struct peer_update *peer_update STEALS,
u64 last_stable_connection,
const struct channel_stats *stats);
const struct channel_stats *stats,
struct state_change_entry *state_changes STEALS);

/* new_inflight - Create a new channel_inflight for a channel */
struct channel_inflight *new_inflight(struct channel *channel,
Expand Down
6 changes: 4 additions & 2 deletions lightningd/opening_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ wallet_commit_channel(struct lightningd *ld,
ld->config.ignore_fee_limits,
NULL,
0,
&zero_channel_stats);
&zero_channel_stats,
tal_arr(NULL, struct state_change_entry, 0));

/* Now we finally put it in the database. */
wallet_channel_insert(ld->wallet, channel);
Expand Down Expand Up @@ -1598,7 +1599,8 @@ static struct channel *stub_chan(struct command *cmd,
false,
NULL,
0,
&zero_channel_stats);
&zero_channel_stats,
tal_arr(NULL, struct state_change_entry, 0));

/* We don't want to gossip about this, ever. */
channel->channel_gossip = tal_free(channel->channel_gossip);
Expand Down
14 changes: 6 additions & 8 deletions lightningd/peer_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,6 @@ static void NON_NULL_ARGS(1, 2, 4, 5) json_add_channel(struct command *cmd,
struct lightningd *ld = cmd->ld;
struct amount_msat funding_msat;
struct amount_sat peer_funded_sats;
struct state_change_entry *state_changes;
const struct peer_update *peer_update;
u32 feerate;

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

state_changes = wallet_state_change_get(tmpctx, ld->wallet, channel->dbid);
json_array_start(response, "state_changes");
for (size_t i = 0; i < tal_count(state_changes); i++) {
for (size_t i = 0; i < tal_count(channel->state_changes); i++) {
json_object_start(response, NULL);
json_add_timeiso(response, "timestamp",
state_changes[i].timestamp);
channel->state_changes[i].timestamp);
json_add_string(response, "old_state",
channel_state_str(state_changes[i].old_state));
channel_state_str(channel->state_changes[i].old_state));
json_add_string(response, "new_state",
channel_state_str(state_changes[i].new_state));
channel_state_str(channel->state_changes[i].new_state));
json_add_string(response, "cause",
channel_change_state_reason_str(state_changes[i].cause));
json_add_string(response, "message", state_changes[i].message);
channel_change_state_reason_str(channel->state_changes[i].cause));
json_add_string(response, "message", channel->state_changes[i].message);
json_object_end(response);
}
json_array_end(response);
Expand Down
3 changes: 2 additions & 1 deletion wallet/test/run-db.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ struct channel *new_channel(struct peer *peer UNNEEDED, u64 dbid UNNEEDED,
/* NULL or stolen */
struct peer_update *peer_update STEALS UNNEEDED,
u64 last_stable_connection UNNEEDED,
const struct channel_stats *stats UNNEEDED)
const struct channel_stats *stats UNNEEDED,
struct state_change_entry *state_changes STEALS UNNEEDED)
{ fprintf(stderr, "new_channel called!\n"); abort(); }
/* Generated stub for new_coin_wallet_deposit */
struct chain_coin_mvt *new_coin_wallet_deposit(const tal_t *ctx UNNEEDED,
Expand Down
3 changes: 2 additions & 1 deletion wallet/test/run-wallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1997,7 +1997,8 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx)
false,
NULL,
0,
stats);
stats,
tal_arr(NULL, struct state_change_entry, 0));
db_begin_transaction(w->db);
CHECK(!wallet_err);
wallet_channel_insert(w, chan);
Expand Down
6 changes: 5 additions & 1 deletion wallet/wallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1522,6 +1522,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
bool ignore_fee_limits;
struct peer_update *remote_update;
struct channel_stats stats;
struct state_change_entry *state_changes;

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

/* Stolen by new_channel */
state_changes = wallet_state_change_get(NULL, w, db_col_u64(stmt, "id"));
chan = new_channel(peer, db_col_u64(stmt, "id"),
&wshachain,
channel_state_in_db(db_col_int(stmt, "state")),
Expand Down Expand Up @@ -1787,7 +1790,8 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
ignore_fee_limits,
remote_update,
db_col_u64(stmt, "last_stable_connection"),
&stats);
&stats,
state_changes);

if (!wallet_channel_load_inflights(w, chan)) {
tal_free(chan);
Expand Down

0 comments on commit 0440700

Please sign in to comment.