diff --git a/bitcoin/script.c b/bitcoin/script.c index 63974644a34c..18461a8396b4 100644 --- a/bitcoin/script.c +++ b/bitcoin/script.c @@ -187,17 +187,6 @@ u8 *scriptpubkey_p2pkh(const tal_t *ctx, const struct bitcoin_address *addr) return script; } -u8 *scriptpubkey_opreturn_padded(const tal_t *ctx) -{ - u8 *script = tal_arr(ctx, u8, 0); - u8 random[20]; - randombytes_buf(random, sizeof(random)); - - add_op(&script, OP_RETURN); - script_push_bytes(&script, random, sizeof(random)); - return script; -} - /* Create an input script which spends p2pkh */ u8 *bitcoin_redeem_p2pkh(const tal_t *ctx, const struct pubkey *pubkey, const struct bitcoin_signature *sig) diff --git a/bitcoin/script.h b/bitcoin/script.h index 5b96d696ff15..c0a005c17d57 100644 --- a/bitcoin/script.h +++ b/bitcoin/script.h @@ -27,12 +27,6 @@ u8 *scriptpubkey_p2sh_hash(const tal_t *ctx, const struct ripemd160 *redeemhash) /* Create an output script using p2pkh */ u8 *scriptpubkey_p2pkh(const tal_t *ctx, const struct bitcoin_address *addr); -/* Create a prunable output script with 20 random bytes. - * This is needed since a spend from a p2wpkh to an `OP_RETURN` without - * any other outputs would result in a transaction smaller than the - * minimum size. */ -u8 *scriptpubkey_opreturn_padded(const tal_t *ctx); - /* Create an input script which spends p2pkh */ u8 *bitcoin_redeem_p2pkh(const tal_t *ctx, const struct pubkey *pubkey, const struct bitcoin_signature *sig); diff --git a/bitcoin/test/run-secret_eq_consttime.c b/bitcoin/test/run-secret_eq_consttime.c index 4f21ee191f11..bfba7ceb5029 100644 --- a/bitcoin/test/run-secret_eq_consttime.c +++ b/bitcoin/test/run-secret_eq_consttime.c @@ -22,7 +22,7 @@ static struct timerel const_time_test(struct secret *s1, struct secret *s2, size_t off) { - struct timeabs start, end; + struct timemono start, end; int result = 0; memset(s1, 0, RUNS * sizeof(*s1)); @@ -31,16 +31,16 @@ static struct timerel const_time_test(struct secret *s1, for (size_t i = 0; i < RUNS; i++) s2[i].data[off] = i; - start = time_now(); + start = time_mono(); for (size_t i = 0; i < RUNS; i++) result += secret_eq_consttime(&s1[i], &s2[i]); - end = time_now(); + end = time_mono(); if (result != RUNS / 256) errx(1, "Expected %u successes at offset %zu, not %u!", RUNS / 256, off, result); - return time_between(end, start); + return timemono_between(end, start); } static inline bool secret_eq_nonconst(const struct secret *a, @@ -53,7 +53,7 @@ static struct timerel nonconst_time_test(struct secret *s1, struct secret *s2, size_t off) { - struct timeabs start, end; + struct timemono start, end; int result = 0; memset(s1, 0, RUNS * sizeof(*s1)); @@ -62,16 +62,16 @@ static struct timerel nonconst_time_test(struct secret *s1, for (size_t i = 0; i < RUNS; i++) s2[i].data[off] = i; - start = time_now(); + start = time_mono(); for (size_t i = 0; i < RUNS; i++) result += secret_eq_nonconst(&s1[i], &s2[i]); - end = time_now(); + end = time_mono(); if (result != RUNS / 256) errx(1, "Expected %u successes at offset %zu, not %u!", RUNS / 256, off, result); - return time_between(end, start); + return timemono_between(end, start); } static struct secret *s1, *s2; diff --git a/channeld/full_channel.c b/channeld/full_channel.c index 699ccdf40ca4..cf27c69c11ad 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -17,12 +17,6 @@ /* Needs to be at end, since it doesn't include its own hdrs */ #include "full_channel_error_names_gen.h" -static void memleak_help_htlcmap(struct htable *memtable, - struct htlc_map *htlcs) -{ - memleak_scan_htable(memtable, &htlcs->raw); -} - /* This is a dangerous thing! Because we apply HTLCs in many places * in bulk, we can temporarily go negative. You must check balance_ok() * at the end! */ @@ -113,11 +107,9 @@ struct channel *new_full_channel(const tal_t *ctx, option_wumbo, opener); - if (channel) { - channel->htlcs = tal(channel, struct htlc_map); - htlc_map_init(channel->htlcs); - memleak_add_helper(channel->htlcs, memleak_help_htlcmap); - } + if (channel) + channel->htlcs = new_htable(channel, htlc_map); + return channel; } diff --git a/cli/Makefile b/cli/Makefile index 82dea907ea61..05c07100d9d1 100644 --- a/cli/Makefile +++ b/cli/Makefile @@ -10,6 +10,7 @@ LIGHTNING_CLI_COMMON_OBJS := \ common/configdir.o \ common/configvar.o \ common/json_parse_simple.o \ + common/memleak.o \ common/status_levels.o \ common/utils.o \ common/version.o diff --git a/common/configdir.c b/common/configdir.c index 248c8e73e010..0926c44fd569 100644 --- a/common/configdir.c +++ b/common/configdir.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -36,8 +37,7 @@ static char *opt_set_abspath(const char *arg, char **p) /* Tal wrappers for opt. */ static void *opt_allocfn(size_t size) { - return tal_arr_label(NULL, char, size, - TAL_LABEL(opt_allocfn_notleak, "")); + return notleak(tal_arr(NULL, char, size)); } static void *tal_reallocfn(void *ptr, size_t size) diff --git a/common/memleak.c b/common/memleak.c index 7ac0da7c7bf3..de321a9a7c66 100644 --- a/common/memleak.c +++ b/common/memleak.c @@ -58,9 +58,6 @@ struct tal_backtrace { void *notleak_(void *ptr, bool plus_children) { const char *name; - /* If we're not tracking, don't do anything. */ - if (!memleak_track) - return cast_const(void *, ptr); /* We use special tal names to mark notleak */ name = tal_name(ptr); @@ -69,12 +66,14 @@ void *notleak_(void *ptr, bool plus_children) /* Don't mark more than once! */ if (!strstr(name, "**NOTLEAK")) { + /* Don't use tmpctx: it might not be set up yet! */ if (plus_children) - name = tal_fmt(tmpctx, "%s **NOTLEAK_IGNORE_CHILDREN**", + name = tal_fmt(NULL, "%s **NOTLEAK_IGNORE_CHILDREN**", name); else - name = tal_fmt(tmpctx, "%s **NOTLEAK**", name); + name = tal_fmt(NULL, "%s **NOTLEAK**", name); tal_set_name(ptr, name); + tal_free(name); } return cast_const(void *, ptr); @@ -331,8 +330,7 @@ static void call_memleak_helpers(struct htable *memtable, const tal_t *p) if (strends(name, "struct memleak_helper")) { const struct memleak_helper *mh = i; mh->cb(memtable, p); - } else if (strends(name, " **NOTLEAK**") - || strends(name, "_notleak")) { + } else if (strends(name, " **NOTLEAK**")) { memleak_ptr(memtable, i); memleak_scan_obj(memtable, i); } else if (strends(name, diff --git a/common/memleak.h b/common/memleak.h index a15413b23f34..b9782e651ceb 100644 --- a/common/memleak.h +++ b/common/memleak.h @@ -109,6 +109,18 @@ void memleak_scan_region(struct htable *memtable, const void *p, size_t len); /* Objects inside this htable (which is opaque to memleak) are not leaks. */ void memleak_scan_htable(struct htable *memtable, const struct htable *ht); +/* Allocate a htable, set up memleak scan automatically (assumes &p->raw == p) */ +#define new_htable(ctx, type) \ + ({ \ + const struct htable *raw; \ + struct type *p = tal(ctx, struct type); \ + type##_init(p); \ + raw = &p->raw; \ + assert((void *)raw == (void *)p); \ + memleak_add_helper(raw, memleak_scan_htable); \ + p; \ + }) + /* Objects inside this uintmap (which is opaque to memleak) are not leaks. */ #define memleak_scan_uintmap(memtable, umap) \ memleak_scan_intmap_(memtable, uintmap_unwrap_(umap)) diff --git a/common/trace.c b/common/trace.c index eade3171f790..f64faa0ef440 100644 --- a/common/trace.c +++ b/common/trace.c @@ -184,15 +184,11 @@ static inline void trace_check_tree(void) {} static void trace_init(void) { const char *dev_trace_file; - const char notleak_name[] = "struct span **NOTLEAK**"; if (active_spans) return; - active_spans = tal_arrz(NULL, struct span, 1); - /* We're usually too early for memleak to be initialized, so mark - * this notleak manually! */ - tal_set_name(active_spans, notleak_name); + active_spans = notleak(tal_arrz(NULL, struct span, 1)); current = NULL; dev_trace_file = getenv("CLN_DEV_TRACE_FILE"); diff --git a/connectd/connectd.c b/connectd/connectd.c index f04f2caa798d..69014fdbb8bb 100644 --- a/connectd/connectd.c +++ b/connectd/connectd.c @@ -2021,9 +2021,6 @@ static void dev_connect_memleak(struct daemon *daemon, const u8 *msg) /* Now delete daemon and those which it has pointers to. */ memleak_scan_obj(memtable, daemon); - memleak_scan_htable(memtable, &daemon->peers->raw); - memleak_scan_htable(memtable, &daemon->scid_htable->raw); - memleak_scan_htable(memtable, &daemon->important_ids->raw); found_leak = dump_memleak(memtable, memleak_status_broken, NULL); daemon_conn_send(daemon->master, @@ -2437,14 +2434,6 @@ static struct io_plan *recv_gossip(struct io_conn *conn, return daemon_conn_read_next(conn, daemon->gossipd); } -/*~ This is a hook used by the memleak code: it can't see pointers - * inside hash tables, so we give it a hint here. */ -static void memleak_daemon_cb(struct htable *memtable, struct daemon *daemon) -{ - memleak_scan_htable(memtable, &daemon->peers->raw); - memleak_scan_htable(memtable, &daemon->connecting->raw); -} - static void gossipd_failed(struct daemon_conn *gossipd) { status_failed(STATUS_FAIL_GOSSIP_IO, "gossipd exited?"); @@ -2464,14 +2453,13 @@ int main(int argc, char *argv[]) daemon = tal(NULL, struct daemon); daemon->developer = developer; daemon->connection_counter = 1; - daemon->peers = tal(daemon, struct peer_htable); + /* htable_new is our helper which allocates a htable, initializes it + * and set up the memleak callback so our memleak code can see objects + * inside it */ + daemon->peers = new_htable(daemon, peer_htable); daemon->listeners = tal_arr(daemon, struct io_listener *, 0); - peer_htable_init(daemon->peers); - memleak_add_helper(daemon, memleak_daemon_cb); - daemon->connecting = tal(daemon, struct connecting_htable); - connecting_htable_init(daemon->connecting); - daemon->important_ids = tal(daemon, struct important_id_htable); - important_id_htable_init(daemon->important_ids); + daemon->connecting = new_htable(daemon, connecting_htable); + daemon->important_ids = new_htable(daemon, important_id_htable); timers_init(&daemon->timers, time_mono()); daemon->gossmap_raw = NULL; daemon->shutting_down = false; @@ -2481,8 +2469,7 @@ int main(int argc, char *argv[]) daemon->dev_exhausted_fds = false; /* We generally allow 1MB per second per peer, except for dev testing */ daemon->gossip_stream_limit = 1000000; - daemon->scid_htable = tal(daemon, struct scid_htable); - scid_htable_init(daemon->scid_htable); + daemon->scid_htable = new_htable(daemon, scid_htable); /* stdin == control */ daemon->master = daemon_conn_new(daemon, STDIN_FILENO, recv_req, NULL, diff --git a/contrib/msggen/msggen/schema.json b/contrib/msggen/msggen/schema.json index a0f42b9c8d4f..dadbb6ff0fd9 100644 --- a/contrib/msggen/msggen/schema.json +++ b/contrib/msggen/msggen/schema.json @@ -16812,6 +16812,359 @@ ], "resources": [ "Main web site: " + ], + "examples": [ + { + "request": { + "id": "example:listchainmoves#1", + "method": "listchainmoves", + "params": {} + }, + "response": { + "chainmoves": [ + { + "created_index": 1, + "account_id": "wallet", + "credit_msat": 200000000000, + "debit_msat": 0, + "timestamp": 1758192762, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "994185cba7723715c0aa1d1859ce2781116776cea917035c90f8f04c9f4e095e:1", + "output_msat": 200000000000, + "blockheight": 104 + }, + { + "created_index": 2, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 0, + "debit_msat": 0, + "timestamp": 1758192777, + "primary_tag": "channel_open", + "extra_tags": [], + "utxo": "542906c8a9d90596592459a9484f4286a3200f6540599c83b43af2ac4166c6ca:1", + "peer_id": "nodeid010101010101010101010101010101010101010101010101010101010101", + "output_msat": 1000000000, + "blockheight": 109 + }, + { + "created_index": 3, + "account_id": "wallet", + "credit_msat": 2000000000, + "debit_msat": 0, + "timestamp": 1758192780, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "19e9e42f2f2097ea1dc18d7eb670bc53c90cbe31bb1daba8e94abf3c6b60d2dc:1", + "output_msat": 2000000000, + "blockheight": 110 + }, + { + "created_index": 4, + "account_id": "wallet", + "credit_msat": 0, + "debit_msat": 200000000000, + "timestamp": 1738530000, + "primary_tag": "withdrawal", + "extra_tags": [], + "utxo": "994185cba7723715c0aa1d1859ce2781116776cea917035c90f8f04c9f4e095e:1", + "spending_txid": "94418b652c9a0d79129552d317dcc37cb55afda1387257a22c7f16aa3981b7bc", + "output_msat": 200000000000, + "blockheight": 111 + }, + { + "created_index": 5, + "account_id": "wallet", + "credit_msat": 198995073000, + "debit_msat": 0, + "timestamp": 1738530000, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "94418b652c9a0d79129552d317dcc37cb55afda1387257a22c7f16aa3981b7bc:1", + "output_msat": 198995073000, + "blockheight": 111 + }, + { + "created_index": 6, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 1000000000, + "debit_msat": 0, + "timestamp": 1738530000, + "primary_tag": "channel_open", + "extra_tags": [ + "opener" + ], + "utxo": "94418b652c9a0d79129552d317dcc37cb55afda1387257a22c7f16aa3981b7bc:0", + "peer_id": "nodeid030303030303030303030303030303030303030303030303030303030303", + "output_msat": 1000000000, + "blockheight": 111 + }, + { + "created_index": 7, + "account_id": "wallet", + "credit_msat": 2000000000, + "debit_msat": 0, + "timestamp": 1758192792, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "b6d0090efbeb347fa59f90b321d6906cdf86779c15477582979fa427249f71f5:1", + "output_msat": 2000000000, + "blockheight": 114 + }, + { + "created_index": 8, + "account_id": "wallet", + "credit_msat": 0, + "debit_msat": 198995073000, + "timestamp": 1758192795, + "primary_tag": "withdrawal", + "extra_tags": [], + "utxo": "94418b652c9a0d79129552d317dcc37cb55afda1387257a22c7f16aa3981b7bc:1", + "spending_txid": "32de3d1592062670eb8630875a28705cc1988b7f83f8c712bf9d39be2152efec", + "output_msat": 198995073000, + "blockheight": 115 + }, + { + "created_index": 9, + "account_id": "wallet", + "credit_msat": 197990453000, + "debit_msat": 0, + "timestamp": 1758192795, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "32de3d1592062670eb8630875a28705cc1988b7f83f8c712bf9d39be2152efec:0", + "output_msat": 197990453000, + "blockheight": 115 + }, + { + "created_index": 10, + "account_id": "f8fc83a432cbfb2fffe222cc06727fdd977b5dd10ebd6707158e799e6f522d9f", + "credit_msat": 1000000000, + "debit_msat": 0, + "timestamp": 1758192795, + "primary_tag": "channel_open", + "extra_tags": [ + "opener" + ], + "utxo": "32de3d1592062670eb8630875a28705cc1988b7f83f8c712bf9d39be2152efec:1", + "peer_id": "nodeid050505050505050505050505050505050505050505050505050505050505", + "output_msat": 1000000000, + "blockheight": 115 + }, + { + "created_index": 11, + "account_id": "wallet", + "credit_msat": 486914000, + "debit_msat": 0, + "timestamp": 1738520000, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "874b26d4c523a902fdc44b88ec000eb5c3fe8754c9d44190a140561e24e77781:0", + "output_msat": 486914000, + "blockheight": 121 + }, + { + "created_index": 12, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 489809898, + "timestamp": 1738520000, + "primary_tag": "channel_close", + "extra_tags": [], + "utxo": "94418b652c9a0d79129552d317dcc37cb55afda1387257a22c7f16aa3981b7bc:0", + "spending_txid": "txid010101010101010101010101010101010101010101010101010101010101", + "output_msat": 1000000000, + "output_count": 2, + "blockheight": 121 + }, + { + "created_index": 13, + "account_id": "external", + "credit_msat": 510190000, + "debit_msat": 0, + "timestamp": 1738520000, + "primary_tag": "to_them", + "extra_tags": [], + "utxo": "874b26d4c523a902fdc44b88ec000eb5c3fe8754c9d44190a140561e24e77781:1", + "originating_account": "channelid0230000230000230000230000230000230000230000230000230000", + "output_msat": 510190000, + "blockheight": 121 + }, + { + "created_index": 14, + "account_id": "wallet", + "credit_msat": 2000000000, + "debit_msat": 0, + "timestamp": 1758192808, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "c9c9bec064382b6a6fb2a30d8923949b3c9f732465542b96e9ad1b5eebda4c7d:0", + "output_msat": 2000000000, + "blockheight": 122 + }, + { + "created_index": 15, + "account_id": "wallet", + "credit_msat": 0, + "debit_msat": 197990453000, + "timestamp": 1738500000, + "primary_tag": "withdrawal", + "extra_tags": [], + "utxo": "32de3d1592062670eb8630875a28705cc1988b7f83f8c712bf9d39be2152efec:0", + "spending_txid": "0137213d852e76d48f0270a78218d2f562ac0a8974f814cab66376537cfd1682", + "output_msat": 197990453000, + "blockheight": 123 + }, + { + "created_index": 16, + "account_id": "wallet", + "credit_msat": 196985833000, + "debit_msat": 0, + "timestamp": 1738500000, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "0137213d852e76d48f0270a78218d2f562ac0a8974f814cab66376537cfd1682:1", + "output_msat": 196985833000, + "blockheight": 123 + }, + { + "created_index": 17, + "account_id": "channelid0230200230200230200230200230200230200230200230200230200", + "credit_msat": 1000000000, + "debit_msat": 0, + "timestamp": 1738500000, + "primary_tag": "channel_open", + "extra_tags": [ + "opener" + ], + "utxo": "0137213d852e76d48f0270a78218d2f562ac0a8974f814cab66376537cfd1682:0", + "peer_id": "nodeid030303030303030303030303030303030303030303030303030303030303", + "output_msat": 1000000000, + "blockheight": 123 + } + ] + } + }, + { + "request": { + "id": "example:listchainmoves#2", + "method": "listchainmoves", + "params": { + "index": "created", + "start": 10 + } + }, + "response": { + "chainmoves": [ + { + "created_index": 10, + "account_id": "f8fc83a432cbfb2fffe222cc06727fdd977b5dd10ebd6707158e799e6f522d9f", + "credit_msat": 1000000000, + "debit_msat": 0, + "timestamp": 1758192795, + "primary_tag": "channel_open", + "extra_tags": [ + "opener" + ], + "utxo": "32de3d1592062670eb8630875a28705cc1988b7f83f8c712bf9d39be2152efec:1", + "peer_id": "nodeid050505050505050505050505050505050505050505050505050505050505", + "output_msat": 1000000000, + "blockheight": 115 + }, + { + "created_index": 11, + "account_id": "wallet", + "credit_msat": 486914000, + "debit_msat": 0, + "timestamp": 1738520000, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "874b26d4c523a902fdc44b88ec000eb5c3fe8754c9d44190a140561e24e77781:0", + "output_msat": 486914000, + "blockheight": 121 + }, + { + "created_index": 12, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 489809898, + "timestamp": 1738520000, + "primary_tag": "channel_close", + "extra_tags": [], + "utxo": "94418b652c9a0d79129552d317dcc37cb55afda1387257a22c7f16aa3981b7bc:0", + "spending_txid": "txid010101010101010101010101010101010101010101010101010101010101", + "output_msat": 1000000000, + "output_count": 2, + "blockheight": 121 + }, + { + "created_index": 13, + "account_id": "external", + "credit_msat": 510190000, + "debit_msat": 0, + "timestamp": 1738520000, + "primary_tag": "to_them", + "extra_tags": [], + "utxo": "874b26d4c523a902fdc44b88ec000eb5c3fe8754c9d44190a140561e24e77781:1", + "originating_account": "channelid0230000230000230000230000230000230000230000230000230000", + "output_msat": 510190000, + "blockheight": 121 + }, + { + "created_index": 14, + "account_id": "wallet", + "credit_msat": 2000000000, + "debit_msat": 0, + "timestamp": 1758192808, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "c9c9bec064382b6a6fb2a30d8923949b3c9f732465542b96e9ad1b5eebda4c7d:0", + "output_msat": 2000000000, + "blockheight": 122 + }, + { + "created_index": 15, + "account_id": "wallet", + "credit_msat": 0, + "debit_msat": 197990453000, + "timestamp": 1738500000, + "primary_tag": "withdrawal", + "extra_tags": [], + "utxo": "32de3d1592062670eb8630875a28705cc1988b7f83f8c712bf9d39be2152efec:0", + "spending_txid": "0137213d852e76d48f0270a78218d2f562ac0a8974f814cab66376537cfd1682", + "output_msat": 197990453000, + "blockheight": 123 + }, + { + "created_index": 16, + "account_id": "wallet", + "credit_msat": 196985833000, + "debit_msat": 0, + "timestamp": 1738500000, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "0137213d852e76d48f0270a78218d2f562ac0a8974f814cab66376537cfd1682:1", + "output_msat": 196985833000, + "blockheight": 123 + }, + { + "created_index": 17, + "account_id": "channelid0230200230200230200230200230200230200230200230200230200", + "credit_msat": 1000000000, + "debit_msat": 0, + "timestamp": 1738500000, + "primary_tag": "channel_open", + "extra_tags": [ + "opener" + ], + "utxo": "0137213d852e76d48f0270a78218d2f562ac0a8974f814cab66376537cfd1682:0", + "peer_id": "nodeid030303030303030303030303030303030303030303030303030303030303", + "output_msat": 1000000000, + "blockheight": 123 + } + ] + } + } ] }, "listchannelmoves.json": { @@ -16961,6 +17314,242 @@ ], "resources": [ "Main web site: " + ], + "examples": [ + { + "request": { + "id": "example:listchannelmoves#1", + "method": "listchannelmoves", + "params": {} + }, + "response": { + "channelmoves": [ + { + "created_index": 1, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 500000000, + "debit_msat": 0, + "timestamp": 1738520000, + "primary_tag": "invoice", + "payment_hash": "paymenthashdelpay10101010101010101010101010101010101010101010101", + "fees_msat": 0 + }, + { + "created_index": 2, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 500000000, + "timestamp": 1738520000, + "primary_tag": "invoice", + "payment_hash": "8a46ab91013146df39e98ad7c89505fbb5419f110e928f7a393e8304f3057df7", + "part_id": 0, + "group_id": 1, + "fees_msat": 0 + }, + { + "created_index": 3, + "account_id": "f8fc83a432cbfb2fffe222cc06727fdd977b5dd10ebd6707158e799e6f522d9f", + "credit_msat": 0, + "debit_msat": 500000000, + "timestamp": 1758192801, + "primary_tag": "invoice", + "payment_hash": "88969daaf02214a1928e6eb62a237a8ee557f3da93b2c44f3901432c88f4334b", + "part_id": 0, + "group_id": 1, + "fees_msat": 0 + }, + { + "created_index": 4, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 10000, + "timestamp": 1758192801, + "primary_tag": "routed", + "payment_hash": "paymenthashinvl0310031003100310031003100310031003100310031003100", + "fees_msat": 1 + }, + { + "created_index": 5, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 10001, + "debit_msat": 0, + "timestamp": 1758192801, + "primary_tag": "routed", + "payment_hash": "paymenthashinvl0310031003100310031003100310031003100310031003100", + "fees_msat": 1 + }, + { + "created_index": 6, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 10000, + "timestamp": 1758192801, + "primary_tag": "routed", + "payment_hash": "paymenthashkey01k101k101k101k101k101k101k101k101k101k101k101k101", + "fees_msat": 1 + }, + { + "created_index": 7, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 10001, + "debit_msat": 0, + "timestamp": 1758192801, + "primary_tag": "routed", + "payment_hash": "paymenthashkey01k101k101k101k101k101k101k101k101k101k101k101k101", + "fees_msat": 1 + }, + { + "created_index": 8, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 10000101, + "timestamp": 1758192802, + "primary_tag": "routed", + "payment_hash": "paymenthashkey02k201k201k201k201k201k201k201k201k201k201k201k201", + "fees_msat": 101 + }, + { + "created_index": 9, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 10000202, + "debit_msat": 0, + "timestamp": 1758192802, + "primary_tag": "routed", + "payment_hash": "paymenthashkey02k201k201k201k201k201k201k201k201k201k201k201k201", + "fees_msat": 101 + }, + { + "created_index": 10, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 10000, + "timestamp": 1758192802, + "primary_tag": "routed", + "payment_hash": "paymenthashkey03k301k301k301k301k301k301k301k301k301k301k301k301", + "fees_msat": 1 + }, + { + "created_index": 11, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 10001, + "debit_msat": 0, + "timestamp": 1758192802, + "primary_tag": "routed", + "payment_hash": "paymenthashkey03k301k301k301k301k301k301k301k301k301k301k301k301", + "fees_msat": 1 + }, + { + "created_index": 12, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 50000, + "timestamp": 1758192802, + "primary_tag": "routed", + "payment_hash": "paymenthashinvl0320032003200320032003200320032003200320032003200", + "fees_msat": 1 + }, + { + "created_index": 13, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 50001, + "debit_msat": 0, + "timestamp": 1758192802, + "primary_tag": "routed", + "payment_hash": "paymenthashinvl0320032003200320032003200320032003200320032003200", + "fees_msat": 1 + }, + { + "created_index": 14, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 100000, + "timestamp": 1758192803, + "primary_tag": "invoice", + "payment_hash": "paymenthashinvl0330033003300330033003300330033003300330033003300", + "part_id": 0, + "group_id": 1, + "fees_msat": 0 + }, + { + "created_index": 15, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 10001, + "timestamp": 1758192803, + "primary_tag": "routed", + "payment_hash": "61b929204f4db4f38e0412b2bd4c3c03668dad3575fb05f4e15a2214046c2bff", + "fees_msat": 1 + }, + { + "created_index": 16, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 10002, + "debit_msat": 0, + "timestamp": 1758192803, + "primary_tag": "routed", + "payment_hash": "61b929204f4db4f38e0412b2bd4c3c03668dad3575fb05f4e15a2214046c2bff", + "fees_msat": 1 + }, + { + "created_index": 17, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 0, + "debit_msat": 1000000, + "timestamp": 1758192821, + "primary_tag": "invoice", + "payment_hash": "paymenthashsdinvsi10si10si10si10si10si10si10si10si10si10si10si10", + "part_id": 0, + "group_id": 1, + "fees_msat": 0 + }, + { + "created_index": 18, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 1000, + "debit_msat": 0, + "timestamp": 1758192821, + "primary_tag": "invoice", + "payment_hash": "paymenthashinvl0270027002700270027002700270027002700270027002700", + "fees_msat": 0 + } + ] + } + }, + { + "request": { + "id": "example:listchannelmoves#2", + "method": "listchannelmoves", + "params": { + "index": "created", + "start": 10, + "limit": 2 + } + }, + "response": { + "channelmoves": [ + { + "created_index": 10, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 10000, + "timestamp": 1758192802, + "primary_tag": "routed", + "payment_hash": "paymenthashkey03k301k301k301k301k301k301k301k301k301k301k301k301", + "fees_msat": 1 + }, + { + "created_index": 11, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 10001, + "debit_msat": 0, + "timestamp": 1758192802, + "primary_tag": "routed", + "payment_hash": "paymenthashkey03k301k301k301k301k301k301k301k301k301k301k301k301", + "fees_msat": 1 + } + ] + } + } ] }, "listchannels.json": { diff --git a/doc/schemas/listchainmoves.json b/doc/schemas/listchainmoves.json index 985105e93a55..eeec3e6b902e 100644 --- a/doc/schemas/listchainmoves.json +++ b/doc/schemas/listchainmoves.json @@ -197,5 +197,358 @@ ], "resources": [ "Main web site: " + ], + "examples": [ + { + "request": { + "id": "example:listchainmoves#1", + "method": "listchainmoves", + "params": {} + }, + "response": { + "chainmoves": [ + { + "created_index": 1, + "account_id": "wallet", + "credit_msat": 200000000000, + "debit_msat": 0, + "timestamp": 1758192762, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "994185cba7723715c0aa1d1859ce2781116776cea917035c90f8f04c9f4e095e:1", + "output_msat": 200000000000, + "blockheight": 104 + }, + { + "created_index": 2, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 0, + "debit_msat": 0, + "timestamp": 1758192777, + "primary_tag": "channel_open", + "extra_tags": [], + "utxo": "542906c8a9d90596592459a9484f4286a3200f6540599c83b43af2ac4166c6ca:1", + "peer_id": "nodeid010101010101010101010101010101010101010101010101010101010101", + "output_msat": 1000000000, + "blockheight": 109 + }, + { + "created_index": 3, + "account_id": "wallet", + "credit_msat": 2000000000, + "debit_msat": 0, + "timestamp": 1758192780, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "19e9e42f2f2097ea1dc18d7eb670bc53c90cbe31bb1daba8e94abf3c6b60d2dc:1", + "output_msat": 2000000000, + "blockheight": 110 + }, + { + "created_index": 4, + "account_id": "wallet", + "credit_msat": 0, + "debit_msat": 200000000000, + "timestamp": 1738530000, + "primary_tag": "withdrawal", + "extra_tags": [], + "utxo": "994185cba7723715c0aa1d1859ce2781116776cea917035c90f8f04c9f4e095e:1", + "spending_txid": "94418b652c9a0d79129552d317dcc37cb55afda1387257a22c7f16aa3981b7bc", + "output_msat": 200000000000, + "blockheight": 111 + }, + { + "created_index": 5, + "account_id": "wallet", + "credit_msat": 198995073000, + "debit_msat": 0, + "timestamp": 1738530000, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "94418b652c9a0d79129552d317dcc37cb55afda1387257a22c7f16aa3981b7bc:1", + "output_msat": 198995073000, + "blockheight": 111 + }, + { + "created_index": 6, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 1000000000, + "debit_msat": 0, + "timestamp": 1738530000, + "primary_tag": "channel_open", + "extra_tags": [ + "opener" + ], + "utxo": "94418b652c9a0d79129552d317dcc37cb55afda1387257a22c7f16aa3981b7bc:0", + "peer_id": "nodeid030303030303030303030303030303030303030303030303030303030303", + "output_msat": 1000000000, + "blockheight": 111 + }, + { + "created_index": 7, + "account_id": "wallet", + "credit_msat": 2000000000, + "debit_msat": 0, + "timestamp": 1758192792, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "b6d0090efbeb347fa59f90b321d6906cdf86779c15477582979fa427249f71f5:1", + "output_msat": 2000000000, + "blockheight": 114 + }, + { + "created_index": 8, + "account_id": "wallet", + "credit_msat": 0, + "debit_msat": 198995073000, + "timestamp": 1758192795, + "primary_tag": "withdrawal", + "extra_tags": [], + "utxo": "94418b652c9a0d79129552d317dcc37cb55afda1387257a22c7f16aa3981b7bc:1", + "spending_txid": "32de3d1592062670eb8630875a28705cc1988b7f83f8c712bf9d39be2152efec", + "output_msat": 198995073000, + "blockheight": 115 + }, + { + "created_index": 9, + "account_id": "wallet", + "credit_msat": 197990453000, + "debit_msat": 0, + "timestamp": 1758192795, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "32de3d1592062670eb8630875a28705cc1988b7f83f8c712bf9d39be2152efec:0", + "output_msat": 197990453000, + "blockheight": 115 + }, + { + "created_index": 10, + "account_id": "f8fc83a432cbfb2fffe222cc06727fdd977b5dd10ebd6707158e799e6f522d9f", + "credit_msat": 1000000000, + "debit_msat": 0, + "timestamp": 1758192795, + "primary_tag": "channel_open", + "extra_tags": [ + "opener" + ], + "utxo": "32de3d1592062670eb8630875a28705cc1988b7f83f8c712bf9d39be2152efec:1", + "peer_id": "nodeid050505050505050505050505050505050505050505050505050505050505", + "output_msat": 1000000000, + "blockheight": 115 + }, + { + "created_index": 11, + "account_id": "wallet", + "credit_msat": 486914000, + "debit_msat": 0, + "timestamp": 1738520000, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "874b26d4c523a902fdc44b88ec000eb5c3fe8754c9d44190a140561e24e77781:0", + "output_msat": 486914000, + "blockheight": 121 + }, + { + "created_index": 12, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 489809898, + "timestamp": 1738520000, + "primary_tag": "channel_close", + "extra_tags": [], + "utxo": "94418b652c9a0d79129552d317dcc37cb55afda1387257a22c7f16aa3981b7bc:0", + "spending_txid": "txid010101010101010101010101010101010101010101010101010101010101", + "output_msat": 1000000000, + "output_count": 2, + "blockheight": 121 + }, + { + "created_index": 13, + "account_id": "external", + "credit_msat": 510190000, + "debit_msat": 0, + "timestamp": 1738520000, + "primary_tag": "to_them", + "extra_tags": [], + "utxo": "874b26d4c523a902fdc44b88ec000eb5c3fe8754c9d44190a140561e24e77781:1", + "originating_account": "channelid0230000230000230000230000230000230000230000230000230000", + "output_msat": 510190000, + "blockheight": 121 + }, + { + "created_index": 14, + "account_id": "wallet", + "credit_msat": 2000000000, + "debit_msat": 0, + "timestamp": 1758192808, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "c9c9bec064382b6a6fb2a30d8923949b3c9f732465542b96e9ad1b5eebda4c7d:0", + "output_msat": 2000000000, + "blockheight": 122 + }, + { + "created_index": 15, + "account_id": "wallet", + "credit_msat": 0, + "debit_msat": 197990453000, + "timestamp": 1738500000, + "primary_tag": "withdrawal", + "extra_tags": [], + "utxo": "32de3d1592062670eb8630875a28705cc1988b7f83f8c712bf9d39be2152efec:0", + "spending_txid": "0137213d852e76d48f0270a78218d2f562ac0a8974f814cab66376537cfd1682", + "output_msat": 197990453000, + "blockheight": 123 + }, + { + "created_index": 16, + "account_id": "wallet", + "credit_msat": 196985833000, + "debit_msat": 0, + "timestamp": 1738500000, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "0137213d852e76d48f0270a78218d2f562ac0a8974f814cab66376537cfd1682:1", + "output_msat": 196985833000, + "blockheight": 123 + }, + { + "created_index": 17, + "account_id": "channelid0230200230200230200230200230200230200230200230200230200", + "credit_msat": 1000000000, + "debit_msat": 0, + "timestamp": 1738500000, + "primary_tag": "channel_open", + "extra_tags": [ + "opener" + ], + "utxo": "0137213d852e76d48f0270a78218d2f562ac0a8974f814cab66376537cfd1682:0", + "peer_id": "nodeid030303030303030303030303030303030303030303030303030303030303", + "output_msat": 1000000000, + "blockheight": 123 + } + ] + } + }, + { + "request": { + "id": "example:listchainmoves#2", + "method": "listchainmoves", + "params": { + "index": "created", + "start": 10 + } + }, + "response": { + "chainmoves": [ + { + "created_index": 10, + "account_id": "f8fc83a432cbfb2fffe222cc06727fdd977b5dd10ebd6707158e799e6f522d9f", + "credit_msat": 1000000000, + "debit_msat": 0, + "timestamp": 1758192795, + "primary_tag": "channel_open", + "extra_tags": [ + "opener" + ], + "utxo": "32de3d1592062670eb8630875a28705cc1988b7f83f8c712bf9d39be2152efec:1", + "peer_id": "nodeid050505050505050505050505050505050505050505050505050505050505", + "output_msat": 1000000000, + "blockheight": 115 + }, + { + "created_index": 11, + "account_id": "wallet", + "credit_msat": 486914000, + "debit_msat": 0, + "timestamp": 1738520000, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "874b26d4c523a902fdc44b88ec000eb5c3fe8754c9d44190a140561e24e77781:0", + "output_msat": 486914000, + "blockheight": 121 + }, + { + "created_index": 12, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 489809898, + "timestamp": 1738520000, + "primary_tag": "channel_close", + "extra_tags": [], + "utxo": "94418b652c9a0d79129552d317dcc37cb55afda1387257a22c7f16aa3981b7bc:0", + "spending_txid": "txid010101010101010101010101010101010101010101010101010101010101", + "output_msat": 1000000000, + "output_count": 2, + "blockheight": 121 + }, + { + "created_index": 13, + "account_id": "external", + "credit_msat": 510190000, + "debit_msat": 0, + "timestamp": 1738520000, + "primary_tag": "to_them", + "extra_tags": [], + "utxo": "874b26d4c523a902fdc44b88ec000eb5c3fe8754c9d44190a140561e24e77781:1", + "originating_account": "channelid0230000230000230000230000230000230000230000230000230000", + "output_msat": 510190000, + "blockheight": 121 + }, + { + "created_index": 14, + "account_id": "wallet", + "credit_msat": 2000000000, + "debit_msat": 0, + "timestamp": 1758192808, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "c9c9bec064382b6a6fb2a30d8923949b3c9f732465542b96e9ad1b5eebda4c7d:0", + "output_msat": 2000000000, + "blockheight": 122 + }, + { + "created_index": 15, + "account_id": "wallet", + "credit_msat": 0, + "debit_msat": 197990453000, + "timestamp": 1738500000, + "primary_tag": "withdrawal", + "extra_tags": [], + "utxo": "32de3d1592062670eb8630875a28705cc1988b7f83f8c712bf9d39be2152efec:0", + "spending_txid": "0137213d852e76d48f0270a78218d2f562ac0a8974f814cab66376537cfd1682", + "output_msat": 197990453000, + "blockheight": 123 + }, + { + "created_index": 16, + "account_id": "wallet", + "credit_msat": 196985833000, + "debit_msat": 0, + "timestamp": 1738500000, + "primary_tag": "deposit", + "extra_tags": [], + "utxo": "0137213d852e76d48f0270a78218d2f562ac0a8974f814cab66376537cfd1682:1", + "output_msat": 196985833000, + "blockheight": 123 + }, + { + "created_index": 17, + "account_id": "channelid0230200230200230200230200230200230200230200230200230200", + "credit_msat": 1000000000, + "debit_msat": 0, + "timestamp": 1738500000, + "primary_tag": "channel_open", + "extra_tags": [ + "opener" + ], + "utxo": "0137213d852e76d48f0270a78218d2f562ac0a8974f814cab66376537cfd1682:0", + "peer_id": "nodeid030303030303030303030303030303030303030303030303030303030303", + "output_msat": 1000000000, + "blockheight": 123 + } + ] + } + } ] } diff --git a/doc/schemas/listchannelmoves.json b/doc/schemas/listchannelmoves.json index d98a72b777a8..eba0f45a35db 100644 --- a/doc/schemas/listchannelmoves.json +++ b/doc/schemas/listchannelmoves.json @@ -145,5 +145,241 @@ ], "resources": [ "Main web site: " + ], + "examples": [ + { + "request": { + "id": "example:listchannelmoves#1", + "method": "listchannelmoves", + "params": {} + }, + "response": { + "channelmoves": [ + { + "created_index": 1, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 500000000, + "debit_msat": 0, + "timestamp": 1738520000, + "primary_tag": "invoice", + "payment_hash": "paymenthashdelpay10101010101010101010101010101010101010101010101", + "fees_msat": 0 + }, + { + "created_index": 2, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 500000000, + "timestamp": 1738520000, + "primary_tag": "invoice", + "payment_hash": "8a46ab91013146df39e98ad7c89505fbb5419f110e928f7a393e8304f3057df7", + "part_id": 0, + "group_id": 1, + "fees_msat": 0 + }, + { + "created_index": 3, + "account_id": "f8fc83a432cbfb2fffe222cc06727fdd977b5dd10ebd6707158e799e6f522d9f", + "credit_msat": 0, + "debit_msat": 500000000, + "timestamp": 1758192801, + "primary_tag": "invoice", + "payment_hash": "88969daaf02214a1928e6eb62a237a8ee557f3da93b2c44f3901432c88f4334b", + "part_id": 0, + "group_id": 1, + "fees_msat": 0 + }, + { + "created_index": 4, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 10000, + "timestamp": 1758192801, + "primary_tag": "routed", + "payment_hash": "paymenthashinvl0310031003100310031003100310031003100310031003100", + "fees_msat": 1 + }, + { + "created_index": 5, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 10001, + "debit_msat": 0, + "timestamp": 1758192801, + "primary_tag": "routed", + "payment_hash": "paymenthashinvl0310031003100310031003100310031003100310031003100", + "fees_msat": 1 + }, + { + "created_index": 6, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 10000, + "timestamp": 1758192801, + "primary_tag": "routed", + "payment_hash": "paymenthashkey01k101k101k101k101k101k101k101k101k101k101k101k101", + "fees_msat": 1 + }, + { + "created_index": 7, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 10001, + "debit_msat": 0, + "timestamp": 1758192801, + "primary_tag": "routed", + "payment_hash": "paymenthashkey01k101k101k101k101k101k101k101k101k101k101k101k101", + "fees_msat": 1 + }, + { + "created_index": 8, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 10000101, + "timestamp": 1758192802, + "primary_tag": "routed", + "payment_hash": "paymenthashkey02k201k201k201k201k201k201k201k201k201k201k201k201", + "fees_msat": 101 + }, + { + "created_index": 9, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 10000202, + "debit_msat": 0, + "timestamp": 1758192802, + "primary_tag": "routed", + "payment_hash": "paymenthashkey02k201k201k201k201k201k201k201k201k201k201k201k201", + "fees_msat": 101 + }, + { + "created_index": 10, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 10000, + "timestamp": 1758192802, + "primary_tag": "routed", + "payment_hash": "paymenthashkey03k301k301k301k301k301k301k301k301k301k301k301k301", + "fees_msat": 1 + }, + { + "created_index": 11, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 10001, + "debit_msat": 0, + "timestamp": 1758192802, + "primary_tag": "routed", + "payment_hash": "paymenthashkey03k301k301k301k301k301k301k301k301k301k301k301k301", + "fees_msat": 1 + }, + { + "created_index": 12, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 50000, + "timestamp": 1758192802, + "primary_tag": "routed", + "payment_hash": "paymenthashinvl0320032003200320032003200320032003200320032003200", + "fees_msat": 1 + }, + { + "created_index": 13, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 50001, + "debit_msat": 0, + "timestamp": 1758192802, + "primary_tag": "routed", + "payment_hash": "paymenthashinvl0320032003200320032003200320032003200320032003200", + "fees_msat": 1 + }, + { + "created_index": 14, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 100000, + "timestamp": 1758192803, + "primary_tag": "invoice", + "payment_hash": "paymenthashinvl0330033003300330033003300330033003300330033003300", + "part_id": 0, + "group_id": 1, + "fees_msat": 0 + }, + { + "created_index": 15, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 10001, + "timestamp": 1758192803, + "primary_tag": "routed", + "payment_hash": "61b929204f4db4f38e0412b2bd4c3c03668dad3575fb05f4e15a2214046c2bff", + "fees_msat": 1 + }, + { + "created_index": 16, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 10002, + "debit_msat": 0, + "timestamp": 1758192803, + "primary_tag": "routed", + "payment_hash": "61b929204f4db4f38e0412b2bd4c3c03668dad3575fb05f4e15a2214046c2bff", + "fees_msat": 1 + }, + { + "created_index": 17, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 0, + "debit_msat": 1000000, + "timestamp": 1758192821, + "primary_tag": "invoice", + "payment_hash": "paymenthashsdinvsi10si10si10si10si10si10si10si10si10si10si10si10", + "part_id": 0, + "group_id": 1, + "fees_msat": 0 + }, + { + "created_index": 18, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 1000, + "debit_msat": 0, + "timestamp": 1758192821, + "primary_tag": "invoice", + "payment_hash": "paymenthashinvl0270027002700270027002700270027002700270027002700", + "fees_msat": 0 + } + ] + } + }, + { + "request": { + "id": "example:listchannelmoves#2", + "method": "listchannelmoves", + "params": { + "index": "created", + "start": 10, + "limit": 2 + } + }, + "response": { + "channelmoves": [ + { + "created_index": 10, + "account_id": "a397dd9b3e44afcb67f3f3ce1d649b74a8ade63e35505985e4cc1828634f69a2", + "credit_msat": 0, + "debit_msat": 10000, + "timestamp": 1758192802, + "primary_tag": "routed", + "payment_hash": "paymenthashkey03k301k301k301k301k301k301k301k301k301k301k301k301", + "fees_msat": 1 + }, + { + "created_index": 11, + "account_id": "252d1b0a1e57895e84137f28cf19ab2c35847e284c112fefdecc7afeaa5c1de7", + "credit_msat": 10001, + "debit_msat": 0, + "timestamp": 1758192802, + "primary_tag": "routed", + "payment_hash": "paymenthashkey03k301k301k301k301k301k301k301k301k301k301k301k301", + "fees_msat": 1 + } + ] + } + } ] } diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index 41807050806f..40bfe551fa9e 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -479,7 +479,6 @@ static void dev_gossip_memleak(struct daemon *daemon, const u8 *msg) memleak_ptr(memtable, msg); /* Now delete daemon and those which it has pointers to. */ memleak_scan_obj(memtable, daemon); - memleak_scan_htable(memtable, &daemon->peers->raw); dev_seeker_memleak(memtable, daemon->seeker); gossmap_manage_memleak(memtable, daemon->gm); @@ -632,8 +631,7 @@ int main(int argc, char *argv[]) daemon = tal(NULL, struct daemon); daemon->developer = developer; daemon->dev_gossip_time = NULL; - daemon->peers = tal(daemon, struct peer_node_id_map); - peer_node_id_map_init(daemon->peers); + daemon->peers = new_htable(daemon, peer_node_id_map); daemon->deferred_txouts = tal_arr(daemon, struct short_channel_id, 0); daemon->current_blockheight = 0; /* i.e. unknown */ diff --git a/lightningd/bitcoind.c b/lightningd/bitcoind.c index 771ccf2f9f0a..879e2d87fe7c 100644 --- a/lightningd/bitcoind.c +++ b/lightningd/bitcoind.c @@ -703,7 +703,6 @@ struct filteredblock_call { struct filteredblock *result; struct filteredblock_outpoint **outpoints; size_t current_outpoint; - struct timeabs start_time; u32 height; }; @@ -858,7 +857,6 @@ void bitcoind_getfilteredblock_(const tal_t *ctx, call->arg = arg; call->height = height; assert(call->cb != NULL); - call->start_time = time_now(); call->result = NULL; call->current_outpoint = 0; diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index 59f004f732a7..5214b490ed0e 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -356,6 +356,37 @@ static void watch_for_utxo_reconfirmation(struct chain_topology *topo, } } +static enum watch_result tx_confirmed(struct lightningd *ld, + const struct bitcoin_txid *txid, + const struct bitcoin_tx *tx, + unsigned int depth, + void *unused) +{ + /* We don't actually need to do anything here: the fact that we were + * watching the tx made chaintopology.c update the transaction depth */ + if (depth != 0) + return DELETE_WATCH; + return KEEP_WATCHING; +} + +void watch_unconfirmed_txid(struct lightningd *ld, + struct chain_topology *topo, + const struct bitcoin_txid *txid) +{ + watch_txid(ld->wallet, topo, txid, tx_confirmed, NULL); +} + +static void watch_for_unconfirmed_txs(struct lightningd *ld, + struct chain_topology *topo) +{ + struct bitcoin_txid *txids; + + txids = wallet_transactions_by_height(tmpctx, ld->wallet, 0); + log_debug(ld->log, "Got %zu unconfirmed transactions", tal_count(txids)); + for (size_t i = 0; i < tal_count(txids); i++) + watch_unconfirmed_txid(ld, topo, &txids[i]); +} + /* Mutual recursion via timer. */ static void next_updatefee_timer(struct chain_topology *topo); @@ -1028,6 +1059,7 @@ static void remove_tip(struct chain_topology *topo) /* This may have unconfirmed txs: reconfirm as we add blocks. */ watch_for_utxo_reconfirmation(topo, topo->ld->wallet); + block_map_del(topo->block_map, b); /* These no longer exist, so gossipd drops any reference to them just @@ -1197,14 +1229,10 @@ struct chain_topology *new_topology(struct lightningd *ld, struct logger *log) struct chain_topology *topo = tal(ld, struct chain_topology); topo->ld = ld; - topo->block_map = tal(topo, struct block_map); - block_map_init(topo->block_map); - topo->outgoing_txs = tal(topo, struct outgoing_tx_map); - outgoing_tx_map_init(topo->outgoing_txs); - topo->txwatches = tal(topo, struct txwatch_hash); - txwatch_hash_init(topo->txwatches); - topo->txowatches = tal(topo, struct txowatch_hash); - txowatch_hash_init(topo->txowatches); + topo->block_map = new_htable(topo, block_map); + topo->outgoing_txs = new_htable(topo, outgoing_tx_map); + topo->txwatches = new_htable(topo, txwatch_hash); + topo->txowatches = new_htable(topo, txowatch_hash); topo->log = log; topo->bitcoind = new_bitcoind(topo, ld, log); topo->poll_seconds = 30; @@ -1478,6 +1506,11 @@ void setup_topology(struct chain_topology *topo) /* May have unconfirmed txs: reconfirm as we add blocks. */ watch_for_utxo_reconfirmation(topo, topo->ld->wallet); + + /* We usually watch txs because we have outputs coming to us, or they're + * related to a channel. But not if they're created by sendpsbt without any + * outputs to us. */ + watch_for_unconfirmed_txs(topo->ld, topo); db_commit_transaction(topo->ld->wallet->db); tal_free(local_ctx); diff --git a/lightningd/chaintopology.h b/lightningd/chaintopology.h index 4f80d21622a8..8a867b0e21f1 100644 --- a/lightningd/chaintopology.h +++ b/lightningd/chaintopology.h @@ -12,6 +12,7 @@ struct command; struct lightningd; struct peer; struct txwatch; +struct wallet; /* We keep the last three in case there are outliers (for min/max) */ #define FEE_HISTORY_NUM 3 @@ -280,4 +281,11 @@ void topology_add_sync_waiter_(const tal_t *ctx, /* In channel_control.c */ void notify_feerate_change(struct lightningd *ld); + +/* We want to update db when this txid is confirmed. We always do this + * if it's related to a channel or incoming funds, but sendpsbt without + * change would be otherwise untracked. */ +void watch_unconfirmed_txid(struct lightningd *ld, + struct chain_topology *topo, + const struct bitcoin_txid *txid); #endif /* LIGHTNING_LIGHTNINGD_CHAINTOPOLOGY_H */ diff --git a/lightningd/channel.c b/lightningd/channel.c index 354249a4c24c..1390a4868713 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -343,7 +343,6 @@ struct channel *new_unsaved_channel(struct peer *peer, channel->openchannel_signed_cmd = NULL; channel->state = DUALOPEND_OPEN_INIT; channel->owner = NULL; - channel->scb = NULL; channel->reestablished = false; memset(&channel->billboard, 0, sizeof(channel->billboard)); channel->billboard.transient = tal_fmt(channel, "%s", @@ -578,30 +577,6 @@ struct channel *new_channel(struct peer *peer, u64 dbid, channel->billboard.transient = tal_strdup(channel, transient_billboard); channel->channel_info = *channel_info; - /* If it's a unix domain socket connection, we don't save it */ - if (peer->addr.itype == ADDR_INTERNAL_WIREADDR) { - channel->scb = tal(channel, struct modern_scb_chan); - channel->scb->id = dbid; - /* More useful to have last_known_addr, if avail */ - if (peer->last_known_addr) - channel->scb->addr = *peer->last_known_addr; - channel->scb->addr = peer->addr.u.wireaddr.wireaddr; - channel->scb->node_id = peer->id; - channel->scb->funding = *funding; - channel->scb->cid = *cid; - channel->scb->funding_sats = funding_sats; - channel->scb->type = channel_type_dup(channel->scb, type); - - struct tlv_scb_tlvs *scb_tlvs = tlv_scb_tlvs_new(channel); - scb_tlvs->shachain = &channel->their_shachain.chain; - scb_tlvs->basepoints = &channel->channel_info.theirbase; - scb_tlvs->opener = &channel->opener; - scb_tlvs->remote_to_self_delay = &channel->channel_info.their_config.to_self_delay; - - channel->scb->tlvs = scb_tlvs; - } else - channel->scb = NULL; - if (!log) { channel->log = new_logger(channel, peer->ld->log_book, diff --git a/lightningd/channel.h b/lightningd/channel.h index af2f18a54b8a..fd8e031b0c39 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -343,10 +343,6 @@ struct channel { /* Lease commited max part per thousandth channel fee (ppm * 1000) */ u16 lease_chan_max_ppt; - /* `Channel-shell` of this channel - * (Minimum information required to backup this channel). */ - struct modern_scb_chan *scb; - /* Do we allow the peer to set any fee it wants? */ bool ignore_fee_limits; diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index a72f959837ae..78102f2579f0 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -1134,7 +1135,8 @@ static void handle_peer_splice_locked(struct channel *channel, const u8 *msg) wallet_htlcsigs_confirm_inflight(channel->peer->ld->wallet, channel, &inflight->funding->outpoint); - update_channel_from_inflight(channel->peer->ld, channel, inflight, true); + /* Stop watching previous funding tx (could be, for announcement) */ + channel_unwatch_funding(channel->peer->ld, channel); /* Stash prev funding data so we can log it after scid is updated * (to get the blockheight) */ @@ -1142,6 +1144,8 @@ static void handle_peer_splice_locked(struct channel *channel, const u8 *msg) prev_funding_sats = channel->funding_sats; prev_funding_out = channel->funding; + update_channel_from_inflight(channel->peer->ld, channel, inflight, true); + channel->our_msat.millisatoshis += splice_amnt * 1000; /* Raw: splicing */ channel->msat_to_us_min.millisatoshis += splice_amnt * 1000; /* Raw: splicing */ channel->msat_to_us_max.millisatoshis += splice_amnt * 1000; /* Raw: splicing */ @@ -1824,6 +1828,11 @@ bool peer_start_channeld(struct channel *channel, if (inflight->splice_locked_memonly) continue; + if (!inflight->funding->splice_remote_funding) { + send_backtrace("Inflight has no splice_remote_funding?!"); + continue; + } + infcopy = tal(inflights, struct inflight); infcopy->remote_funding = *inflight->funding->splice_remote_funding; diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index 1e46c06a991c..ab84e3f498bd 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -1467,28 +1467,9 @@ wallet_commit_channel(struct lightningd *ld, &commitment_feerate); channel->min_possible_feerate = commitment_feerate; channel->max_possible_feerate = commitment_feerate; - if (channel->peer->addr.itype == ADDR_INTERNAL_WIREADDR) { - channel->scb = tal(channel, struct modern_scb_chan); - channel->scb->id = channel->dbid; - channel->scb->addr = channel->peer->addr.u.wireaddr.wireaddr; - channel->scb->node_id = channel->peer->id; - channel->scb->funding = *funding; - channel->scb->cid = channel->cid; - channel->scb->funding_sats = total_funding; - - struct tlv_scb_tlvs *scb_tlvs = tlv_scb_tlvs_new(channel); - scb_tlvs->shachain = &channel->their_shachain.chain; - scb_tlvs->basepoints = &channel_info->theirbase; - scb_tlvs->opener = &channel->opener; - scb_tlvs->remote_to_self_delay = &channel_info->their_config.to_self_delay; - - channel->scb->tlvs = scb_tlvs; - } else - channel->scb = NULL; tal_free(channel->type); channel->type = channel_type_dup(channel, type); - channel->scb->type = channel_type_dup(channel->scb, type); if (our_upfront_shutdown_script) channel->shutdown_scriptpubkey[LOCAL] diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 5a350daeb43e..7a529b489e13 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -190,42 +190,34 @@ static struct lightningd *new_lightningd(const tal_t *ctx) * list attached to the channel structure itself, or even left them in * the database rather than making an in-memory version. Obviously * I was in a premature optimization mood when I wrote this: */ - ld->htlcs_in = tal(ld, struct htlc_in_map); - htlc_in_map_init(ld->htlcs_in); + ld->htlcs_in = new_htable(ld, htlc_in_map); /*~ Note also: we didn't need to use an allocation here! We could * have simply made the `struct htlc_out_map` a member. But we * override the htable allocation routines to use tal(), and they * want a tal parent, so we always make our hash table a tallocated * object. */ - ld->htlcs_out = tal(ld, struct htlc_out_map); - htlc_out_map_init(ld->htlcs_out); + ld->htlcs_out = new_htable(ld, htlc_out_map); /*~ This is the hash table of peers: converted from a * linked-list as part of the 100k-peers project! */ - ld->peers = tal(ld, struct peer_node_id_map); - peer_node_id_map_init(ld->peers); + ld->peers = new_htable(ld, peer_node_id_map); /*~ And this was done at the same time, for db lookups at startup */ - ld->peers_by_dbid = tal(ld, struct peer_dbid_map); - peer_dbid_map_init(ld->peers_by_dbid); + ld->peers_by_dbid = new_htable(ld, peer_dbid_map); /*~ This speeds lookups for short_channel_ids to their channels. */ - ld->channels_by_scid = tal(ld, struct channel_scid_map); - channel_scid_map_init(ld->channels_by_scid); + ld->channels_by_scid = new_htable(ld, channel_scid_map); /*~ Coin movements in db are indexed by the channel dbid. */ - ld->channels_by_dbid = tal(ld, struct channel_dbid_map); - channel_dbid_map_init(ld->channels_by_dbid); + ld->channels_by_dbid = new_htable(ld, channel_dbid_map); /*~ For multi-part payments, we need to keep some incoming payments * in limbo until we get all the parts, or we time them out. */ - ld->htlc_sets = tal(ld, struct htlc_set_map); - htlc_set_map_init(ld->htlc_sets); + ld->htlc_sets = new_htable(ld, htlc_set_map); /*~ We keep a map of closed channels. Mainly so we can respond to peers * who talk to us about long-closed channels. */ - ld->closed_channels = tal(ld, struct closed_channel_map); - closed_channel_map_init(ld->closed_channels); + ld->closed_channels = new_htable(ld, closed_channel_map); /*~ We have a multi-entry log-book infrastructure: we define a 10MB log * book to hold all the entries (and trims as necessary), and multiple diff --git a/lightningd/memdump.c b/lightningd/memdump.c index b2f32a10636f..31d84b0e057f 100644 --- a/lightningd/memdump.c +++ b/lightningd/memdump.c @@ -194,19 +194,6 @@ static bool lightningd_check_leaks(struct command *cmd) memleak_ptr(memtable, cmd); memleak_ignore_children(memtable, cmd); - /* First delete known false positives. */ - memleak_scan_htable(memtable, &ld->topology->txwatches->raw); - memleak_scan_htable(memtable, &ld->topology->txowatches->raw); - memleak_scan_htable(memtable, &ld->topology->outgoing_txs->raw); - memleak_scan_htable(memtable, &ld->htlcs_in->raw); - memleak_scan_htable(memtable, &ld->htlcs_out->raw); - memleak_scan_htable(memtable, &ld->htlc_sets->raw); - memleak_scan_htable(memtable, &ld->peers->raw); - memleak_scan_htable(memtable, &ld->peers_by_dbid->raw); - memleak_scan_htable(memtable, &ld->channels_by_scid->raw); - memleak_scan_htable(memtable, &ld->closed_channels->raw); - wallet_memleak_scan(memtable, ld->wallet); - /* Now delete ld and those which it has pointers to. */ memleak_scan_obj(memtable, ld); diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index b82523ab1b38..4d2723a5d1db 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -49,13 +49,6 @@ static bool replay_tx_eq_txid(const struct replay_tx *rtx, HTABLE_DEFINE_NODUPS_TYPE(struct replay_tx, replay_tx_keyof, txid_hash, replay_tx_eq_txid, replay_tx_hash); -/* Helper for memleak detection */ -static void memleak_replay_tx_hash(struct htable *memtable, - struct replay_tx_hash *replay_tx_hash) -{ - memleak_scan_htable(memtable, &replay_tx_hash->raw); -} - /* We dump all the known preimages when onchaind starts up. */ static void onchaind_tell_fulfill(struct channel *channel) { @@ -1904,11 +1897,8 @@ void onchaind_replay_channels(struct lightningd *ld) channel_state_name(channel), blockheight); /* We're in replay mode */ - channel->onchaind_replay_watches = tal(channel, struct replay_tx_hash); + channel->onchaind_replay_watches = new_htable(channel, replay_tx_hash); channel->onchaind_replay_height = blockheight; - replay_tx_hash_init(channel->onchaind_replay_watches); - memleak_add_helper(channel->onchaind_replay_watches, - memleak_replay_tx_hash); onchaind_funding_spent(channel, tx, blockheight); onchaind_replay(channel); diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 19780fae7e7a..4cc212eff2d7 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -2382,6 +2382,14 @@ void channel_watch_wrong_funding(struct lightningd *ld, struct channel *channel) } } +/* We need to do this before we change channel funding (for splice), otherwise + * funding_depth_cb will fail the assertion that it's the current funding tx */ +void channel_unwatch_funding(struct lightningd *ld, struct channel *channel) +{ + tal_free(find_txwatch(ld->topology, + &channel->funding.txid, funding_depth_cb, channel)); +} + void channel_watch_funding(struct lightningd *ld, struct channel *channel) { log_debug(channel->log, "Watching for funding txid: %s", @@ -2480,15 +2488,35 @@ static void json_add_scb(struct command *cmd, struct json_stream *response, struct channel *c) { - u8 *scb = tal_arr(cmd, u8, 0); + u8 *scb_wire = tal_arr(cmd, u8, 0); + struct modern_scb_chan *scb; - /* Update shachain & basepoints in SCB. */ - c->scb->tlvs->shachain = &c->their_shachain.chain; - c->scb->tlvs->basepoints = &c->channel_info.theirbase; - towire_modern_scb_chan(&scb, c->scb); + /* Don't do scb for unix domain sockets. */ + if (c->peer->addr.itype != ADDR_INTERNAL_WIREADDR) + return; - json_add_hex_talarr(response, fieldname, - scb); + scb = tal(tmpctx, struct modern_scb_chan); + scb->id = c->dbid; + /* More useful to have last_known_addr, if avail */ + if (c->peer->last_known_addr) + scb->addr = *c->peer->last_known_addr; + else + scb->addr = c->peer->addr.u.wireaddr.wireaddr; + scb->node_id = c->peer->id; + scb->funding = c->funding; + scb->cid = c->cid; + scb->funding_sats = c->funding_sats; + scb->type = channel_type_dup(scb, c->type); + + scb->tlvs = tlv_scb_tlvs_new(scb); + scb->tlvs->shachain = &c->their_shachain.chain; + scb->tlvs->basepoints = &c->channel_info.theirbase; + scb->tlvs->opener = &c->opener; + scb->tlvs->remote_to_self_delay = &c->channel_info.their_config.to_self_delay; + + towire_modern_scb_chan(&scb_wire, scb); + + json_add_hex_talarr(response, fieldname, scb_wire); } /* This will return a SCB for all the channels currently loaded @@ -2513,9 +2541,6 @@ static struct command_result *json_staticbackup(struct command *cmd, peer = peer_node_id_map_next(cmd->ld->peers, &it)) { struct channel *channel; list_for_each(&peer->channels, channel, list){ - /* cppcheck-suppress uninitvar - false positive on channel */ - if (!channel->scb) - continue; json_add_scb(cmd, NULL, response, channel); } } diff --git a/lightningd/peer_control.h b/lightningd/peer_control.h index 382d0826baf1..63826f5b628d 100644 --- a/lightningd/peer_control.h +++ b/lightningd/peer_control.h @@ -131,6 +131,7 @@ void update_channel_from_inflight(struct lightningd *ld, const struct channel_inflight *inflight, bool is_splice); +void channel_unwatch_funding(struct lightningd *ld, struct channel *channel); void channel_watch_funding(struct lightningd *ld, struct channel *channel); /* If this channel has a "wrong funding" shutdown, watch that too. */ diff --git a/lightningd/plugin.c b/lightningd/plugin.c index 42718c27bb7a..98d95d42d54e 100644 --- a/lightningd/plugin.c +++ b/lightningd/plugin.c @@ -2697,16 +2697,24 @@ static void dev_save_plugin_io(struct plugins *plugins, const char *buf, size_t len) { static size_t counter; + static u64 starttime; const char *file; int fd; if (!plugins->dev_save_io) return; + /* If we reexec, we still want unique names */ + if (!starttime) { + struct timemono start = time_mono(); + starttime = start.ts.tv_sec * 1000000 + start.ts.tv_nsec / 1000; + } + file = path_join(tmpctx, plugins->dev_save_io, - take(tal_fmt(NULL, "%s-%s-%u-%zu", + take(tal_fmt(NULL, "%s-%s-%u-%"PRIu64"-%zu", type, name, (unsigned int)getpid(), + starttime, counter++))); fd = open(file, O_CREAT|O_EXCL|O_WRONLY, 0600); if (fd < 0 || !write_all(fd, buf, len)) diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index 00eef5e44b70..1c885a1b2c84 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -144,6 +144,10 @@ const char *channel_state_name(const struct channel *channel UNNEEDED) /* 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_type_dup */ +struct channel_type *channel_type_dup(const tal_t *ctx UNNEEDED, + const struct channel_type *t UNNEEDED) +{ fprintf(stderr, "channel_type_dup called!\n"); abort(); } /* Generated stub for channel_type_has */ bool channel_type_has(const struct channel_type *type UNNEEDED, int feature UNNEEDED) { fprintf(stderr, "channel_type_has called!\n"); abort(); } @@ -291,6 +295,16 @@ struct channel *find_channel_by_id(const struct peer *peer UNNEEDED, struct plugin *find_plugin_for_command(struct lightningd *ld UNNEEDED, const char *cmd_name UNNEEDED) { fprintf(stderr, "find_plugin_for_command called!\n"); abort(); } +/* Generated stub for find_txwatch_ */ +struct txwatch *find_txwatch_(struct chain_topology *topo UNNEEDED, + const struct bitcoin_txid *txid UNNEEDED, + enum watch_result (*cb)(struct lightningd *ld UNNEEDED, + const struct bitcoin_txid * UNNEEDED, + const struct bitcoin_tx * UNNEEDED, + unsigned int depth UNNEEDED, + void *arg) UNNEEDED, + void *arg UNNEEDED) +{ fprintf(stderr, "find_txwatch_ called!\n"); abort(); } /* Generated stub for fixup_htlcs_out */ void fixup_htlcs_out(struct lightningd *ld UNNEEDED) { fprintf(stderr, "fixup_htlcs_out called!\n"); abort(); } @@ -969,6 +983,9 @@ void subd_send_fd(struct subd *sd UNNEEDED, int fd UNNEEDED) /* Generated stub for subd_send_msg */ void subd_send_msg(struct subd *sd UNNEEDED, const u8 *msg_out UNNEEDED) { fprintf(stderr, "subd_send_msg called!\n"); abort(); } +/* Generated stub for tlv_scb_tlvs_new */ +struct tlv_scb_tlvs *tlv_scb_tlvs_new(const tal_t *ctx UNNEEDED) +{ fprintf(stderr, "tlv_scb_tlvs_new called!\n"); abort(); } /* Generated stub for towire_bigsize */ void towire_bigsize(u8 **pptr UNNEEDED, const bigsize_t val UNNEEDED) { fprintf(stderr, "towire_bigsize called!\n"); abort(); } diff --git a/onchaind/test/run-grind_feerate.c b/onchaind/test/run-grind_feerate.c index e413f100d043..c9b1d4dd5368 100644 --- a/onchaind/test/run-grind_feerate.c +++ b/onchaind/test/run-grind_feerate.c @@ -356,7 +356,7 @@ int main(int argc, char *argv[]) struct amount_sat fee; struct pubkey htlc_key; struct keyset *keys; - struct timeabs start, end; + struct timemono start, end; int iterations = 1000; u8 *spk = tal_arr(tmpctx, u8, 1); spk[0] = 0x00; @@ -388,15 +388,15 @@ int main(int argc, char *argv[]) max_possible_feerate = 250000; min_possible_feerate = max_possible_feerate + 1 - iterations; - start = time_now(); + start = time_mono(); if (!grind_htlc_tx_fee(&fee, tx, &sig, wscript, 663)) abort(); - end = time_now(); + end = time_mono(); assert(amount_sat_eq(fee, AMOUNT_SAT(165750))); printf("%u iterations in %"PRIu64" msec = %"PRIu64" nsec each\n", iterations, - time_to_msec(time_between(end, start)), - time_to_nsec(time_divide(time_between(end, start), iterations))); + time_to_msec(timemono_between(end, start)), + time_to_nsec(time_divide(timemono_between(end, start), iterations))); common_shutdown(); return 0; diff --git a/plugins/askrene/askrene.c b/plugins/askrene/askrene.c index 9664d2487d7f..7f7f2d0d50c3 100644 --- a/plugins/askrene/askrene.c +++ b/plugins/askrene/askrene.c @@ -1290,13 +1290,6 @@ static const struct plugin_command commands[] = { }, }; -static void askrene_markmem(struct plugin *plugin, struct htable *memtable) -{ - struct askrene *askrene = get_askrene(plugin); - layer_memleak_mark(askrene, memtable); - reserve_memleak_mark(askrene, memtable); -} - static const char *init(struct command *init_cmd, const char *buf UNUSED, const jsmntok_t *config UNUSED) { @@ -1316,7 +1309,6 @@ static const char *init(struct command *init_cmd, "{id:%}", JSON_SCAN(json_to_node_id, &askrene->my_id)); plugin_set_data(plugin, askrene); - plugin_set_memleak_handler(plugin, askrene_markmem); load_layers(askrene, init_cmd); diff --git a/plugins/askrene/layer.c b/plugins/askrene/layer.c index 281e32a03c7b..4cbe657ac637 100644 --- a/plugins/askrene/layer.c +++ b/plugins/askrene/layer.c @@ -162,14 +162,10 @@ struct layer *new_temp_layer(const tal_t *ctx, struct askrene *askrene, const ch l->askrene = askrene; l->name = tal_strdup(l, name); l->persistent = false; - l->local_channels = tal(l, struct local_channel_hash); - local_channel_hash_init(l->local_channels); - l->local_updates = tal(l, struct local_update_hash); - local_update_hash_init(l->local_updates); - l->constraints = tal(l, struct constraint_hash); - constraint_hash_init(l->constraints); - l->biases = tal(l, struct bias_hash); - bias_hash_init(l->biases); + l->local_channels = new_htable(l, local_channel_hash); + l->local_updates = new_htable(l, local_update_hash); + l->constraints = new_htable(l, constraint_hash); + l->biases = new_htable(l, bias_hash); l->disabled_nodes = tal_arr(l, struct node_id, 0); return l; @@ -1162,14 +1158,3 @@ bool layer_disables_node(const struct layer *layer, } return false; } - -void layer_memleak_mark(struct askrene *askrene, struct htable *memtable) -{ - struct layer *l; - list_for_each(&askrene->layers, l, list) { - memleak_scan_htable(memtable, &l->constraints->raw); - memleak_scan_htable(memtable, &l->local_channels->raw); - memleak_scan_htable(memtable, &l->local_updates->raw); - memleak_scan_htable(memtable, &l->biases->raw); - } -} diff --git a/plugins/askrene/layer.h b/plugins/askrene/layer.h index e9b06fd5a4e6..b93f228ff05d 100644 --- a/plugins/askrene/layer.h +++ b/plugins/askrene/layer.h @@ -135,6 +135,4 @@ bool layer_disables_chan(const struct layer *layer, const struct short_channel_i /* For explain_failure: did this layer disable this node? */ bool layer_disables_node(const struct layer *layer, const struct node_id *node); -/* Scan for memleaks */ -void layer_memleak_mark(struct askrene *askrene, struct htable *memtable); #endif /* LIGHTNING_PLUGINS_ASKRENE_LAYER_H */ diff --git a/plugins/askrene/reserve.c b/plugins/askrene/reserve.c index abec9372dfc7..678ca248d667 100644 --- a/plugins/askrene/reserve.c +++ b/plugins/askrene/reserve.c @@ -36,9 +36,7 @@ HTABLE_DEFINE_DUPS_TYPE(struct reserve, reserve_scidd, hash_scidd, struct reserve_htable *new_reserve_htable(const tal_t *ctx) { - struct reserve_htable *reserved = tal(ctx, struct reserve_htable); - reserve_htable_init(reserved); - return reserved; + return new_htable(ctx, reserve_htable); } void reserve_add(struct reserve_htable *reserved, @@ -176,8 +174,3 @@ const char *fmt_reservations(const tal_t *ctx, } return ret; } - -void reserve_memleak_mark(struct askrene *askrene, struct htable *memtable) -{ - memleak_scan_htable(memtable, &askrene->reserved->raw); -} diff --git a/plugins/askrene/reserve.h b/plugins/askrene/reserve.h index 1c9e71eaaf60..868756ca0d9a 100644 --- a/plugins/askrene/reserve.h +++ b/plugins/askrene/reserve.h @@ -50,6 +50,4 @@ void json_add_reservations(struct json_stream *js, const struct reserve_htable *reserved, const char *fieldname); -/* Scan for memleaks */ -void reserve_memleak_mark(struct askrene *askrene, struct htable *memtable); #endif /* LIGHTNING_PLUGINS_ASKRENE_RESERVE_H */ diff --git a/plugins/chanbackup.c b/plugins/chanbackup.c index 11091edd92c4..16d6cb6189df 100644 --- a/plugins/chanbackup.c +++ b/plugins/chanbackup.c @@ -1040,10 +1040,8 @@ static void setup_backup_map(struct command *init_cmd, const jsmntok_t *datastore, *t; size_t i, total = 0; - cb->backups = tal(cb, struct backup_map); - backup_map_init(cb->backups); - cb->peers = tal(cb, struct peer_map); - peer_map_init(cb->peers); + cb->backups = new_htable(cb, backup_map); + cb->peers = new_htable(cb, peer_map); json_out_start(params, NULL, '{'); json_out_start(params, "key", '['); @@ -1084,14 +1082,6 @@ static void setup_backup_map(struct command *init_cmd, "Loaded %zu stored backups for peers", total); } -static void chanbackup_mark_mem(struct plugin *plugin, - struct htable *memtable) -{ - const struct chanbackup *cb = chanbackup(plugin); - memleak_scan_htable(memtable, &cb->backups->raw); - memleak_scan_htable(memtable, &cb->peers->raw); -} - static const char *init(struct command *init_cmd, const char *buf UNUSED, const jsmntok_t *config UNUSED) @@ -1132,9 +1122,6 @@ static const char *init(struct command *init_cmd, unlink_noerr("scb.tmp"); maybe_create_new_scb(init_cmd->plugin, scb_chan); - - plugin_set_memleak_handler(init_cmd->plugin, - chanbackup_mark_mem); return NULL; } diff --git a/plugins/channel_hint.c b/plugins/channel_hint.c index 1db37791ea0a..7a14f3992a44 100644 --- a/plugins/channel_hint.c +++ b/plugins/channel_hint.c @@ -23,12 +23,6 @@ bool channel_hint_eq(const struct channel_hint *a, a->scid.dir == b->dir; } -static void memleak_help_channel_hint_map(struct htable *memtable, - struct channel_hint_map *channel_hints) -{ - memleak_scan_htable(memtable, &channel_hints->raw); -} - void channel_hint_to_json(const char *name, const struct channel_hint *hint, struct json_stream *dest) { @@ -211,9 +205,7 @@ struct channel_hint *channel_hint_from_json(const tal_t *ctx, struct channel_hint_set *channel_hint_set_new(const tal_t *ctx) { struct channel_hint_set *set = tal(ctx, struct channel_hint_set); - set->hints = tal(set, struct channel_hint_map); - channel_hint_map_init(set->hints); - memleak_add_helper(set->hints, memleak_help_channel_hint_map); + set->hints = new_htable(set, channel_hint_map); return set; } diff --git a/tests/autogenerate-rpc-examples.py b/tests/autogenerate-rpc-examples.py index bfd564288c4f..1036adbd7a55 100644 --- a/tests/autogenerate-rpc-examples.py +++ b/tests/autogenerate-rpc-examples.py @@ -972,6 +972,19 @@ def generate_bookkeeper_examples(l2, l3, c23_2_chan_id): raise +def generate_coinmvt_examples(l2): + """Generates listchannelmoves and listchainmoves rpc examples""" + try: + logger.info('listcoinmoves Start...') + update_example(node=l2, method='listchainmoves', params={}) + update_example(node=l2, method='listchainmoves', params={'index': 'created', 'start': 10}) + update_example(node=l2, method='listchannelmoves', params={}) + update_example(node=l2, method='listchannelmoves', params={'index': 'created', 'start': 10, 'limit': 2}) + except Exception as e: + logger.error(f'Error in generating coinmoves examples: {e}') + raise + + def generate_offers_renepay_examples(l1, l2, inv_l21, inv_l34): """Covers all offers and renepay related examples""" try: @@ -2096,6 +2109,7 @@ def list_missing_examples(): c23_2, c23res2, c34_2, inv_l11, inv_l21, inv_l22, inv_l31, inv_l32, inv_l34 = generate_transactions_examples(l1, l2, l3, l4, l5, c25, bitcoind) rune_l21 = generate_runes_examples(l1, l2, l3) generate_datastore_examples(l2) + generate_coinmvt_examples(l2) generate_bookkeeper_examples(l2, l3, c23res2['channel_id']) offer_l23, inv_req_l1_l22 = generate_offers_renepay_examples(l1, l2, inv_l21, inv_l34) generate_askrene_examples(l1, l2, l3, c12, c23_2) diff --git a/tests/test_misc.py b/tests/test_misc.py index a4d355b12b72..665e3c8d4018 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -3689,8 +3689,6 @@ def test_version_reexec(node_factory, bitcoind): # We use a file to tell our openingd wrapper where the real one is with open(os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, "openingd-real"), 'w') as f: f.write(os.path.abspath('lightningd/lightning_openingd')) - # Internal restart doesn't work well with --dev-save-plugin-io - del l1.daemon.opts['dev-save-plugin-io'] l1.start() # This is a "version" message verfile = os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, "openingd-version") @@ -4566,11 +4564,7 @@ def test_setconfig_changed(node_factory, bitcoind): @unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "deletes database, which is assumed sqlite3") def test_recover_command(node_factory, bitcoind): - l1 = node_factory.get_node(start=False) - # Internal restart doesn't work well with --dev-save-plugin-io - del l1.daemon.opts['dev-save-plugin-io'] - l1.start() - l2 = node_factory.get_node() + l1, l2 = node_factory.get_nodes(2) l1oldid = l1.info['id'] diff --git a/tests/test_splicing.py b/tests/test_splicing.py index 996afcec3897..50d91b2f9303 100644 --- a/tests/test_splicing.py +++ b/tests/test_splicing.py @@ -556,3 +556,31 @@ def test_route_by_old_scid(node_factory, bitcoind): wait_for(lambda: only_one(l1.rpc.listpeers()['peers'])['connected'] is True) l1.rpc.sendpay(route, inv2['payment_hash'], payment_secret=inv2['payment_secret']) l1.rpc.waitsendpay(inv2['payment_hash']) + + +@pytest.mark.openchannel('v1') +@pytest.mark.openchannel('v2') +def test_splice_unannounced(node_factory, bitcoind): + l1, l2 = node_factory.line_graph(2, fundamount=1000000, wait_for_announce=False, opts={'experimental-splicing': None}) + + chan_id = l1.get_channel_id(l2) + + # add extra sats to pay fee + funds_result = l1.rpc.fundpsbt("109000sat", "slow", 166, excess_as_change=True) + result = l1.rpc.splice_init(chan_id, 100000, funds_result['psbt']) + result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is False) + result = l1.rpc.splice_update(chan_id, result['psbt']) + assert(result['commitments_secured'] is True) + result = l1.rpc.signpsbt(result['psbt']) + result = l1.rpc.splice_signed(chan_id, result['signed_psbt']) + + l2.daemon.wait_for_log(r'CHANNELD_NORMAL to CHANNELD_AWAITING_SPLICE') + l1.daemon.wait_for_log(r'CHANNELD_NORMAL to CHANNELD_AWAITING_SPLICE') + + bitcoind.generate_block(1, wait_for_mempool=1) + + l2.daemon.wait_for_log(r'CHANNELD_AWAITING_SPLICE to CHANNELD_NORMAL') + l1.daemon.wait_for_log(r'CHANNELD_AWAITING_SPLICE to CHANNELD_NORMAL') + bitcoind.generate_block(1) + sync_blockheight(bitcoind, [l1, l2]) diff --git a/tests/test_wallet.py b/tests/test_wallet.py index b26679b1856c..c2cd96aafafc 100644 --- a/tests/test_wallet.py +++ b/tests/test_wallet.py @@ -1887,6 +1887,34 @@ def test_onchain_missing_no_p2tr_migrate(node_factory, bitcoind): l2.daemon.wait_for_log('Rescan finished! 1 outputs recovered') +@pytest.mark.parametrize("restart", [False, True]) +def test_sendpsbt_confirm(node_factory, bitcoind, restart): + """We should see our sendpsbt in wallet, and that it gets confirmed""" + l1, l2 = node_factory.get_nodes(2) + l1.fundwallet(100000) + + psbt = l1.rpc.fundpsbt(satoshi=10000, + feerate=7500, + startweight=42)['psbt'] + psbt = l2.rpc.addpsbtoutput(10000, psbt)['psbt'] + psbt = l1.rpc.signpsbt(psbt)['signed_psbt'] + sent = l1.rpc.sendpsbt(psbt) + + # Unconfirmed + lt = only_one([t for t in l1.rpc.listtransactions()['transactions'] if t['rawtx'] == sent['tx']]) + assert lt['blockheight'] == 0 + + if restart: + l1.restart() + + bitcoind.generate_block(1, wait_for_mempool=sent['txid']) + sync_blockheight(bitcoind, [l1]) + + # Should be confirmed now! + lt = only_one([t for t in l1.rpc.listtransactions()['transactions'] if t['rawtx'] == sent['tx']]) + assert lt['blockheight'] == bitcoind.rpc.getblockcount() + + def test_old_htlcs_cleanup(node_factory, bitcoind): """We lazily delete htlcs from channel_htlcs table""" l1, l2 = node_factory.line_graph(2) diff --git a/tools/Makefile b/tools/Makefile index 6b92ebdd5555..3922ce0c8566 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -18,7 +18,7 @@ tools/headerversions: $(FORCE) tools/headerversions.o libccan.a tools/headerversions.o: ccan/config.h tools/check-bolt: tools/check-bolt.o $(TOOLS_COMMON_OBJS) -tools/hsmtool: tools/hsmtool.o $(TOOLS_COMMON_OBJS) $(BITCOIN_OBJS) common/amount.o common/autodata.o common/bech32.o common/bech32_util.o common/bigsize.o common/codex32.o common/configdir.o common/configvar.o common/derive_basepoints.o common/descriptor_checksum.o common/hsm_encryption.o common/key_derive.o common/node_id.o common/version.o wire/fromwire.o wire/towire.o +tools/hsmtool: tools/hsmtool.o $(TOOLS_COMMON_OBJS) $(BITCOIN_OBJS) common/amount.o common/autodata.o common/bech32.o common/bech32_util.o common/bigsize.o common/codex32.o common/configdir.o common/configvar.o common/derive_basepoints.o common/descriptor_checksum.o common/hsm_encryption.o common/key_derive.o common/node_id.o common/version.o common/memleak.o wire/fromwire.o wire/towire.o tools/lightning-hsmtool: tools/hsmtool cp $< $@ diff --git a/wallet/test/run-chain_moves_duplicate-detect.c b/wallet/test/run-chain_moves_duplicate-detect.c index fdf62145e64a..d8e236b9dfdd 100644 --- a/wallet/test/run-chain_moves_duplicate-detect.c +++ b/wallet/test/run-chain_moves_duplicate-detect.c @@ -162,10 +162,6 @@ struct invoices *invoices_new(const tal_t *ctx UNNEEDED, struct wallet *wallet UNNEEDED, struct timers *timers UNNEEDED) { fprintf(stderr, "invoices_new called!\n"); abort(); } -/* Generated stub for memleak_scan_outpointfilter */ -void memleak_scan_outpointfilter(struct htable *memtable UNNEEDED, - const struct outpointfilter *opf UNNEEDED) -{ fprintf(stderr, "memleak_scan_outpointfilter called!\n"); abort(); } /* Generated stub for new_channel */ struct channel *new_channel(struct peer *peer UNNEEDED, u64 dbid UNNEEDED, /* NULL or stolen */ diff --git a/wallet/test/run-db.c b/wallet/test/run-db.c index 106cd38026ae..86d6501463a3 100644 --- a/wallet/test/run-db.c +++ b/wallet/test/run-db.c @@ -170,10 +170,6 @@ struct invoices *invoices_new(const tal_t *ctx UNNEEDED, void logv(struct logger *logger UNNEEDED, enum log_level level UNNEEDED, const struct node_id *node_id UNNEEDED, bool call_notifier UNNEEDED, const char *fmt UNNEEDED, va_list ap UNNEEDED) { fprintf(stderr, "logv called!\n"); abort(); } -/* Generated stub for memleak_scan_outpointfilter */ -void memleak_scan_outpointfilter(struct htable *memtable UNNEEDED, - const struct outpointfilter *opf UNNEEDED) -{ fprintf(stderr, "memleak_scan_outpointfilter called!\n"); abort(); } /* Generated stub for mk_mvt_tags_ */ struct mvt_tags mk_mvt_tags_(enum mvt_tag tag UNNEEDED, ...) { fprintf(stderr, "mk_mvt_tags_ called!\n"); abort(); } diff --git a/wallet/test/run-migrate_remove_chain_moves_duplicates.c b/wallet/test/run-migrate_remove_chain_moves_duplicates.c index f9ed9699df27..67b7a20f7731 100644 --- a/wallet/test/run-migrate_remove_chain_moves_duplicates.c +++ b/wallet/test/run-migrate_remove_chain_moves_duplicates.c @@ -174,10 +174,6 @@ struct invoices *invoices_new(const tal_t *ctx UNNEEDED, void logv(struct logger *logger UNNEEDED, enum log_level level UNNEEDED, const struct node_id *node_id UNNEEDED, bool call_notifier UNNEEDED, const char *fmt UNNEEDED, va_list ap UNNEEDED) { fprintf(stderr, "logv called!\n"); abort(); } -/* Generated stub for memleak_scan_outpointfilter */ -void memleak_scan_outpointfilter(struct htable *memtable UNNEEDED, - const struct outpointfilter *opf UNNEEDED) -{ fprintf(stderr, "memleak_scan_outpointfilter called!\n"); abort(); } /* Generated stub for migrate_from_account_db */ void migrate_from_account_db(struct lightningd *ld UNNEEDED, struct db *db UNNEEDED) { fprintf(stderr, "migrate_from_account_db called!\n"); abort(); } diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 5a6ad596c3b7..ea0eb1d8f968 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -264,6 +264,16 @@ void fatal(const char *fmt UNNEEDED, ...) /* Generated stub for fatal_vfmt */ void fatal_vfmt(const char *fmt UNNEEDED, va_list ap UNNEEDED) { fprintf(stderr, "fatal_vfmt called!\n"); abort(); } +/* Generated stub for find_txwatch_ */ +struct txwatch *find_txwatch_(struct chain_topology *topo UNNEEDED, + const struct bitcoin_txid *txid UNNEEDED, + enum watch_result (*cb)(struct lightningd *ld UNNEEDED, + const struct bitcoin_txid * UNNEEDED, + const struct bitcoin_tx * UNNEEDED, + unsigned int depth UNNEEDED, + void *arg) UNNEEDED, + void *arg UNNEEDED) +{ fprintf(stderr, "find_txwatch_ called!\n"); abort(); } /* Generated stub for force_peer_disconnect */ void force_peer_disconnect(struct lightningd *ld UNNEEDED, const struct peer *peer UNNEEDED, @@ -654,10 +664,6 @@ void lockin_complete(struct channel *channel UNNEEDED, void logv(struct logger *logger UNNEEDED, enum log_level level UNNEEDED, const struct node_id *node_id UNNEEDED, bool call_notifier UNNEEDED, const char *fmt UNNEEDED, va_list ap UNNEEDED) { fprintf(stderr, "logv called!\n"); abort(); } -/* Generated stub for memleak_scan_outpointfilter */ -void memleak_scan_outpointfilter(struct htable *memtable UNNEEDED, - const struct outpointfilter *opf UNNEEDED) -{ fprintf(stderr, "memleak_scan_outpointfilter called!\n"); abort(); } /* Generated stub for mk_mvt_tags_ */ struct mvt_tags mk_mvt_tags_(enum mvt_tag tag UNNEEDED, ...) { fprintf(stderr, "mk_mvt_tags_ called!\n"); abort(); } diff --git a/wallet/txfilter.c b/wallet/txfilter.c index 10ef774e41b0..0ce6f46a7a2c 100644 --- a/wallet/txfilter.c +++ b/wallet/txfilter.c @@ -128,12 +128,6 @@ void outpointfilter_remove(struct outpointfilter *of, struct outpointfilter *outpointfilter_new(tal_t *ctx) { struct outpointfilter *opf = tal(ctx, struct outpointfilter); - opf->set = tal(opf, struct outpointset); - outpointset_init(opf->set); + opf->set = new_htable(opf, outpointset); return opf; } - -void memleak_scan_outpointfilter(struct htable *memtable, const struct outpointfilter *opf) -{ - memleak_scan_htable(memtable, &opf->set->raw); -} diff --git a/wallet/txfilter.h b/wallet/txfilter.h index c9152bffd390..2e72b68e1b93 100644 --- a/wallet/txfilter.h +++ b/wallet/txfilter.h @@ -64,9 +64,6 @@ bool outpointfilter_matches(struct outpointfilter *of, void outpointfilter_remove(struct outpointfilter *of, const struct bitcoin_outpoint *outpoint); -void memleak_scan_outpointfilter(struct htable *memtable, - const struct outpointfilter *opf); - /* Useful for other callers */ size_t scriptpubkey_hash(const u8 *out); diff --git a/wallet/wallet.c b/wallet/wallet.c index 599e2f920ade..1f7d980ac895 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -181,8 +181,7 @@ static void our_addresses_add_for_index(struct wallet *w, u32 i) static void our_addresses_init(struct wallet *w) { w->our_addresses_maxindex = 0; - w->our_addresses = tal(w, struct wallet_address_htable); - wallet_address_htable_init(w->our_addresses); + w->our_addresses = new_htable(w, wallet_address_htable); our_addresses_add_for_index(w, w->our_addresses_maxindex); } @@ -5189,9 +5188,16 @@ struct bitcoin_txid *wallet_transactions_by_height(const tal_t *ctx, struct db_stmt *stmt; struct bitcoin_txid *txids = tal_arr(ctx, struct bitcoin_txid, 0); int count = 0; - stmt = db_prepare_v2( - w->db, SQL("SELECT id FROM transactions WHERE blockheight=?")); - db_bind_int(stmt, blockheight); + + /* Note: blockheight=NULL is not the same as is NULL! */ + if (blockheight == 0) { + stmt = db_prepare_v2( + w->db, SQL("SELECT id FROM transactions WHERE blockheight IS NULL")); + } else { + stmt = db_prepare_v2( + w->db, SQL("SELECT id FROM transactions WHERE blockheight=?")); + db_bind_int(stmt, blockheight); + } db_query_prepared(stmt); while (db_step(stmt)) { @@ -6911,13 +6917,6 @@ struct local_anchor_info *wallet_get_local_anchors(const tal_t *ctx, return anchors; } -void wallet_memleak_scan(struct htable *memtable, const struct wallet *w) -{ - memleak_scan_outpointfilter(memtable, w->utxoset_outpoints); - memleak_scan_outpointfilter(memtable, w->owned_outpoints); - memleak_scan_htable(memtable, &w->our_addresses->raw); -} - struct issued_address_type *wallet_list_addresses(const tal_t *ctx, struct wallet *wallet, u64 liststart, const u32 *listlimit) { diff --git a/wallet/wallet.h b/wallet/wallet.h index f956196b37cd..ccadb121e180 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -1928,8 +1928,4 @@ void wallet_datastore_save_payment_description(struct db *db, void migrate_setup_coinmoves(struct lightningd *ld, struct db *db); void migrate_remove_chain_moves_duplicates(struct lightningd *ld, struct db *db); -/** - * wallet_memleak_scan - Check for memleaks in wallet. - */ -void wallet_memleak_scan(struct htable *memtable, const struct wallet *w); #endif /* LIGHTNING_WALLET_WALLET_H */ diff --git a/wallet/walletrpc.c b/wallet/walletrpc.c index 677db8bab66f..ab011b553b4c 100644 --- a/wallet/walletrpc.c +++ b/wallet/walletrpc.c @@ -953,7 +953,6 @@ static void maybe_notify_new_external_send(struct lightningd *ld, wallet_save_chain_mvt(ld, take(mvt)); } - static void sendpsbt_done(struct bitcoind *bitcoind UNUSED, bool success, const char *msg, struct sending_psbt *sending) @@ -985,10 +984,14 @@ static void sendpsbt_done(struct bitcoind *bitcoind UNUSED, } wallet_transaction_add(ld->wallet, sending->wtx, 0, 0); + wally_txid(sending->wtx, &txid); /* Extract the change output and add it to the DB */ - wallet_extract_owned_outputs(ld->wallet, sending->wtx, false, NULL); - wally_txid(sending->wtx, &txid); + if (wallet_extract_owned_outputs(ld->wallet, sending->wtx, false, NULL) == 0) { + /* If we're not watching it for selfish reasons (i.e. pure send to + * others), make sure we're watching it so we can update depth in db */ + watch_unconfirmed_txid(ld, ld->topology, &txid); + } for (size_t i = 0; i < sending->psbt->num_outputs; i++) maybe_notify_new_external_send(ld, &txid, i, sending->psbt);