diff --git a/lightningd/channel_state.h b/lightningd/channel_state.h index bfd319ab8..262c0e55d 100644 --- a/lightningd/channel_state.h +++ b/lightningd/channel_state.h @@ -2,6 +2,8 @@ #define LIGHTNING_LIGHTNINGD_CHANNEL_STATE_H #include "config.h" +#include + /* These are in the database, so don't renumber them! */ enum channel_state { /* In channeld, still waiting for lockin. */ @@ -54,4 +56,12 @@ enum state_change { REASON_ONCHAIN }; +struct state_change_entry { + struct timeabs timestamp; + enum channel_state old_state; + enum channel_state new_state; + enum state_change cause; + char *message; +}; + #endif /* LIGHTNING_LIGHTNINGD_CHANNEL_STATE_H */ diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 1653ac98a..99b6ef902 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -765,6 +765,7 @@ static void json_add_channel(struct lightningd *ld, struct amount_msat funding_msat, peer_msats, our_msats; struct amount_sat peer_funded_sats; struct peer *p = channel->peer; + struct state_change_entry *state_changes; json_object_start(response, key); json_add_string(response, "state", channel_state_name(channel)); @@ -927,6 +928,23 @@ static void json_add_channel(struct lightningd *ld, json_add_num(response, "max_accepted_htlcs", channel->our_config.max_accepted_htlcs); + state_changes = wallet_state_change_get(ld->wallet, response, channel->dbid); + json_array_start(response, "state_changes"); + for (size_t i = 0; i < tal_count(state_changes); i++) { + json_object_start(response, NULL); + json_add_timeiso(response, "timestamp", + &state_changes[i].timestamp); + json_add_string(response, "old_state", + channel_state_str(state_changes[i].old_state)); + json_add_string(response, "new_state", + channel_state_str(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); + json_object_end(response); + } + json_array_end(response); + json_array_start(response, "status"); for (size_t i = 0; i < ARRAY_SIZE(channel->billboard.permanent); i++) { if (!channel->billboard.permanent[i]) diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index 5488dc367..ce649a7c6 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -42,6 +42,9 @@ void broadcast_tx(struct chain_topology *topo UNNEEDED, bool success UNNEEDED, const char *err)) { fprintf(stderr, "broadcast_tx called!\n"); abort(); } +/* Generated stub for channel_change_state_reason_str */ +const char *channel_change_state_reason_str(enum state_change reason UNNEEDED) +{ fprintf(stderr, "channel_change_state_reason_str called!\n"); abort(); } /* Generated stub for channel_fail_forget */ void channel_fail_forget(struct channel *channel UNNEEDED, const char *fmt UNNEEDED, ...) { fprintf(stderr, "channel_fail_forget called!\n"); abort(); } @@ -82,6 +85,9 @@ void channel_set_state(struct channel *channel UNNEEDED, /* Generated stub for channel_state_name */ const char *channel_state_name(const struct channel *channel UNNEEDED) { fprintf(stderr, "channel_state_name called!\n"); abort(); } +/* Generated stub for channel_state_str */ +const char *channel_state_str(enum channel_state state UNNEEDED) +{ fprintf(stderr, "channel_state_str called!\n"); abort(); } /* Generated stub for channel_tell_depth */ bool channel_tell_depth(struct lightningd *ld UNNEEDED, struct channel *channel UNNEEDED, @@ -657,6 +663,11 @@ void wallet_invoice_waitone(const tal_t *ctx UNNEEDED, /* Generated stub for wallet_peer_delete */ void wallet_peer_delete(struct wallet *w UNNEEDED, u64 peer_dbid UNNEEDED) { fprintf(stderr, "wallet_peer_delete called!\n"); abort(); } +/* Generated stub for wallet_state_change_get */ +struct state_change_entry *wallet_state_change_get(struct wallet *w UNNEEDED, + const tal_t *ctx UNNEEDED, + u64 channel_id UNNEEDED) +{ fprintf(stderr, "wallet_state_change_get called!\n"); abort(); } /* Generated stub for wallet_total_forward_fees */ struct amount_msat wallet_total_forward_fees(struct wallet *w UNNEEDED) { fprintf(stderr, "wallet_total_forward_fees called!\n"); abort(); } diff --git a/wallet/db_postgres_sqlgen.c b/wallet/db_postgres_sqlgen.c index e371eec07..d99fb238b 100644 --- a/wallet/db_postgres_sqlgen.c +++ b/wallet/db_postgres_sqlgen.c @@ -1256,6 +1256,12 @@ struct db_query db_postgres_queries[] = { .placeholders = 6, .readonly = false, }, + { + .name = "SELECT timestamp, old_state, new_state, cause, message FROM channel_state_changes WHERE channel_id = ? ORDER BY timestamp ASC;", + .query = "SELECT timestamp, old_state, new_state, cause, message FROM channel_state_changes WHERE channel_id = $1 ORDER BY timestamp ASC;", + .placeholders = 1, + .readonly = true, + }, { .name = "SELECT id FROM peers WHERE node_id = ?", .query = "SELECT id FROM peers WHERE node_id = $1", @@ -1678,10 +1684,10 @@ struct db_query db_postgres_queries[] = { }, }; -#define DB_POSTGRES_QUERY_COUNT 278 +#define DB_POSTGRES_QUERY_COUNT 279 #endif /* HAVE_POSTGRES */ #endif /* LIGHTNINGD_WALLET_GEN_DB_POSTGRES */ -// SHA256STAMP:9ed50e3cbb14e9bb979a6b0f8754f1cb2412a7adc032f0a71e88cd534b3828d4 +// SHA256STAMP:756457b3587828d8b4226c2787cbadc1605669371ac57bb92c0b21e434bd80e1 diff --git a/wallet/db_sqlite3_sqlgen.c b/wallet/db_sqlite3_sqlgen.c index 0d2d2f47b..7d0629c76 100644 --- a/wallet/db_sqlite3_sqlgen.c +++ b/wallet/db_sqlite3_sqlgen.c @@ -1256,6 +1256,12 @@ struct db_query db_sqlite3_queries[] = { .placeholders = 6, .readonly = false, }, + { + .name = "SELECT timestamp, old_state, new_state, cause, message FROM channel_state_changes WHERE channel_id = ? ORDER BY timestamp ASC;", + .query = "SELECT timestamp, old_state, new_state, cause, message FROM channel_state_changes WHERE channel_id = ? ORDER BY timestamp ASC;", + .placeholders = 1, + .readonly = true, + }, { .name = "SELECT id FROM peers WHERE node_id = ?", .query = "SELECT id FROM peers WHERE node_id = ?", @@ -1678,10 +1684,10 @@ struct db_query db_sqlite3_queries[] = { }, }; -#define DB_SQLITE3_QUERY_COUNT 278 +#define DB_SQLITE3_QUERY_COUNT 279 #endif /* HAVE_SQLITE3 */ #endif /* LIGHTNINGD_WALLET_GEN_DB_SQLITE3 */ -// SHA256STAMP:9ed50e3cbb14e9bb979a6b0f8754f1cb2412a7adc032f0a71e88cd534b3828d4 +// SHA256STAMP:756457b3587828d8b4226c2787cbadc1605669371ac57bb92c0b21e434bd80e1 diff --git a/wallet/statements_gettextgen.po b/wallet/statements_gettextgen.po index 16a1131a1..e944c3a21 100644 --- a/wallet/statements_gettextgen.po +++ b/wallet/statements_gettextgen.po @@ -830,271 +830,275 @@ msgstr "" msgid "INSERT INTO channel_state_changes ( channel_id, timestamp, old_state, new_state, cause, message) VALUES (?, ?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:1610 +#: wallet/wallet.c:1614 +msgid "SELECT timestamp, old_state, new_state, cause, message FROM channel_state_changes WHERE channel_id = ? ORDER BY timestamp ASC;" +msgstr "" + +#: wallet/wallet.c:1643 msgid "SELECT id FROM peers WHERE node_id = ?" msgstr "" -#: wallet/wallet.c:1622 +#: wallet/wallet.c:1655 msgid "UPDATE peers SET address = ? WHERE id = ?" msgstr "" -#: wallet/wallet.c:1631 +#: wallet/wallet.c:1664 msgid "INSERT INTO peers (node_id, address) VALUES (?, ?);" msgstr "" -#: wallet/wallet.c:1649 +#: wallet/wallet.c:1682 msgid "INSERT INTO channels (peer_id, first_blocknum, id) VALUES (?, ?, ?);" msgstr "" -#: wallet/wallet.c:1675 +#: wallet/wallet.c:1708 msgid "DELETE FROM channel_htlcs WHERE channel_id=?" msgstr "" -#: wallet/wallet.c:1681 +#: wallet/wallet.c:1714 msgid "DELETE FROM htlc_sigs WHERE channelid=?" msgstr "" -#: wallet/wallet.c:1687 +#: wallet/wallet.c:1720 msgid "DELETE FROM channeltxs WHERE channel_id=?" msgstr "" -#: wallet/wallet.c:1693 +#: wallet/wallet.c:1726 msgid "DELETE FROM shachains WHERE id IN ( SELECT shachain_remote_id FROM channels WHERE channels.id=?)" msgstr "" -#: wallet/wallet.c:1703 +#: wallet/wallet.c:1736 msgid "UPDATE channels SET state=?, peer_id=? WHERE channels.id=?" msgstr "" -#: wallet/wallet.c:1717 +#: wallet/wallet.c:1750 msgid "SELECT * FROM channels WHERE peer_id = ?;" msgstr "" -#: wallet/wallet.c:1725 +#: wallet/wallet.c:1758 msgid "DELETE FROM peers WHERE id=?" msgstr "" -#: wallet/wallet.c:1736 +#: wallet/wallet.c:1769 msgid "UPDATE outputs SET confirmation_height = ? WHERE prev_out_tx = ?" msgstr "" -#: wallet/wallet.c:1839 +#: wallet/wallet.c:1872 msgid "INSERT INTO channel_htlcs ( channel_id, channel_htlc_id, direction, msatoshi, cltv_expiry, payment_hash, payment_key, hstate, shared_secret, routing_onion, received_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:1892 +#: wallet/wallet.c:1925 msgid "INSERT INTO channel_htlcs ( channel_id, channel_htlc_id, direction, origin_htlc, msatoshi, cltv_expiry, payment_hash, payment_key, hstate, routing_onion, partid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:1952 +#: wallet/wallet.c:1985 msgid "UPDATE channel_htlcs SET hstate=?, payment_key=?, malformed_onion=?, failuremsg=?, localfailmsg=?, we_filled=? WHERE id=?" msgstr "" -#: wallet/wallet.c:2168 +#: wallet/wallet.c:2201 msgid "SELECT id, channel_htlc_id, msatoshi, cltv_expiry, hstate, payment_hash, payment_key, routing_onion, failuremsg, malformed_onion, origin_htlc, shared_secret, received_time, we_filled FROM channel_htlcs WHERE direction= ? AND channel_id= ? AND hstate != ?" msgstr "" -#: wallet/wallet.c:2215 +#: wallet/wallet.c:2248 msgid "SELECT id, channel_htlc_id, msatoshi, cltv_expiry, hstate, payment_hash, payment_key, routing_onion, failuremsg, malformed_onion, origin_htlc, shared_secret, received_time, partid, localfailmsg FROM channel_htlcs WHERE direction = ? AND channel_id = ? AND hstate != ?" msgstr "" -#: wallet/wallet.c:2345 +#: wallet/wallet.c:2378 msgid "SELECT channel_id, direction, cltv_expiry, channel_htlc_id, payment_hash FROM channel_htlcs WHERE channel_id = ?;" msgstr "" -#: wallet/wallet.c:2379 +#: wallet/wallet.c:2412 msgid "DELETE FROM channel_htlcs WHERE direction = ? AND origin_htlc = ? AND payment_hash = ? AND partid = ?;" msgstr "" -#: wallet/wallet.c:2432 +#: wallet/wallet.c:2465 msgid "SELECT status FROM payments WHERE payment_hash=? AND partid = ?;" msgstr "" -#: wallet/wallet.c:2450 +#: wallet/wallet.c:2483 msgid "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:2533 +#: wallet/wallet.c:2566 msgid "DELETE FROM payments WHERE payment_hash = ? AND partid = ?" msgstr "" -#: wallet/wallet.c:2547 +#: wallet/wallet.c:2580 msgid "DELETE FROM payments WHERE payment_hash = ?" msgstr "" -#: wallet/wallet.c:2642 +#: wallet/wallet.c:2675 msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ? AND partid = ?" msgstr "" -#: wallet/wallet.c:2691 +#: wallet/wallet.c:2724 msgid "UPDATE payments SET status=? WHERE payment_hash=? AND partid=?" msgstr "" -#: wallet/wallet.c:2701 +#: wallet/wallet.c:2734 msgid "UPDATE payments SET payment_preimage=? WHERE payment_hash=? AND partid=?" msgstr "" -#: wallet/wallet.c:2711 +#: wallet/wallet.c:2744 msgid "UPDATE payments SET path_secrets = NULL , route_nodes = NULL , route_channels = NULL WHERE payment_hash = ? AND partid = ?;" msgstr "" -#: wallet/wallet.c:2743 +#: wallet/wallet.c:2776 msgid "SELECT failonionreply, faildestperm, failindex, failcode, failnode, failchannel, failupdate, faildetail, faildirection FROM payments WHERE payment_hash=? AND partid=?;" msgstr "" -#: wallet/wallet.c:2810 +#: wallet/wallet.c:2843 msgid "UPDATE payments SET failonionreply=? , faildestperm=? , failindex=? , failcode=? , failnode=? , failchannel=? , failupdate=? , faildetail=? , faildirection=? WHERE payment_hash=? AND partid=?;" msgstr "" -#: wallet/wallet.c:2869 +#: wallet/wallet.c:2902 msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ?;" msgstr "" -#: wallet/wallet.c:2890 +#: wallet/wallet.c:2923 msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments ORDER BY id;" msgstr "" -#: wallet/wallet.c:2934 +#: wallet/wallet.c:2967 msgid "DELETE FROM htlc_sigs WHERE channelid = ?" msgstr "" -#: wallet/wallet.c:2941 +#: wallet/wallet.c:2974 msgid "INSERT INTO htlc_sigs (channelid, signature) VALUES (?, ?)" msgstr "" -#: wallet/wallet.c:2953 +#: wallet/wallet.c:2986 msgid "SELECT blobval FROM vars WHERE name='genesis_hash'" msgstr "" -#: wallet/wallet.c:2977 +#: wallet/wallet.c:3010 msgid "INSERT INTO vars (name, blobval) VALUES ('genesis_hash', ?);" msgstr "" -#: wallet/wallet.c:2993 +#: wallet/wallet.c:3026 msgid "DELETE FROM utxoset WHERE spendheight < ?" msgstr "" -#: wallet/wallet.c:3001 wallet/wallet.c:3111 +#: wallet/wallet.c:3034 wallet/wallet.c:3144 msgid "INSERT INTO blocks (height, hash, prev_hash) VALUES (?, ?, ?);" msgstr "" -#: wallet/wallet.c:3020 +#: wallet/wallet.c:3053 msgid "DELETE FROM blocks WHERE hash = ?" msgstr "" -#: wallet/wallet.c:3026 +#: wallet/wallet.c:3059 msgid "SELECT * FROM blocks WHERE height >= ?;" msgstr "" -#: wallet/wallet.c:3035 +#: wallet/wallet.c:3068 msgid "DELETE FROM blocks WHERE height > ?" msgstr "" -#: wallet/wallet.c:3047 +#: wallet/wallet.c:3080 msgid "UPDATE outputs SET spend_height = ?, status = ? WHERE prev_out_tx = ? AND prev_out_index = ?" msgstr "" -#: wallet/wallet.c:3064 +#: wallet/wallet.c:3097 msgid "UPDATE utxoset SET spendheight = ? WHERE txid = ? AND outnum = ?" msgstr "" -#: wallet/wallet.c:3086 wallet/wallet.c:3122 +#: wallet/wallet.c:3119 wallet/wallet.c:3155 msgid "INSERT INTO utxoset ( txid, outnum, blockheight, spendheight, txindex, scriptpubkey, satoshis) VALUES(?, ?, ?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:3146 +#: wallet/wallet.c:3179 msgid "SELECT height FROM blocks WHERE height = ?" msgstr "" -#: wallet/wallet.c:3159 +#: wallet/wallet.c:3192 msgid "SELECT txid, spendheight, scriptpubkey, satoshis FROM utxoset WHERE blockheight = ? AND txindex = ? AND outnum = ? AND spendheight IS NULL" msgstr "" -#: wallet/wallet.c:3201 +#: wallet/wallet.c:3234 msgid "SELECT blockheight, txindex, outnum FROM utxoset WHERE spendheight = ?" msgstr "" -#: wallet/wallet.c:3232 wallet/wallet.c:3392 +#: wallet/wallet.c:3265 wallet/wallet.c:3425 msgid "SELECT blockheight FROM transactions WHERE id=?" msgstr "" -#: wallet/wallet.c:3242 +#: wallet/wallet.c:3275 msgid "INSERT INTO transactions ( id, blockheight, txindex, rawtx) VALUES (?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:3263 +#: wallet/wallet.c:3296 msgid "UPDATE transactions SET blockheight = ?, txindex = ? WHERE id = ?" msgstr "" -#: wallet/wallet.c:3280 +#: wallet/wallet.c:3313 msgid "INSERT INTO transaction_annotations (txid, idx, location, type, channel) VALUES (?, ?, ?, ?, ?) ON CONFLICT(txid,idx) DO NOTHING;" msgstr "" -#: wallet/wallet.c:3312 +#: wallet/wallet.c:3345 msgid "SELECT type, channel_id FROM transactions WHERE id=?" msgstr "" -#: wallet/wallet.c:3328 +#: wallet/wallet.c:3361 msgid "UPDATE transactions SET type = ?, channel_id = ? WHERE id = ?" msgstr "" -#: wallet/wallet.c:3347 +#: wallet/wallet.c:3380 msgid "SELECT type FROM transactions WHERE id=?" msgstr "" -#: wallet/wallet.c:3370 +#: wallet/wallet.c:3403 msgid "SELECT rawtx FROM transactions WHERE id=?" msgstr "" -#: wallet/wallet.c:3416 +#: wallet/wallet.c:3449 msgid "SELECT blockheight, txindex FROM transactions WHERE id=?" msgstr "" -#: wallet/wallet.c:3444 +#: wallet/wallet.c:3477 msgid "SELECT id FROM transactions WHERE blockheight=?" msgstr "" -#: wallet/wallet.c:3463 +#: wallet/wallet.c:3496 msgid "INSERT INTO channeltxs ( channel_id, type, transaction_id, input_num, blockheight) VALUES (?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:3487 +#: wallet/wallet.c:3520 msgid "SELECT DISTINCT(channel_id) FROM channeltxs WHERE type = ?;" msgstr "" -#: wallet/wallet.c:3508 +#: wallet/wallet.c:3541 msgid "SELECT c.type, c.blockheight, t.rawtx, c.input_num, c.blockheight - t.blockheight + 1 AS depth, t.id as txid FROM channeltxs c JOIN transactions t ON t.id = c.transaction_id WHERE c.channel_id = ? ORDER BY c.id ASC;" msgstr "" -#: wallet/wallet.c:3553 +#: wallet/wallet.c:3586 msgid "UPDATE forwarded_payments SET in_msatoshi=?, out_msatoshi=?, state=?, resolved_time=?, failcode=? WHERE in_htlc_id=?" msgstr "" -#: wallet/wallet.c:3611 +#: wallet/wallet.c:3644 msgid "INSERT INTO forwarded_payments ( in_htlc_id, out_htlc_id, in_channel_scid, out_channel_scid, in_msatoshi, out_msatoshi, state, received_time, resolved_time, failcode) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:3670 +#: wallet/wallet.c:3703 msgid "SELECT CAST(COALESCE(SUM(in_msatoshi - out_msatoshi), 0) AS BIGINT)FROM forwarded_payments WHERE state = ?;" msgstr "" -#: wallet/wallet.c:3694 +#: wallet/wallet.c:3727 msgid "SELECT f.state, in_msatoshi, out_msatoshi, hin.payment_hash as payment_hash, in_channel_scid, out_channel_scid, f.received_time, f.resolved_time, f.failcode FROM forwarded_payments f LEFT JOIN channel_htlcs hin ON (f.in_htlc_id = hin.id)" msgstr "" -#: wallet/wallet.c:3782 +#: wallet/wallet.c:3815 msgid "SELECT t.id, t.rawtx, t.blockheight, t.txindex, t.type as txtype, c2.short_channel_id as txchan, a.location, a.idx as ann_idx, a.type as annotation_type, c.short_channel_id FROM transactions t LEFT JOIN transaction_annotations a ON (a.txid = t.id) LEFT JOIN channels c ON (a.channel = c.id) LEFT JOIN channels c2 ON (t.channel_id = c2.id) ORDER BY t.blockheight, t.txindex ASC" msgstr "" -#: wallet/wallet.c:3876 +#: wallet/wallet.c:3909 msgid "INSERT INTO penalty_bases ( channel_id, commitnum, txid, outnum, amount) VALUES (?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:3901 +#: wallet/wallet.c:3934 msgid "SELECT commitnum, txid, outnum, amount FROM penalty_bases WHERE channel_id = ?" msgstr "" -#: wallet/wallet.c:3925 +#: wallet/wallet.c:3958 msgid "DELETE FROM penalty_bases WHERE channel_id = ? AND commitnum = ?" msgstr "" @@ -1106,7 +1110,7 @@ msgstr "" msgid "not a valid SQL statement" msgstr "" -#: wallet/test/run-wallet.c:1371 +#: wallet/test/run-wallet.c:1376 msgid "INSERT INTO channels (id) VALUES (1);" msgstr "" -# SHA256STAMP:419d2f0d03ce748b3e54bd380834b1fc721c823e38f2ce38fc87df73671743ef +# SHA256STAMP:8fd4a9d444c885db744f98790817b0b580f3e39e36be393e578cc05418d25323 diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 0dbffb093..81be48722 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -319,6 +319,11 @@ void json_add_string(struct json_stream *result UNNEEDED, const char *fieldname void json_add_timeabs(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED, struct timeabs t UNNEEDED) { fprintf(stderr, "json_add_timeabs called!\n"); abort(); } +/* Generated stub for json_add_timeiso */ +void json_add_timeiso(struct json_stream *result UNNEEDED, + const char *fieldname UNNEEDED, + struct timeabs *time UNNEEDED) +{ fprintf(stderr, "json_add_timeiso called!\n"); abort(); } /* Generated stub for json_add_tx */ void json_add_tx(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED, diff --git a/wallet/wallet.c b/wallet/wallet.c index a1b82c2ed..169454243 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1602,6 +1602,39 @@ void wallet_state_change_add(struct wallet *w, db_exec_prepared_v2(take(stmt)); } +struct state_change_entry *wallet_state_change_get(struct wallet *w, + const tal_t *ctx, + u64 channel_id) +{ + struct db_stmt *stmt; + struct state_change_entry tmp; + struct state_change_entry *res = tal_arr(ctx, + struct state_change_entry, 0); + stmt = db_prepare_v2( + w->db, SQL("SELECT" + " timestamp," + " old_state," + " new_state," + " cause," + " message " + "FROM channel_state_changes " + "WHERE channel_id = ? " + "ORDER BY timestamp ASC;")); + db_bind_int(stmt, 0, channel_id); + db_query_prepared(stmt); + + while (db_step(stmt)) { + tmp.timestamp = db_column_timeabs(stmt, 0); + tmp.old_state = db_column_int(stmt, 1); + tmp.new_state = db_column_int(stmt, 2); + tmp.cause = db_column_int(stmt, 3); + tmp.message = tal_strdup(ctx, (const char *)db_column_text(stmt, 4)); + tal_arr_expand(&res, tmp); + } + tal_free(stmt); + return res; +} + static void wallet_peer_save(struct wallet *w, struct peer *peer) { const char *addr = diff --git a/wallet/wallet.h b/wallet/wallet.h index f6077516c..383081fe4 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -506,6 +506,13 @@ void wallet_state_change_add(struct wallet *w, enum state_change cause, char *message); +/** + * Gets all state change history entries for a channel from the database + */ +struct state_change_entry *wallet_state_change_get(struct wallet *w, + const tal_t *ctx, + u64 channel_id); + /** * wallet_peer_delete -- After no more channels in peer, forget about it */