From ee1a483e8d47eccf5f788b11e67df2510ad21f63 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Oct 2021 10:57:11 +1030 Subject: [PATCH 01/16] offers: fix overzealous BROKEN log. sendonionmessage can fail when sending a reply, either because the reply had a bad first peer, or because it went offline. The latter happens in CI, which is how I found this. Also fixed typo "onio" -> "onion". Signed-off-by: Rusty Russell --- plugins/offers.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/offers.c b/plugins/offers.c index b89a12cc4998..94c1016504ff 100644 --- a/plugins/offers.c +++ b/plugins/offers.c @@ -31,8 +31,10 @@ static struct command_result *sendonionmessage_error(struct command *cmd, const jsmntok_t *err, void *unused) { - plugin_log(cmd->plugin, LOG_BROKEN, - "sendoniomessage gave JSON error: %.*s", + /* This can happen if the peer goes offline or wasn't directly + * connected: "Unknown first peer" */ + plugin_log(cmd->plugin, LOG_DBG, + "sendonionmessage gave JSON error: %.*s", json_tok_full_len(err), json_tok_full(buf, err)); return command_hook_success(cmd); From edd9f6cfa140ded66ab17acf3443b569994c6810 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Oct 2021 14:12:42 +1030 Subject: [PATCH 02/16] fuzz: make it build again. How did this pass CI? I saw this break in my PR, but it's (long) broken in master. Signed-off-by: Rusty Russell --- tests/fuzz/Makefile | 7 ++++++- tests/fuzz/fuzz-bech32.c | 2 ++ tests/fuzz/fuzz-initial_channel.c | 17 ++++++++++++++--- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/tests/fuzz/Makefile b/tests/fuzz/Makefile index 602ee5e0f43e..6a6c35fa7798 100644 --- a/tests/fuzz/Makefile +++ b/tests/fuzz/Makefile @@ -10,18 +10,22 @@ FUZZ_TARGETS_BIN := $(FUZZ_TARGETS_SRC:.c=) FUZZ_COMMON_OBJS := \ common/amount.o \ common/addr.o \ + common/autodata.o \ common/base32.o \ common/base64.o \ common/bech32.o \ common/bip32.o \ common/bigsize.o \ + common/blockheight_states.o \ common/channel_config.o \ common/close_tx.o \ common/channel_id.o \ + common/channel_type.o \ common/daemon.o \ common/daemon_conn.o \ common/derive_basepoints.o \ common/descriptor_checksum.o \ + common/features.o \ common/fee_states.o \ common/hsm_encryption.o \ common/htlc_state.o \ @@ -46,7 +50,8 @@ FUZZ_COMMON_OBJS := \ wire/fromwire.o \ wire/onion_wiregen.o \ wire/peer_wire.o \ - wire/peer_wiregen.o \ + wire/peer$(EXP)_wiregen.o \ + wire/channel_type_wiregen.o \ wire/tlvstream.o \ wire/towire.o \ wire/wire_io.o \ diff --git a/tests/fuzz/fuzz-bech32.c b/tests/fuzz/fuzz-bech32.c index b3ab46f44c20..9acac0605ab3 100644 --- a/tests/fuzz/fuzz-bech32.c +++ b/tests/fuzz/fuzz-bech32.c @@ -1,3 +1,5 @@ +#include "config.h" +#include #include #include #include diff --git a/tests/fuzz/fuzz-initial_channel.c b/tests/fuzz/fuzz-initial_channel.c index 06e1e89bdc20..df2b34177084 100644 --- a/tests/fuzz/fuzz-initial_channel.c +++ b/tests/fuzz/fuzz-initial_channel.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include #include @@ -38,7 +40,8 @@ void run(const uint8_t *data, size_t size) struct channel_config local, remote; struct basepoints local_basepoints, remote_basepoints; struct pubkey local_funding_pubkey, remote_funding_pubkey; - bool option_static_remotekey, option_anchor_outputs; + bool option_static_remotekey, option_anchor_outputs, wumbo; + struct channel_type *channel_type; struct channel *channel; fromwire_channel_id(&data, &size, &cid); @@ -59,9 +62,17 @@ void run(const uint8_t *data, size_t size) fromwire_basepoints(&data, &size, &remote_basepoints); fromwire_pubkey(&data, &size, &local_funding_pubkey); fromwire_pubkey(&data, &size, &remote_funding_pubkey); + wumbo = fromwire_bool(&data, &size); option_anchor_outputs = fromwire_bool(&data, &size); option_static_remotekey = option_anchor_outputs || fromwire_bool(&data, &size); + if (option_anchor_outputs) + channel_type = channel_type_anchor_outputs(tmpctx); + else if (option_static_remotekey) + channel_type = channel_type_static_remotekey(tmpctx); + else + channel_type = channel_type_none(tmpctx); + /* TODO: determine if it makes sense to check at each step for libfuzzer * to deduce pertinent inputs */ if (!data || !size) @@ -81,8 +92,8 @@ void run(const uint8_t *data, size_t size) &remote_basepoints, &local_funding_pubkey, &remote_funding_pubkey, - option_static_remotekey, - option_anchor_outputs, opener); + channel_type, + wumbo, opener); /* TODO: make initial_channel_tx() work with ASAN.. */ } From 35bf024e9230908aa813ce9df345a3d3caf8e4a3 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Oct 2021 14:12:42 +1030 Subject: [PATCH 03/16] utils: add max_unsigned/min_unsigned helpers. We are usually dealing with unsigned values, so use this. Signed-off-by: Rusty Russell --- bitcoin/script.c | 4 +--- common/utils.h | 24 ++++++++++++++++++++++++ onchaind/onchaind.c | 3 +-- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/bitcoin/script.c b/bitcoin/script.c index fdd05be54a12..6a3e6f8c4ab3 100644 --- a/bitcoin/script.c +++ b/bitcoin/script.c @@ -12,8 +12,6 @@ /* To push 0-75 bytes onto stack. */ #define OP_PUSHBYTES(val) (val) -#define max(a, b) ((a) > (b) ? (a) : (b)) - /* Bitcoin's OP_HASH160 is RIPEMD(SHA256()) */ static void hash160(struct ripemd160 *redeemhash, const void *mem, size_t len) { @@ -556,7 +554,7 @@ u8 *bitcoin_wscript_to_local(const tal_t *ctx, u16 to_self_delay, add_op(&script, OP_IF); add_push_key(&script, revocation_pubkey); add_op(&script, OP_ELSE); - add_number(&script, max(lease_remaining, to_self_delay)); + add_number(&script, max_unsigned(lease_remaining, to_self_delay)); add_op(&script, OP_CHECKSEQUENCEVERIFY); add_op(&script, OP_DROP); add_push_key(&script, local_delayedkey); diff --git a/common/utils.h b/common/utils.h index 0b396bb870b2..0282f5a53018 100644 --- a/common/utils.h +++ b/common/utils.h @@ -1,6 +1,7 @@ #ifndef LIGHTNING_COMMON_UTILS_H #define LIGHTNING_COMMON_UTILS_H #include "config.h" +#include #include #include #include @@ -12,6 +13,29 @@ extern secp256k1_context *secp256k1_ctx; extern const struct chainparams *chainparams; +/* Unsigned min/max macros: BUILD_ASSERT make sure types are unsigned */ +#if HAVE_TYPEOF +#define MUST_BE_UNSIGNED_INT(x) BUILD_ASSERT_OR_ZERO((typeof(x))(-1)>=0) +#else +#define MUST_BE_UNSIGNED_INT(x) 0 +#endif + +#define min_unsigned(a, b) \ + (MUST_BE_UNSIGNED_INT(a) + MUST_BE_UNSIGNED_INT(b) + min_u64((a), (b))) + +#define max_unsigned(a, b) \ + (MUST_BE_UNSIGNED_INT(a) + MUST_BE_UNSIGNED_INT(b) + max_u64((a), (b))) + +static inline u64 min_u64(u64 a, u64 b) +{ + return a < b ? a : b; +} + +static inline u64 max_u64(u64 a, u64 b) +{ + return a < b ? b : a; +} + /* Marker which indicates an (tal) pointer argument is stolen * (i.e. eventually freed) by the function. Unlike TAKEN, which * indicates it's only stolen if caller says take() */ diff --git a/onchaind/onchaind.c b/onchaind/onchaind.c index 425a5da74ebe..39836e1c426d 100644 --- a/onchaind/onchaind.c +++ b/onchaind/onchaind.c @@ -23,7 +23,6 @@ /* stdin == requests */ #define REQ_FD STDIN_FILENO #define HSM_FD 3 -#define max(a, b) ((a) > (b) ? (a) : (b)) /* Required in various places: keys for commitment transaction. */ static const struct keyset *keyset; @@ -2837,7 +2836,7 @@ static void handle_our_unilateral(const struct tx_parts *tx, our_unilateral_to_us(&outs, tx, tx_blockheight, i, amt, - max(to_self_delay[LOCAL], csv), + max_unsigned(to_self_delay[LOCAL], csv), script[LOCAL], local_wscript, is_replay); From e82a4ce7a51bfed9472900a2e77b7ca0a3a52e00 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Oct 2021 14:12:43 +1030 Subject: [PATCH 04/16] wallet: wrap htlc_state enum in db function. All enums in the db should be wrapped this way on reading/writing them. Signed-off-by: Rusty Russell --- wallet/wallet.c | 11 ++++---- wallet/wallet.h | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 6 deletions(-) diff --git a/wallet/wallet.c b/wallet/wallet.c index 0fc3f2878c1e..227740077b3a 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -968,7 +968,7 @@ static struct fee_states *wallet_channel_fee_states_load(struct wallet *w, /* Start with blank slate. */ fee_states = new_fee_states(w, opener, NULL); while (db_step(stmt)) { - enum htlc_state hstate = db_column_int(stmt, 0); + enum htlc_state hstate = htlc_state_in_db(db_column_int(stmt, 0)); u32 feerate = db_column_int(stmt, 1); if (fee_states->feerate[hstate] != NULL) { @@ -1004,7 +1004,7 @@ static struct height_states *wallet_channel_height_states_load(struct wallet *w, /* Start with blank slate. */ states = new_height_states(w, opener, NULL); while (db_step(stmt)) { - enum htlc_state hstate = db_column_int(stmt, 0); + enum htlc_state hstate = htlc_state_in_db(db_column_int(stmt, 0)); u32 blockheight = db_column_int(stmt, 1); if (states->height[hstate] != NULL) { @@ -1936,7 +1936,7 @@ void wallet_channel_save(struct wallet *w, struct channel *chan) stmt = db_prepare_v2(w->db, SQL("INSERT INTO channel_feerates " " VALUES(?, ?, ?)")); db_bind_u64(stmt, 0, chan->dbid); - db_bind_int(stmt, 1, i); + db_bind_int(stmt, 1, htlc_state_in_db(i)); db_bind_int(stmt, 2, *chan->fee_states->feerate[i]); db_exec_prepared_v2(take(stmt)); } @@ -1955,7 +1955,7 @@ void wallet_channel_save(struct wallet *w, struct channel *chan) stmt = db_prepare_v2(w->db, SQL("INSERT INTO channel_blockheights " " VALUES(?, ?, ?)")); db_bind_u64(stmt, 0, chan->dbid); - db_bind_int(stmt, 1, i); + db_bind_int(stmt, 1, htlc_state_in_db(i)); db_bind_int(stmt, 2, *chan->blockheight_states->height[i]); db_exec_prepared_v2(take(stmt)); } @@ -2429,8 +2429,7 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, "we_filled=?" " WHERE id=?")); - /* FIXME: htlc_state_in_db */ - db_bind_int(stmt, 0, new_state); + db_bind_int(stmt, 0, htlc_state_in_db(new_state)); db_bind_u64(stmt, 6, htlc_dbid); if (payment_key) diff --git a/wallet/wallet.h b/wallet/wallet.h index 95e4814aa417..7cf7eaaf1079 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -159,6 +159,77 @@ static inline const char* forward_status_name(enum forward_status status) bool string_to_forward_status(const char *status_str, enum forward_status *status); +/* DB wrapper to check htlc_state */ +static inline enum htlc_state htlc_state_in_db(enum htlc_state s) +{ + switch (s) { + case SENT_ADD_HTLC: + BUILD_ASSERT(SENT_ADD_HTLC == 0); + return s; + case SENT_ADD_COMMIT: + BUILD_ASSERT(SENT_ADD_COMMIT == 1); + return s; + case RCVD_ADD_REVOCATION: + BUILD_ASSERT(RCVD_ADD_REVOCATION == 2); + return s; + case RCVD_ADD_ACK_COMMIT: + BUILD_ASSERT(RCVD_ADD_ACK_COMMIT == 3); + return s; + case SENT_ADD_ACK_REVOCATION: + BUILD_ASSERT(SENT_ADD_ACK_REVOCATION == 4); + return s; + case RCVD_REMOVE_HTLC: + BUILD_ASSERT(RCVD_REMOVE_HTLC == 5); + return s; + case RCVD_REMOVE_COMMIT: + BUILD_ASSERT(RCVD_REMOVE_COMMIT == 6); + return s; + case SENT_REMOVE_REVOCATION: + BUILD_ASSERT(SENT_REMOVE_REVOCATION == 7); + return s; + case SENT_REMOVE_ACK_COMMIT: + BUILD_ASSERT(SENT_REMOVE_ACK_COMMIT == 8); + return s; + case RCVD_REMOVE_ACK_REVOCATION: + BUILD_ASSERT(RCVD_REMOVE_ACK_REVOCATION == 9); + return s; + case RCVD_ADD_HTLC: + BUILD_ASSERT(RCVD_ADD_HTLC == 10); + return s; + case RCVD_ADD_COMMIT: + BUILD_ASSERT(RCVD_ADD_COMMIT == 11); + return s; + case SENT_ADD_REVOCATION: + BUILD_ASSERT(SENT_ADD_REVOCATION == 12); + return s; + case SENT_ADD_ACK_COMMIT: + BUILD_ASSERT(SENT_ADD_ACK_COMMIT == 13); + return s; + case RCVD_ADD_ACK_REVOCATION: + BUILD_ASSERT(RCVD_ADD_ACK_REVOCATION == 14); + return s; + case SENT_REMOVE_HTLC: + BUILD_ASSERT(SENT_REMOVE_HTLC == 15); + return s; + case SENT_REMOVE_COMMIT: + BUILD_ASSERT(SENT_REMOVE_COMMIT == 16); + return s; + case RCVD_REMOVE_REVOCATION: + BUILD_ASSERT(RCVD_REMOVE_REVOCATION == 17); + return s; + case RCVD_REMOVE_ACK_COMMIT: + BUILD_ASSERT(RCVD_REMOVE_ACK_COMMIT == 18); + return s; + case SENT_REMOVE_ACK_REVOCATION: + BUILD_ASSERT(SENT_REMOVE_ACK_REVOCATION == 19); + return s; + case HTLC_STATE_INVALID: + /* Not in db! */ + break; + } + fatal("%s: %u is invalid", __func__, s); +} + struct forwarding { struct short_channel_id channel_in, channel_out; struct amount_msat msat_in, msat_out, fee; From 7e225af4452b3b18480ce0c5f96ae66646f47014 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Oct 2021 14:13:13 +1030 Subject: [PATCH 05/16] db: add min/max commitnum fields to channel_htlcs. And initialize max to current height max when htlcs are already dead. Turns out (thanks CI!) that MAX() of multiple columns is GREATEST() in Postgres. That's clearer (MAX is used elsewhere for single columns), so translate on the sqlite3 side. Signed-off-by: Rusty Russell --- devtools/sql-rewrite.py | 2 ++ wallet/db.c | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/devtools/sql-rewrite.py b/devtools/sql-rewrite.py index f49a23871047..53a8619925b4 100755 --- a/devtools/sql-rewrite.py +++ b/devtools/sql-rewrite.py @@ -43,6 +43,8 @@ def rewrite_single(self, query): r'INSERT INTO[ \t]+(.*)[ \t]+ON CONFLICT.*DO NOTHING;': 'INSERT OR IGNORE INTO \\1;', # Rewrite "decode('abcd', 'hex')" to become "x'abcd'" r'decode\((.*),\s*[\'\"]hex[\'\"]\)': 'x\\1', + # GREATEST() of multiple columns is simple MAX in sqlite3. + r'GREATEST\(([^)]*)\)': "MAX(\\1)", } return self.rewrite_types(query, typemapping) diff --git a/wallet/db.c b/wallet/db.c index e08c62d8afeb..54f78bbdde83 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -835,6 +835,15 @@ static struct migration dbmigrations[] = { /* HTLCs also need to carry the groupid around so we can * selectively update them. */ {SQL("ALTER TABLE channel_htlcs ADD groupid BIGINT;"), NULL}, + {SQL("ALTER TABLE channel_htlcs ADD COLUMN" + " min_commit_num BIGINT default 0;"), NULL}, + {SQL("ALTER TABLE channel_htlcs ADD COLUMN" + " max_commit_num BIGINT default NULL;"), NULL}, + /* Set max_commit_num for dead (RCVD_REMOVE_ACK_REVOCATION or SENT_REMOVE_ACK_REVOCATION) HTLCs based on latest indexes */ + {SQL("UPDATE channel_htlcs SET max_commit_num =" + " (SELECT GREATEST(next_index_local, next_index_remote)" + " FROM channels WHERE id=channel_id)" + " WHERE (hstate=9 OR hstate=19);"), NULL}, }; /* Leak tracking. */ From a7d2ee20e26b0a8fd6f3d1e043e3760e25ca71bf Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Oct 2021 14:15:30 +1030 Subject: [PATCH 06/16] lightningd: populate min/max commit fields in db. Signed-off-by: Rusty Russell --- lightningd/peer_htlcs.c | 19 ++++++++++++++++--- wallet/test/run-wallet.c | 11 ++++++----- wallet/wallet.c | 26 ++++++++++++++++++++------ wallet/wallet.h | 2 ++ 4 files changed, 44 insertions(+), 14 deletions(-) diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index 1f9891efdd0c..e937b8105e6c 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -63,6 +63,8 @@ static bool htlc_in_update_state(struct channel *channel, wallet_htlc_update(channel->peer->ld->wallet, hin->dbid, newstate, hin->preimage, + max_unsigned(channel->next_index[LOCAL], + channel->next_index[REMOTE]), hin->badonion, hin->failonion, NULL, hin->we_filled); @@ -80,7 +82,10 @@ static bool htlc_out_update_state(struct channel *channel, bool we_filled = false; wallet_htlc_update(channel->peer->ld->wallet, hout->dbid, newstate, - hout->preimage, 0, hout->failonion, + hout->preimage, + max_unsigned(channel->next_index[LOCAL], + channel->next_index[REMOTE]), + 0, hout->failonion, hout->failmsg, &we_filled); hout->hstate = newstate; @@ -174,6 +179,8 @@ static void failmsg_update_reply(struct subd *gossipd, wallet_htlc_update(gossipd->ld->wallet, cbdata->hin->dbid, cbdata->hin->hstate, cbdata->hin->preimage, + max_unsigned(cbdata->hin->key.channel->next_index[LOCAL], + cbdata->hin->key.channel->next_index[REMOTE]), cbdata->hin->badonion, cbdata->hin->failonion, NULL, &we_filled); @@ -1282,7 +1289,10 @@ static void fulfill_our_htlc_out(struct channel *channel, struct htlc_out *hout, htlc_out_check(hout, __func__); wallet_htlc_update(ld->wallet, hout->dbid, hout->hstate, - hout->preimage, 0, hout->failonion, + hout->preimage, + max_unsigned(channel->next_index[LOCAL], + channel->next_index[REMOTE]), + 0, hout->failonion, hout->failmsg, &we_filled); /* Update channel stats */ wallet_channel_stats_incr_out_fulfilled(ld->wallet, @@ -1453,7 +1463,10 @@ void onchain_failed_our_htlc(const struct channel *channel, bool we_filled = false; wallet_htlc_update(ld->wallet, hout->dbid, hout->hstate, - hout->preimage, 0, hout->failonion, + hout->preimage, + max_unsigned(channel->next_index[LOCAL], + channel->next_index[REMOTE]), + 0, hout->failonion, hout->failmsg, &we_filled); if (hout->am_origin) { diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 33e788b01a6b..c4e603fadd14 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -1717,6 +1717,7 @@ static bool test_htlc_crud(struct lightningd *ld, const tal_t *ctx) chan->dbid = 1; chan->peer = peer; + chan->next_index[LOCAL] = chan->next_index[REMOTE] = 1; memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); @@ -1743,17 +1744,17 @@ static bool test_htlc_crud(struct lightningd *ld, const tal_t *ctx) wallet_err = tal_free(wallet_err); /* Update */ - CHECK_MSG(transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, RCVD_ADD_HTLC, NULL, 0, NULL, NULL, false)), + CHECK_MSG(transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, RCVD_ADD_HTLC, NULL, 0, 0, NULL, NULL, false)), "Update HTLC with null payment_key failed"); CHECK_MSG( - transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, &payment_key, 0, NULL, NULL, false)), + transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, &payment_key, 0, 0, NULL, NULL, false)), "Update HTLC with payment_key failed"); onionreply = new_onionreply(tmpctx, tal_arrz(tmpctx, u8, 100)); CHECK_MSG( - transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, 0, onionreply, NULL, false)), + transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, 0, 0, onionreply, NULL, false)), "Update HTLC with failonion failed"); CHECK_MSG( - transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, WIRE_INVALID_ONION_VERSION, NULL, NULL, false)), + transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, 0, WIRE_INVALID_ONION_VERSION, NULL, NULL, false)), "Update HTLC with failcode failed"); CHECK_MSG(transaction_wrap(w->db, wallet_htlc_save_out(w, chan, &out)), @@ -1765,7 +1766,7 @@ static bool test_htlc_crud(struct lightningd *ld, const tal_t *ctx) CHECK(wallet_err); wallet_err = tal_free(wallet_err); CHECK_MSG( - transaction_wrap(w->db, wallet_htlc_update(w, out.dbid, SENT_ADD_ACK_REVOCATION, NULL, 0, NULL, tal_arrz(tmpctx, u8, 100), false)), + transaction_wrap(w->db, wallet_htlc_update(w, out.dbid, SENT_ADD_ACK_REVOCATION, NULL, 0, 0, NULL, tal_arrz(tmpctx, u8, 100), false)), "Update outgoing HTLC with failmsg failed"); /* Attempt to load them from the DB again */ diff --git a/wallet/wallet.c b/wallet/wallet.c index 227740077b3a..e7530d1f6126 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -2314,8 +2314,9 @@ void wallet_htlc_save_in(struct wallet *wallet, " hstate," " shared_secret," " routing_onion," - " received_time) VALUES " - "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")); + " received_time," + " min_commit_num) VALUES " + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")); db_bind_u64(stmt, 0, chan->dbid); db_bind_u64(stmt, 1, in->key.id); @@ -2339,6 +2340,8 @@ void wallet_htlc_save_in(struct wallet *wallet, sizeof(in->onion_routing_packet)); db_bind_timeabs(stmt, 10, in->received_time); + db_bind_u64(stmt, 11, min_unsigned(chan->next_index[LOCAL]-1, + chan->next_index[REMOTE]-1)); db_exec_prepared_v2(stmt); in->dbid = db_last_insert_id_v2(take(stmt)); @@ -2369,8 +2372,9 @@ void wallet_htlc_save_out(struct wallet *wallet, " routing_onion," " malformed_onion," " partid," - " groupid" - ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?, ?);")); + " groupid," + " min_commit_num" + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?, ?, ?);")); db_bind_u64(stmt, 0, chan->dbid); db_bind_u64(stmt, 1, out->key.id); @@ -2400,6 +2404,8 @@ void wallet_htlc_save_out(struct wallet *wallet, db_bind_u64(stmt, 10, out->partid); db_bind_u64(stmt, 11, out->groupid); } + db_bind_u64(stmt, 12, min_u64(chan->next_index[LOCAL]-1, + chan->next_index[REMOTE]-1)); db_exec_prepared_v2(stmt); out->dbid = db_last_insert_id_v2(stmt); @@ -2410,6 +2416,7 @@ void wallet_htlc_save_out(struct wallet *wallet, void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, const enum htlc_state new_state, const struct preimage *payment_key, + u64 max_commit_num, enum onion_wire badonion, const struct onionreply *failonion, const u8 *failmsg, @@ -2426,11 +2433,11 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, stmt = db_prepare_v2( wallet->db, SQL("UPDATE channel_htlcs SET hstate=?, payment_key=?, " "malformed_onion=?, failuremsg=?, localfailmsg=?, " - "we_filled=?" + "we_filled=?, max_commit_num=?" " WHERE id=?")); db_bind_int(stmt, 0, htlc_state_in_db(new_state)); - db_bind_u64(stmt, 6, htlc_dbid); + db_bind_u64(stmt, 7, htlc_dbid); if (payment_key) db_bind_preimage(stmt, 1, payment_key); @@ -2451,6 +2458,13 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, else db_bind_null(stmt, 5); + /* Set max_commit_num iff we're in final state. */ + if (new_state == RCVD_REMOVE_ACK_REVOCATION + || new_state == SENT_REMOVE_ACK_REVOCATION) + db_bind_u64(stmt, 6, max_commit_num); + else + db_bind_null(stmt, 6); + db_exec_prepared_v2(take(stmt)); } diff --git a/wallet/wallet.h b/wallet/wallet.h index 7cf7eaaf1079..9215e2824c58 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -713,6 +713,7 @@ void wallet_htlc_save_out(struct wallet *wallet, * @new_state: the state we should transition to * @payment_key: the `payment_key` which hashes to the `payment_hash`, * or NULL if unknown. + * @max_commit_num: maximum of local and remote commitment numbers. * @badonion: the current BADONION failure code, or 0. * @failonion: the current failure onion message (from peer), or NULL. * @failmsg: the current local failure message, or NULL. @@ -725,6 +726,7 @@ void wallet_htlc_save_out(struct wallet *wallet, void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, const enum htlc_state new_state, const struct preimage *payment_key, + u64 max_commit_num, enum onion_wire badonion, const struct onionreply *failonion, const u8 *failmsg, From bea5039e88315a559e3dbe7c37402cba5ac48551 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Oct 2021 14:15:35 +1030 Subject: [PATCH 07/16] wallet: remove unnecessary data from channel_htlcs when htlc is dead. In particular, the onion and errors can be large, but now we'll never need to retransmit them. Signed-off-by: Rusty Russell --- wallet/wallet.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/wallet/wallet.c b/wallet/wallet.c index e7530d1f6126..71794fc0487b 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -2423,6 +2423,8 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, bool *we_filled) { struct db_stmt *stmt; + bool terminal = (new_state == RCVD_REMOVE_ACK_REVOCATION + || new_state == SENT_REMOVE_ACK_REVOCATION); /* We should only use this for badonion codes */ assert(!badonion || (badonion & BADONION)); @@ -2459,13 +2461,22 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, db_bind_null(stmt, 5); /* Set max_commit_num iff we're in final state. */ - if (new_state == RCVD_REMOVE_ACK_REVOCATION - || new_state == SENT_REMOVE_ACK_REVOCATION) + if (terminal) db_bind_u64(stmt, 6, max_commit_num); else db_bind_null(stmt, 6); db_exec_prepared_v2(take(stmt)); + + if (terminal) { + /* If it's terminal, remove the data we needed for re-xmission. */ + stmt = db_prepare_v2( + wallet->db, + SQL("UPDATE channel_htlcs SET payment_key=NULL, routing_onion=NULL, failuremsg=NULL, shared_secret=NULL, localfailmsg=NULL " + " WHERE id=?")); + db_bind_u64(stmt, 0, htlc_dbid); + db_exec_prepared_v2(take(stmt)); + } } static bool wallet_stmt2htlc_in(struct channel *channel, From 1e83be0386f09d3a30fb09f8cc54a1dfcebaa2ba Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Oct 2021 14:15:36 +1030 Subject: [PATCH 08/16] db: clear our unneeded htlc fields in old terminated HTLCs. Signed-off-by: Rusty Russell --- wallet/db.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wallet/db.c b/wallet/db.c index 54f78bbdde83..248bc9debb79 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -844,6 +844,14 @@ static struct migration dbmigrations[] = { " (SELECT GREATEST(next_index_local, next_index_remote)" " FROM channels WHERE id=channel_id)" " WHERE (hstate=9 OR hstate=19);"), NULL}, + /* Remove unused fields which take much room in db. */ + {SQL("UPDATE channel_htlcs SET" + " payment_key=NULL," + " routing_onion=NULL," + " failuremsg=NULL," + " shared_secret=NULL," + " localfailmsg=NULL" + " WHERE (hstate=9 OR hstate=19);"), NULL}, }; /* Leak tracking. */ From 1a273f9dd3f43c970023908018645f57b42efcb2 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Oct 2021 14:15:36 +1030 Subject: [PATCH 09/16] db: vacuum after a db upgrade. This is particularly useful after our recent field deletion: before: 362,573,824 bytes after: 124,190,720 bytes Signed-off-by: Rusty Russell Changelog-Changed: db: removal of old HTLC information and vacuuming shrinks large lightningd.sqlite3 by a factor of 2-3. --- wallet/db.c | 14 ++++++++++++-- wallet/db_common.h | 2 +- wallet/db_postgres.c | 15 +++++++++++++++ wallet/db_sqlite3.c | 16 ++++++++++++++++ 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/wallet/db.c b/wallet/db.c index 248bc9debb79..082793d0d2e2 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -1204,7 +1204,7 @@ static int db_get_version(struct db *db) /** * db_migrate - Apply all remaining migrations from the current version */ -static void db_migrate(struct lightningd *ld, struct db *db, +static bool db_migrate(struct lightningd *ld, struct db *db, const struct ext_key *bip32_base) { /* Attempt to read the version from the database */ @@ -1254,6 +1254,8 @@ static void db_migrate(struct lightningd *ld, struct db *db, db_exec_prepared_v2(stmt); tal_free(stmt); } + + return current != orig; } u32 db_data_version_get(struct db *db) @@ -1272,14 +1274,22 @@ struct db *db_setup(const tal_t *ctx, struct lightningd *ld, const struct ext_key *bip32_base) { struct db *db = db_open(ctx, ld->wallet_dsn); + bool migrated; db->log = new_log(db, ld->log_book, NULL, "database"); db_begin_transaction(db); - db_migrate(ld, db, bip32_base); + migrated = db_migrate(ld, db, bip32_base); db->data_version = db_data_version_get(db); db_commit_transaction(db); + + /* This needs to be done outside a transaction, apparently. + * It's a good idea to do this every so often, and on db + * upgrade is a reasonable time. */ + if (migrated && !db->config->vacuum_fn(db)) + db_fatal("Error vacuuming db: %s", db->error); + return db; } diff --git a/wallet/db_common.h b/wallet/db_common.h index 2b697822cf0e..5db081a6fbb9 100644 --- a/wallet/db_common.h +++ b/wallet/db_common.h @@ -140,7 +140,7 @@ struct db_config { bool (*setup_fn)(struct db *db); void (*teardown_fn)(struct db *db); - u32 (*version)(struct db *db); + bool (*vacuum_fn)(struct db *db); }; /* Provide a way for DB backends to register themselves */ diff --git a/wallet/db_postgres.c b/wallet/db_postgres.c index 55b6ad0b75b5..29920a358420 100644 --- a/wallet/db_postgres.c +++ b/wallet/db_postgres.c @@ -251,6 +251,20 @@ static void db_postgres_teardown(struct db *db) { } +static bool db_postgres_vacuum(struct db *db) +{ + PGresult *res; + res = PQexec(db->conn, "VACUUM FULL;"); + if (PQresultStatus(res) != PGRES_COMMAND_OK) { + db->error = tal_fmt(db, "BEGIN command failed: %s", + PQerrorMessage(db->conn)); + PQclear(res); + return false; + } + PQclear(res); + return true; +} + struct db_config db_postgres_config = { .name = "postgres", .queries = db_postgres_queries, @@ -273,6 +287,7 @@ struct db_config db_postgres_config = { .count_changes_fn = db_postgres_count_changes, .setup_fn = db_postgres_setup, .teardown_fn = db_postgres_teardown, + .vacuum_fn = db_postgres_vacuum, }; AUTODATA(db_backends, &db_postgres_config); diff --git a/wallet/db_sqlite3.c b/wallet/db_sqlite3.c index 754419852e4f..f5e065cf6df5 100644 --- a/wallet/db_sqlite3.c +++ b/wallet/db_sqlite3.c @@ -234,6 +234,20 @@ static u64 db_sqlite3_last_insert_id(struct db_stmt *stmt) return sqlite3_last_insert_rowid(s); } +static bool db_sqlite3_vacuum(struct db *db) +{ + int err; + sqlite3_stmt *stmt; + + sqlite3_prepare_v2(db->conn, "VACUUM;", -1, &stmt, NULL); + err = sqlite3_step(stmt); + if (err != SQLITE_DONE) + db->error = tal_fmt(db, "%s", sqlite3_errmsg(db->conn)); + sqlite3_finalize(stmt); + + return err == SQLITE_DONE; +} + struct db_config db_sqlite3_config = { .name = "sqlite3", .queries = db_sqlite3_queries, @@ -256,6 +270,8 @@ struct db_config db_sqlite3_config = { .count_changes_fn = &db_sqlite3_count_changes, .setup_fn = &db_sqlite3_setup, .teardown_fn = &db_sqlite3_close, + + .vacuum_fn = db_sqlite3_vacuum, }; AUTODATA(db_backends, &db_sqlite3_config); From f6d768d818582c23b13a11edc339328fcfb3b566 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Oct 2021 14:15:36 +1030 Subject: [PATCH 10/16] lightningd: use bitcoin_outpoint in watch. This makes more sense than two args. Signed-off-by: Rusty Russell --- lightningd/chaintopology.c | 4 ++-- lightningd/watch.c | 22 +++++++++++----------- lightningd/watch.h | 12 +++--------- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index 17244bb028a2..09702f179c17 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -72,10 +72,10 @@ static void filter_block_txs(struct chain_topology *topo, struct block *b) /* Tell them if it spends a txo we care about. */ for (j = 0; j < tx->wtx->num_inputs; j++) { - struct txwatch_output out; + struct bitcoin_outpoint out; struct txowatch *txo; bitcoin_tx_input_get_txid(tx, j, &out.txid); - out.index = tx->wtx->inputs[j].index; + out.n = tx->wtx->inputs[j].index; txo = txowatch_hash_get(&topo->txowatches, &out); if (txo) { diff --git a/lightningd/watch.c b/lightningd/watch.c index 34cc8ce4ea4e..123d6e0369e5 100644 --- a/lightningd/watch.c +++ b/lightningd/watch.c @@ -40,7 +40,7 @@ struct txowatch { struct channel *channel; /* Output to watch. */ - struct txwatch_output out; + struct bitcoin_outpoint out; /* A new tx. */ enum watch_result (*cb)(struct channel *channel, @@ -71,24 +71,24 @@ struct txwatch { unsigned int depth); }; -const struct txwatch_output *txowatch_keyof(const struct txowatch *w) +const struct bitcoin_outpoint *txowatch_keyof(const struct txowatch *w) { return &w->out; } -size_t txo_hash(const struct txwatch_output *out) +size_t txo_hash(const struct bitcoin_outpoint *out) { /* This hash-in-one-go trick only works if they're consecutive. */ - BUILD_ASSERT(offsetof(struct txwatch_output, index) - == sizeof(((struct txwatch_output *)NULL)->txid)); - return siphash24(siphash_seed(), &out->txid, - sizeof(out->txid) + sizeof(out->index)); + BUILD_ASSERT(offsetof(struct bitcoin_outpoint, n) + == sizeof(((struct bitcoin_outpoint *)NULL)->txid)); + return siphash24(siphash_seed(), out, + sizeof(out->txid) + sizeof(out->n)); } -bool txowatch_eq(const struct txowatch *w, const struct txwatch_output *out) +bool txowatch_eq(const struct txowatch *w, const struct bitcoin_outpoint *out) { return bitcoin_txid_eq(&w->out.txid, &out->txid) - && w->out.index == out->index; + && w->out.n == out->n; } static void destroy_txowatch(struct txowatch *w) @@ -198,7 +198,7 @@ struct txowatch *watch_txo(const tal_t *ctx, w->topo = topo; w->out.txid = *txid; - w->out.index = output; + w->out.n = output; w->channel = channel; w->cb = cb; @@ -266,7 +266,7 @@ void txowatch_fire(const struct txowatch *txow, log_debug(txow->channel->log, "Got UTXO spend for %s:%u: %s", type_to_string(tmpctx, struct bitcoin_txid, &txow->out.txid), - txow->out.index, + txow->out.n, type_to_string(tmpctx, struct bitcoin_txid, &txid)); r = txow->cb(txow->channel, tx, input_num, block); diff --git a/lightningd/watch.h b/lightningd/watch.h index fc67b43c1d41..348c50fbf6c8 100644 --- a/lightningd/watch.h +++ b/lightningd/watch.h @@ -4,7 +4,6 @@ #include #include -struct bitcoin_tx; struct block; struct channel; struct chain_topology; @@ -17,14 +16,9 @@ enum watch_result { KEEP_WATCHING = -2 }; -struct txwatch_output { - struct bitcoin_txid txid; - unsigned int index; -}; - -const struct txwatch_output *txowatch_keyof(const struct txowatch *w); -size_t txo_hash(const struct txwatch_output *out); -bool txowatch_eq(const struct txowatch *w, const struct txwatch_output *out); +const struct bitcoin_outpoint *txowatch_keyof(const struct txowatch *w); +size_t txo_hash(const struct bitcoin_outpoint *out); +bool txowatch_eq(const struct txowatch *w, const struct bitcoin_outpoint *out); HTABLE_DEFINE_TYPE(struct txowatch, txowatch_keyof, txo_hash, txowatch_eq, txowatch_hash); From bc98128e355d327dbfcb39a883d0dd8a604262fb Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Oct 2021 14:15:36 +1030 Subject: [PATCH 11/16] common/type_to_string: formatting for bitcoin_outpoint. Signed-off-by: Rusty Russell --- bitcoin/tx.c | 10 ++++++++++ common/type_to_string.h | 1 + 2 files changed, 11 insertions(+) diff --git a/bitcoin/tx.c b/bitcoin/tx.c index d676b06dafad..dccec6006fe0 100644 --- a/bitcoin/tx.c +++ b/bitcoin/tx.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -677,6 +678,14 @@ static char *fmt_bitcoin_txid(const tal_t *ctx, const struct bitcoin_txid *txid) return hexstr; } +static char *fmt_bitcoin_outpoint(const tal_t *ctx, + const struct bitcoin_outpoint *outpoint) +{ + return tal_fmt(ctx, "%s:%u", + fmt_bitcoin_txid(tmpctx, &outpoint->txid), + outpoint->n); +} + static char *fmt_wally_tx(const tal_t *ctx, const struct wally_tx *tx) { u8 *lin = linearize_wtx(ctx, tx); @@ -687,6 +696,7 @@ static char *fmt_wally_tx(const tal_t *ctx, const struct wally_tx *tx) REGISTER_TYPE_TO_STRING(bitcoin_tx, fmt_bitcoin_tx); REGISTER_TYPE_TO_STRING(bitcoin_txid, fmt_bitcoin_txid); +REGISTER_TYPE_TO_STRING(bitcoin_outpoint, fmt_bitcoin_outpoint); REGISTER_TYPE_TO_STRING(wally_tx, fmt_wally_tx); void fromwire_bitcoin_txid(const u8 **cursor, size_t *max, diff --git a/common/type_to_string.h b/common/type_to_string.h index 1bdc66542ac8..c58e712da779 100644 --- a/common/type_to_string.h +++ b/common/type_to_string.h @@ -11,6 +11,7 @@ union printable_types { const struct node_id *node_id; const struct bitcoin_txid *bitcoin_txid; const struct bitcoin_blkid *bitcoin_blkid; + const struct bitcoin_outpoint *bitcoin_outpoint; const struct sha256 *sha256; const struct sha256_double *sha256_double; const struct ripemd160 *ripemd160; From 02ab136a4c343cde655bb27bfca58c6ce3dd24f0 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Oct 2021 14:15:36 +1030 Subject: [PATCH 12/16] common: use bitcoin_outpoint. I started pulling this thread, and the entire codebase got unravelled. Oh well, it's done now! Signed-off-by: Rusty Russell --- bitcoin/psbt.c | 25 +- bitcoin/psbt.h | 11 +- bitcoin/tx.c | 44 ++- bitcoin/tx.h | 23 +- channeld/channeld.c | 19 +- channeld/channeld_wire.csv | 3 +- channeld/commit_tx.c | 13 +- channeld/commit_tx.h | 7 +- channeld/full_channel.c | 27 +- channeld/full_channel.h | 10 +- channeld/test/run-commit_tx.c | 38 +-- channeld/test/run-full_channel.c | 17 +- channeld/watchtower.c | 6 +- closingd/closingd.c | 95 +++--- closingd/closingd_wire.csv | 3 +- common/channel_id.c | 10 +- common/channel_id.h | 4 +- common/close_tx.c | 11 +- common/close_tx.h | 7 +- common/coin_mvt.c | 94 +++--- common/coin_mvt.h | 40 +-- common/htlc_tx.c | 15 +- common/htlc_tx.h | 8 +- common/initial_channel.c | 19 +- common/initial_channel.h | 15 +- common/initial_commit_tx.c | 11 +- common/initial_commit_tx.h | 9 +- common/psbt_open.c | 6 +- common/test/run-psbt_diff.c | 6 +- common/utxo.c | 6 +- common/utxo.h | 3 +- devtools/mkclose.c | 9 +- devtools/mkcommit.c | 11 +- devtools/mkfunding.c | 6 +- hsmd/libhsmd.c | 2 +- lightningd/bitcoind.c | 14 +- lightningd/bitcoind.h | 9 +- lightningd/chaintopology.c | 65 ++-- lightningd/channel.c | 18 +- lightningd/channel.h | 20 +- lightningd/channel_control.c | 22 +- lightningd/closing_control.c | 15 +- lightningd/dual_open_control.c | 75 ++--- lightningd/gossip_control.c | 2 +- lightningd/invoice.c | 2 +- lightningd/notification.c | 7 +- lightningd/onchain_control.c | 40 ++- lightningd/opening_common.h | 2 +- lightningd/opening_control.c | 56 ++-- lightningd/peer_control.c | 57 ++-- lightningd/test/run-invoice-select-inchan.c | 12 +- lightningd/watch.c | 6 +- lightningd/watch.h | 3 +- onchaind/onchaind.c | 354 +++++++++++--------- onchaind/onchaind_wire.csv | 6 +- onchaind/test/run-grind_feerate-bug.c | 37 +- onchaind/test/run-grind_feerate.c | 33 +- onchaind/test/run-onchainstress.c | 24 +- openingd/dualopend.c | 88 +++-- openingd/dualopend_wire.csv | 6 +- openingd/openingd.c | 87 +++-- openingd/openingd_wire.csv | 6 +- tests/fuzz/fuzz-channel_id.c | 17 +- tests/fuzz/fuzz-close_tx.c | 13 +- tests/fuzz/fuzz-initial_channel.c | 21 +- tests/test_closing.py | 2 +- wallet/db.c | 9 +- wallet/reservation.c | 81 ++--- wallet/test/run-db.c | 2 +- wallet/test/run-wallet.c | 59 ++-- wallet/txfilter.c | 48 +-- wallet/txfilter.h | 6 +- wallet/wallet.c | 175 +++++----- wallet/wallet.h | 28 +- wallet/walletrpc.c | 57 ++-- 75 files changed, 1061 insertions(+), 1156 deletions(-) diff --git a/bitcoin/psbt.c b/bitcoin/psbt.c index 8075078ee172..17937695c8d2 100644 --- a/bitcoin/psbt.c +++ b/bitcoin/psbt.c @@ -126,8 +126,8 @@ struct wally_psbt_input *psbt_add_input(struct wally_psbt *psbt, } struct wally_psbt_input *psbt_append_input(struct wally_psbt *psbt, - const struct bitcoin_txid *txid, - u32 outnum, u32 sequence, + const struct bitcoin_outpoint *outpoint, + u32 sequence, const u8 *scriptSig, const u8 *input_wscript, const u8 *redeemscript) @@ -139,9 +139,10 @@ struct wally_psbt_input *psbt_append_input(struct wally_psbt *psbt, tal_wally_start(); if (chainparams->is_elements) { - if (wally_tx_elements_input_init_alloc(txid->shad.sha.u.u8, - sizeof(txid->shad.sha.u.u8), - outnum, sequence, NULL, 0, + if (wally_tx_elements_input_init_alloc(outpoint->txid.shad.sha.u.u8, + sizeof(outpoint->txid.shad.sha.u.u8), + outpoint->n, + sequence, NULL, 0, NULL, NULL, 0, NULL, 0, NULL, 0, @@ -150,9 +151,10 @@ struct wally_psbt_input *psbt_append_input(struct wally_psbt *psbt, &tx_in) != WALLY_OK) abort(); } else { - if (wally_tx_input_init_alloc(txid->shad.sha.u.u8, - sizeof(txid->shad.sha.u.u8), - outnum, sequence, NULL, 0, NULL, + if (wally_tx_input_init_alloc(outpoint->txid.shad.sha.u.u8, + sizeof(outpoint->txid.shad.sha.u.u8), + outpoint->n, + sequence, NULL, 0, NULL, &tx_in) != WALLY_OK) abort(); } @@ -412,18 +414,17 @@ void psbt_elements_normalize_fees(struct wally_psbt *psbt) } bool psbt_has_input(const struct wally_psbt *psbt, - const struct bitcoin_txid *txid, - u32 outnum) + const struct bitcoin_outpoint *outpoint) { for (size_t i = 0; i < psbt->num_inputs; i++) { struct bitcoin_txid in_txid; struct wally_tx_input *in = &psbt->tx->inputs[i]; - if (outnum != in->index) + if (outpoint->n != in->index) continue; wally_tx_input_get_txid(in, &in_txid); - if (bitcoin_txid_eq(txid, &in_txid)) + if (bitcoin_txid_eq(&outpoint->txid, &in_txid)) return true; } return false; diff --git a/bitcoin/psbt.h b/bitcoin/psbt.h index 7b98c14aeb72..386ef7a714c7 100644 --- a/bitcoin/psbt.h +++ b/bitcoin/psbt.h @@ -12,6 +12,7 @@ struct wally_tx_output; struct wally_map; struct amount_asset; struct amount_sat; +struct bitcoin_outpoint; struct bitcoin_signature; struct bitcoin_txid; struct pubkey; @@ -119,8 +120,8 @@ struct wally_psbt_input *psbt_add_input(struct wally_psbt *psbt, /* One stop shop for adding an input + metadata to a PSBT */ struct wally_psbt_input *psbt_append_input(struct wally_psbt *psbt, - const struct bitcoin_txid *txid, - u32 outnum, u32 sequence, + const struct bitcoin_outpoint *outpoint, + u32 sequence, const u8 *scriptSig, const u8 *input_wscript, const u8 *redeemscript); @@ -253,12 +254,10 @@ struct amount_sat psbt_compute_fee(const struct wally_psbt *psbt); /* psbt_has_input - Is this input present on this psbt * * @psbt - psbt - * @txid - txid of input - * @outnum - output index of input + * @outpoint - txid/index spent by input */ bool psbt_has_input(const struct wally_psbt *psbt, - const struct bitcoin_txid *txid, - u32 outnum); + const struct bitcoin_outpoint *outpoint); struct wally_psbt *psbt_from_b64(const tal_t *ctx, const char *b64, diff --git a/bitcoin/tx.c b/bitcoin/tx.c index dccec6006fe0..81a5635c79b6 100644 --- a/bitcoin/tx.c +++ b/bitcoin/tx.c @@ -196,15 +196,17 @@ void bitcoin_tx_set_locktime(struct bitcoin_tx *tx, u32 locktime) tx->psbt->tx->locktime = locktime; } -int bitcoin_tx_add_input(struct bitcoin_tx *tx, const struct bitcoin_txid *txid, - u32 outnum, u32 sequence, const u8 *scriptSig, +int bitcoin_tx_add_input(struct bitcoin_tx *tx, + const struct bitcoin_outpoint *outpoint, + u32 sequence, const u8 *scriptSig, struct amount_sat amount, const u8 *scriptPubkey, const u8 *input_wscript) { int wally_err; int input_num = tx->wtx->num_inputs; - psbt_append_input(tx->psbt, txid, outnum, sequence, scriptSig, + psbt_append_input(tx->psbt, outpoint, + sequence, scriptSig, input_wscript, NULL); if (input_wscript) { @@ -388,6 +390,7 @@ const u8 *bitcoin_tx_input_get_witness(const tal_t *ctx, return witness_item; } +/* FIXME: remove */ void bitcoin_tx_input_get_txid(const struct bitcoin_tx *tx, int innum, struct bitcoin_txid *out) { @@ -395,19 +398,27 @@ void bitcoin_tx_input_get_txid(const struct bitcoin_tx *tx, int innum, wally_tx_input_get_txid(&tx->wtx->inputs[innum], out); } -void bitcoin_tx_input_set_txid(struct bitcoin_tx *tx, int innum, - const struct bitcoin_txid *txid, - u32 index) +void bitcoin_tx_input_get_outpoint(const struct bitcoin_tx *tx, + int innum, + struct bitcoin_outpoint *outpoint) +{ + assert(innum < tx->wtx->num_inputs); + wally_tx_input_get_outpoint(&tx->wtx->inputs[innum], outpoint); +} + +void bitcoin_tx_input_set_outpoint(struct bitcoin_tx *tx, int innum, + const struct bitcoin_outpoint *outpoint) { struct wally_tx_input *in; assert(innum < tx->wtx->num_inputs); in = &tx->wtx->inputs[innum]; BUILD_ASSERT(sizeof(struct bitcoin_txid) == sizeof(in->txhash)); - memcpy(in->txhash, txid, sizeof(struct bitcoin_txid)); - in->index = index; + memcpy(in->txhash, &outpoint->txid, sizeof(struct bitcoin_txid)); + in->index = outpoint->n; } +/* FIXME: remove */ void wally_tx_input_get_txid(const struct wally_tx_input *in, struct bitcoin_txid *txid) { @@ -415,6 +426,14 @@ void wally_tx_input_get_txid(const struct wally_tx_input *in, memcpy(txid, in->txhash, sizeof(struct bitcoin_txid)); } +void wally_tx_input_get_outpoint(const struct wally_tx_input *in, + struct bitcoin_outpoint *outpoint) +{ + BUILD_ASSERT(sizeof(struct bitcoin_txid) == sizeof(in->txhash)); + memcpy(&outpoint->txid, in->txhash, sizeof(struct bitcoin_txid)); + outpoint->n = in->index; +} + /* BIP144: * If the witness is empty, the old serialization format should be used. */ static bool uses_witness(const struct wally_tx *wtx) @@ -791,16 +810,15 @@ void towire_bitcoin_tx_output(u8 **pptr, const struct bitcoin_tx_output *output) } bool wally_tx_input_spends(const struct wally_tx_input *input, - const struct bitcoin_txid *txid, - int outnum) + const struct bitcoin_outpoint *outpoint) { /* Useful, as tx_part can have some NULL inputs */ if (!input) return false; - BUILD_ASSERT(sizeof(*txid) == sizeof(input->txhash)); - if (memcmp(txid, input->txhash, sizeof(*txid)) != 0) + BUILD_ASSERT(sizeof(outpoint->txid) == sizeof(input->txhash)); + if (memcmp(&outpoint->txid, input->txhash, sizeof(outpoint->txid)) != 0) return false; - return input->index == outnum; + return input->index == outpoint->n; } /* FIXME(cdecker) Make the caller pass in a reference to amount_asset, and diff --git a/bitcoin/tx.h b/bitcoin/tx.h index 0d6651d71fe5..b6583948d1dc 100644 --- a/bitcoin/tx.h +++ b/bitcoin/tx.h @@ -27,6 +27,9 @@ struct bitcoin_outpoint { /* Define bitcoin_txid_eq */ STRUCTEQ_DEF(bitcoin_txid, 0, shad.sha.u); +/* Define bitcoin_outpoint_eq */ +STRUCTEQ_DEF(bitcoin_outpoint, 0, txid.shad.sha.u, n); + struct bitcoin_tx { struct wally_tx *wtx; @@ -109,15 +112,15 @@ void bitcoin_tx_set_locktime(struct bitcoin_tx *tx, u32 locktime); * Passing in just the {input_wscript}, we'll generate the scriptPubkey for you. * In some cases we may not have the wscript, in which case the scriptPubkey * should be provided. We'll check that it's P2WSH before saving it */ -int bitcoin_tx_add_input(struct bitcoin_tx *tx, const struct bitcoin_txid *txid, - u32 outnum, u32 sequence, const u8 *scriptSig, +int bitcoin_tx_add_input(struct bitcoin_tx *tx, + const struct bitcoin_outpoint *outpoint, + u32 sequence, const u8 *scriptSig, struct amount_sat amount, const u8 *scriptPubkey, const u8 *input_wscript); /* This helps is useful because wally uses a raw byte array for txids */ bool wally_tx_input_spends(const struct wally_tx_input *input, - const struct bitcoin_txid *txid, - int outnum); + const struct bitcoin_outpoint *outpoint); struct amount_asset wally_tx_output_get_amount(const struct wally_tx_output *output); @@ -193,17 +196,23 @@ const u8 *bitcoin_tx_input_get_witness(const tal_t *ctx, /** * Wrap the raw txhash in the wally_tx_input into a bitcoin_txid */ +void bitcoin_tx_input_get_outpoint(const struct bitcoin_tx *tx, + int innum, + struct bitcoin_outpoint *outpoint); + void bitcoin_tx_input_get_txid(const struct bitcoin_tx *tx, int innum, struct bitcoin_txid *out); void wally_tx_input_get_txid(const struct wally_tx_input *in, struct bitcoin_txid *txid); +void wally_tx_input_get_outpoint(const struct wally_tx_input *in, + struct bitcoin_outpoint *outpoint); + /** * Overwrite the txhash and index in the wally_tx_input */ -void bitcoin_tx_input_set_txid(struct bitcoin_tx *tx, int innum, - const struct bitcoin_txid *txid, - u32 index); +void bitcoin_tx_input_set_outpoint(struct bitcoin_tx *tx, int innum, + const struct bitcoin_outpoint *outpoint); /** * Check a transaction for consistency. diff --git a/channeld/channeld.c b/channeld/channeld.c index c2f7660e8dba..8a3b56e8e829 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -235,12 +235,12 @@ static struct amount_msat advertized_htlc_max(const struct channel *channel) struct amount_msat lower_bound_msat; /* This shouldn't fail */ - if (!amount_sat_sub(&lower_bound, channel->funding, + if (!amount_sat_sub(&lower_bound, channel->funding_sats, channel->config[REMOTE].channel_reserve)) { status_failed(STATUS_FAIL_INTERNAL_ERROR, "funding %s - remote reserve %s?", type_to_string(tmpctx, struct amount_sat, - &channel->funding), + &channel->funding_sats), type_to_string(tmpctx, struct amount_sat, &channel->config[REMOTE] .channel_reserve)); @@ -454,7 +454,8 @@ static void make_channel_local_active(struct peer *peer) /* Tell gossipd about local channel. */ msg = towire_gossip_store_private_channel(NULL, - peer->channel->funding, ann); + peer->channel->funding_sats, + ann); wire_sync_write(peer->pps->gossip_fd, take(msg)); /* Tell gossipd and the other side what parameters we expect should @@ -3755,12 +3756,11 @@ static void req_in(struct peer *peer, const u8 *msg) static void init_channel(struct peer *peer) { struct basepoints points[NUM_SIDES]; - struct amount_sat funding; - u16 funding_txout; + struct amount_sat funding_sats; struct amount_msat local_msat; struct pubkey funding_pubkey[NUM_SIDES]; struct channel_config conf[NUM_SIDES]; - struct bitcoin_txid funding_txid; + struct bitcoin_outpoint funding; enum side opener; struct existing_htlc **htlcs; bool reconnected; @@ -3786,8 +3786,8 @@ static void init_channel(struct peer *peer) &chainparams, &peer->our_features, &peer->channel_id, - &funding_txid, &funding_txout, &funding, + &funding_sats, &minimum_depth, &peer->our_blockheight, &blockheight_states, @@ -3899,12 +3899,11 @@ static void init_channel(struct peer *peer) &peer->next_local_per_commit, NULL); peer->channel = new_full_channel(peer, &peer->channel_id, - &funding_txid, - funding_txout, + &funding, minimum_depth, take(blockheight_states), lease_expiry, - funding, + funding_sats, local_msat, take(fee_states), &conf[LOCAL], &conf[REMOTE], diff --git a/channeld/channeld_wire.csv b/channeld/channeld_wire.csv index ae96a489c825..7888fb4d4ce6 100644 --- a/channeld/channeld_wire.csv +++ b/channeld/channeld_wire.csv @@ -15,8 +15,7 @@ msgtype,channeld_init,1000 msgdata,channeld_init,chainparams,chainparams, msgdata,channeld_init,our_features,feature_set, msgdata,channeld_init,channel_id,channel_id, -msgdata,channeld_init,funding_txid,bitcoin_txid, -msgdata,channeld_init,funding_txout,u16, +msgdata,channeld_init,funding,bitcoin_outpoint, msgdata,channeld_init,funding_satoshi,amount_sat, msgdata,channeld_init,minimum_depth,u32, msgdata,channeld_init,our_blockheight,u32, diff --git a/channeld/commit_tx.c b/channeld/commit_tx.c index 8f58a4a9ee13..3eec184401b7 100644 --- a/channeld/commit_tx.c +++ b/channeld/commit_tx.c @@ -80,9 +80,8 @@ static void add_received_htlc_out(struct bitcoin_tx *tx, size_t n, } struct bitcoin_tx *commit_tx(const tal_t *ctx, - const struct bitcoin_txid *funding_txid, - unsigned int funding_txout, - struct amount_sat funding, + const struct bitcoin_outpoint *funding, + struct amount_sat funding_sats, const struct pubkey *local_funding_key, const struct pubkey *remote_funding_key, enum side opener, @@ -119,7 +118,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, if (!amount_msat_add(&total_pay, self_pay, other_pay)) abort(); - assert(!amount_msat_greater_sat(total_pay, funding)); + assert(!amount_msat_greater_sat(total_pay, funding_sats)); /* BOLT #3: * @@ -176,7 +175,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, ok &= amount_sat_add(&out, out, amount_msat_to_sat_round_down(other_pay)); assert(ok); SUPERVERBOSE("# actual commitment transaction fee = %"PRIu64"\n", - funding.satoshis - out.satoshis); /* Raw: test output */ + funding_sats.satoshis - out.satoshis); /* Raw: test output */ } #endif @@ -390,8 +389,8 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, * * `txin[0]` sequence: upper 8 bits are 0x80, lower 24 bits are upper 24 bits of the obscured commitment number */ u32 sequence = (0x80000000 | ((obscured_commitment_number>>24) & 0xFFFFFF)); - bitcoin_tx_add_input(tx, funding_txid, funding_txout, - sequence, NULL, funding, NULL, funding_wscript); + bitcoin_tx_add_input(tx, funding, + sequence, NULL, funding_sats, NULL, funding_wscript); /* Identify the direct outputs (to_us, to_them). */ if (direct_outputs != NULL) { diff --git a/channeld/commit_tx.h b/channeld/commit_tx.h index ec8c42059a84..1de552ef61a8 100644 --- a/channeld/commit_tx.h +++ b/channeld/commit_tx.h @@ -27,7 +27,7 @@ size_t commit_tx_num_untrimmed(const struct htlc **htlcs, /** * commit_tx: create (unsigned) commitment tx to spend the funding tx output * @ctx: context to allocate transaction and @htlc_map from. - * @funding_txid, @funding_out, @funding: funding outpoint. + * @funding, @funding_sats: funding outpoint and amount * @local_funding_key, @remote_funding_key: keys for funding input. * @opener: is the LOCAL or REMOTE paying the fee? * @keyset: keys derived for this commit tx. @@ -48,9 +48,8 @@ size_t commit_tx_num_untrimmed(const struct htlc **htlcs, * transaction, so we carefully use the terms "self" and "other" here. */ struct bitcoin_tx *commit_tx(const tal_t *ctx, - const struct bitcoin_txid *funding_txid, - unsigned int funding_txout, - struct amount_sat funding, + const struct bitcoin_outpoint *funding, + struct amount_sat funding_sats, const struct pubkey *local_funding_key, const struct pubkey *remote_funding_key, enum side opener, diff --git a/channeld/full_channel.c b/channeld/full_channel.c index cbf38ada4dfd..1ae08ec79909 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -80,12 +80,11 @@ static bool balance_ok(const struct balance *balance, struct channel *new_full_channel(const tal_t *ctx, const struct channel_id *cid, - const struct bitcoin_txid *funding_txid, - unsigned int funding_txout, + const struct bitcoin_outpoint *funding, u32 minimum_depth, const struct height_states *blockheight_states, u32 lease_expiry, - struct amount_sat funding, + struct amount_sat funding_sats, struct amount_msat local_msat, const struct fee_states *fee_states TAKES, const struct channel_config *local, @@ -100,12 +99,11 @@ struct channel *new_full_channel(const tal_t *ctx, { struct channel *channel = new_initial_channel(ctx, cid, - funding_txid, - funding_txout, + funding, minimum_depth, blockheight_states, lease_expiry, - funding, + funding_sats, local_msat, fee_states, local, remote, @@ -244,16 +242,15 @@ static void add_htlcs(struct bitcoin_tx ***txs, const struct keyset *keyset, enum side side) { - size_t i; - struct bitcoin_txid txid; + struct bitcoin_outpoint outpoint; u32 feerate_per_kw = channel_feerate(channel, side); bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS); /* Get txid of commitment transaction */ - bitcoin_txid((*txs)[0], &txid); + bitcoin_txid((*txs)[0], &outpoint.txid); - for (i = 0; i < tal_count(htlcmap); i++) { - const struct htlc *htlc = htlcmap[i]; + for (outpoint.n = 0; outpoint.n < tal_count(htlcmap); outpoint.n++) { + const struct htlc *htlc = htlcmap[outpoint.n]; struct bitcoin_tx *tx; struct ripemd160 ripemd; const u8 *wscript; @@ -265,7 +262,7 @@ static void add_htlcs(struct bitcoin_tx ***txs, ripemd160(&ripemd, htlc->rhash.u.u8, sizeof(htlc->rhash.u.u8)); wscript = htlc_offered_wscript(tmpctx, &ripemd, keyset, option_anchor_outputs); - tx = htlc_timeout_tx(*txs, chainparams, &txid, i, + tx = htlc_timeout_tx(*txs, chainparams, &outpoint, wscript, htlc->amount, htlc->expiry.locktime, @@ -278,7 +275,7 @@ static void add_htlcs(struct bitcoin_tx ***txs, wscript = htlc_received_wscript(tmpctx, &ripemd, &htlc->expiry, keyset, option_anchor_outputs); - tx = htlc_success_tx(*txs, chainparams, &txid, i, + tx = htlc_success_tx(*txs, chainparams, &outpoint, wscript, htlc->amount, channel->config[!side].to_self_delay, @@ -324,8 +321,8 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx, txs = tal_arr(ctx, struct bitcoin_tx *, 1); txs[0] = commit_tx( - ctx, &channel->funding_txid, channel->funding_txout, - channel->funding, + ctx, &channel->funding, + channel->funding_sats, &channel->funding_pubkey[side], &channel->funding_pubkey[!side], channel->opener, diff --git a/channeld/full_channel.h b/channeld/full_channel.h index 8351de8defd0..b9f59e9c1da6 100644 --- a/channeld/full_channel.h +++ b/channeld/full_channel.h @@ -14,12 +14,11 @@ struct existing_htlc; * new_full_channel: Given initial fees and funding, what is initial state? * @ctx: tal context to allocate return value from. * @cid: The channel id. - * @funding_txid: The commitment transaction id. - * @funding_txout: The commitment transaction output number. + * @funding: The commitment transaction id/output number. * @minimum_depth: The minimum confirmations needed for funding transaction. * @blockheight_states: The blockheight update states. * @lease_expiry: The block the lease on this channel expires at; 0 if no lease. - * @funding: The commitment transaction amount. + * @funding_sats: The commitment transaction amount. * @local_msat: The amount for the local side (remainder goes to remote) * @fee_states: The fee update states. * @local: local channel configuration @@ -36,12 +35,11 @@ struct existing_htlc; */ struct channel *new_full_channel(const tal_t *ctx, const struct channel_id *cid, - const struct bitcoin_txid *funding_txid, - unsigned int funding_txout, + const struct bitcoin_outpoint *funding, u32 minimum_depth, const struct height_states *blockheight_states, u32 lease_expiry, - struct amount_sat funding, + struct amount_sat funding_sats, struct amount_msat local_msat, const struct fee_states *fee_states TAKES, const struct channel_config *local, diff --git a/channeld/test/run-commit_tx.c b/channeld/test/run-commit_tx.c index 57d4ce234020..7dfeed50c7c6 100644 --- a/channeld/test/run-commit_tx.c +++ b/channeld/test/run-commit_tx.c @@ -247,7 +247,7 @@ static void report_htlcs(const struct bitcoin_tx *tx, bool option_anchor_outputs) { size_t i, n; - struct bitcoin_txid txid; + struct bitcoin_outpoint outpoint; struct bitcoin_tx **htlc_tx; struct bitcoin_signature *remotehtlcsig; struct keyset keyset; @@ -258,7 +258,7 @@ static void report_htlcs(const struct bitcoin_tx *tx, tal_count(htlc_map)); wscript = tal_arr(tmpctx, u8 *, tal_count(htlc_map)); - bitcoin_txid(tx, &txid); + bitcoin_txid(tx, &outpoint.txid); /* First report remote signatures, in order we would receive them. */ n = 0; @@ -283,6 +283,7 @@ static void report_htlcs(const struct bitcoin_tx *tx, if (!htlc) continue; + outpoint.n = i; if (htlc_owner(htlc) == LOCAL) { wscript[i] = bitcoin_wscript_htlc_offer(tmpctx, local_htlckey, @@ -291,7 +292,7 @@ static void report_htlcs(const struct bitcoin_tx *tx, remote_revocation_key, option_anchor_outputs); htlc_tx[i] = htlc_timeout_tx(htlc_tx, tx->chainparams, - &txid, i, wscript[i], + &outpoint, wscript[i], htlc->amount, htlc->expiry.locktime, to_self_delay, @@ -306,7 +307,7 @@ static void report_htlcs(const struct bitcoin_tx *tx, remote_revocation_key, option_anchor_outputs); htlc_tx[i] = htlc_success_tx(htlc_tx, tx->chainparams, - &txid, i, wscript[i], + &outpoint, wscript[i], htlc->amount, to_self_delay, feerate_per_kw, @@ -490,7 +491,7 @@ int main(int argc, const char *argv[]) { common_setup(argv[0]); - struct bitcoin_txid funding_txid; + struct bitcoin_outpoint funding; struct amount_sat funding_amount, dust_limit; u32 feerate_per_kw; u16 to_self_delay; @@ -516,7 +517,6 @@ int main(int argc, const char *argv[]) struct bitcoin_tx *tx, *tx2; struct keyset keyset; u8 *wscript; - unsigned int funding_output_index; u64 commitment_number, cn_obscurer; struct amount_msat to_local, to_remote; const struct htlc **htlcs, **htlc_map, **htlc_map2, **inv_htlcs; @@ -565,8 +565,8 @@ int main(int argc, const char *argv[]) * local_delay: 144 * local_dust_limit_satoshi: 546 */ - funding_txid = txid_from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be"); - funding_output_index = 0; + funding.txid = txid_from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be"); + funding.n = 0; funding_amount.satoshis = 10000000; commitment_number = 42; to_self_delay = 144; @@ -792,7 +792,7 @@ int main(int argc, const char *argv[]) print_superverbose = true; tx = commit_tx(tmpctx, - &funding_txid, funding_output_index, + &funding, funding_amount, &local_funding_pubkey, &remote_funding_pubkey, @@ -808,7 +808,7 @@ int main(int argc, const char *argv[]) LOCAL); print_superverbose = false; tx2 = commit_tx(tmpctx, - &funding_txid, funding_output_index, + &funding, funding_amount, &local_funding_pubkey, &remote_funding_pubkey, @@ -857,7 +857,7 @@ int main(int argc, const char *argv[]) print_superverbose = true; tx = commit_tx(tmpctx, - &funding_txid, funding_output_index, + &funding, funding_amount, &local_funding_pubkey, &remote_funding_pubkey, @@ -873,7 +873,7 @@ int main(int argc, const char *argv[]) LOCAL); print_superverbose = false; tx2 = commit_tx(tmpctx, - &funding_txid, funding_output_index, + &funding, funding_amount, &local_funding_pubkey, &remote_funding_pubkey, @@ -910,7 +910,7 @@ int main(int argc, const char *argv[]) feerate_per_kw = increase(feerate_per_kw); print_superverbose = false; newtx = commit_tx(tmpctx, - &funding_txid, funding_output_index, + &funding, funding_amount, &local_funding_pubkey, &remote_funding_pubkey, @@ -927,7 +927,7 @@ int main(int argc, const char *argv[]) LOCAL); /* This is what it would look like for peer generating it! */ tx2 = commit_tx(tmpctx, - &funding_txid, funding_output_index, + &funding, funding_amount, &local_funding_pubkey, &remote_funding_pubkey, @@ -970,7 +970,7 @@ int main(int argc, const char *argv[]) /* Recalc with verbosity on */ print_superverbose = true; tx = commit_tx(tmpctx, - &funding_txid, funding_output_index, + &funding, funding_amount, &local_funding_pubkey, &remote_funding_pubkey, @@ -1019,7 +1019,7 @@ int main(int argc, const char *argv[]) /* Recalc with verbosity on */ print_superverbose = true; newtx = commit_tx(tmpctx, - &funding_txid, funding_output_index, + &funding, funding_amount, &local_funding_pubkey, &remote_funding_pubkey, @@ -1094,7 +1094,7 @@ int main(int argc, const char *argv[]) "local_feerate_per_kw: %u\n", to_local.millisatoshis, to_remote.millisatoshis, feerate_per_kw); tx = commit_tx(tmpctx, - &funding_txid, funding_output_index, + &funding, funding_amount, &local_funding_pubkey, &remote_funding_pubkey, @@ -1149,7 +1149,7 @@ int main(int argc, const char *argv[]) print_superverbose = true; tx = commit_tx(tmpctx, - &funding_txid, funding_output_index, + &funding, funding_amount, &local_funding_pubkey, &remote_funding_pubkey, @@ -1165,7 +1165,7 @@ int main(int argc, const char *argv[]) LOCAL); print_superverbose = false; tx2 = commit_tx(tmpctx, - &funding_txid, funding_output_index, + &funding, funding_amount, &local_funding_pubkey, &remote_funding_pubkey, diff --git a/channeld/test/run-full_channel.c b/channeld/test/run-full_channel.c index bc7b3e3a84be..b82dfa5d5f90 100644 --- a/channeld/test/run-full_channel.c +++ b/channeld/test/run-full_channel.c @@ -341,13 +341,12 @@ int main(int argc, const char *argv[]) { common_setup(argv[0]); - struct bitcoin_txid funding_txid; + struct bitcoin_outpoint funding; /* We test from both sides. */ struct channel *lchannel, *rchannel; struct channel_id cid; struct amount_sat funding_amount; u32 *feerate_per_kw; - unsigned int funding_output_index; struct keyset keyset; struct pubkey local_funding_pubkey, remote_funding_pubkey; struct pubkey local_per_commitment_point; @@ -395,8 +394,8 @@ int main(int argc, const char *argv[]) * local_delay: 144 * local_dust_limit_satoshi: 546 */ - funding_txid = txid_from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be"); - funding_output_index = 0; + funding.txid = txid_from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be"); + funding.n = 0; funding_amount = AMOUNT_SAT(10000000); remote_config->to_self_delay = 144; @@ -468,9 +467,9 @@ int main(int argc, const char *argv[]) to_local = AMOUNT_MSAT(7000000000); to_remote = AMOUNT_MSAT(3000000000); feerate_per_kw[LOCAL] = feerate_per_kw[REMOTE] = 15000; - derive_channel_id(&cid, &funding_txid, funding_output_index); + derive_channel_id(&cid, &funding); lchannel = new_full_channel(tmpctx, &cid, - &funding_txid, funding_output_index, 0, + &funding, 0, take(new_height_states(NULL, LOCAL, &blockheight)), 0, /* No channel lease */ funding_amount, to_local, @@ -483,7 +482,7 @@ int main(int argc, const char *argv[]) &remote_funding_pubkey, take(channel_type_none(NULL)), false, LOCAL); rchannel = new_full_channel(tmpctx, &cid, - &funding_txid, funding_output_index, 0, + &funding, 0, take(new_height_states(NULL, REMOTE, &blockheight)), 0, /* No channel lease */ funding_amount, to_remote, @@ -517,7 +516,7 @@ int main(int argc, const char *argv[]) keyset.other_htlc_key = keyset.other_payment_key; raw_tx = commit_tx(tmpctx, - &funding_txid, funding_output_index, + &funding, funding_amount, &local_funding_pubkey, &remote_funding_pubkey, @@ -648,7 +647,7 @@ int main(int argc, const char *argv[]) = feerate_per_kw[REMOTE]; raw_tx = commit_tx( - tmpctx, &funding_txid, funding_output_index, + tmpctx, &funding, funding_amount, &local_funding_pubkey, &remote_funding_pubkey, diff --git a/channeld/watchtower.c b/channeld/watchtower.c index db81121d7f9f..cdf11a106fe0 100644 --- a/channeld/watchtower.c +++ b/channeld/watchtower.c @@ -38,6 +38,7 @@ penalty_tx_create(const tal_t *ctx, const struct secret remote_per_commitment_secret = *revocation_preimage; struct pubkey remote_per_commitment_point; const struct basepoints *basepoints = channel->basepoints; + struct bitcoin_outpoint outpoint; if (to_them_outnum == -1 || amount_sat_less_eq(to_them_sats, dust_limit)) { @@ -47,6 +48,9 @@ penalty_tx_create(const tal_t *ctx, return NULL; } + outpoint.txid = *commitment_txid; + outpoint.n = to_them_outnum; + if (!pubkey_from_secret(&remote_per_commitment_secret, &remote_per_commitment_point)) status_failed(STATUS_FAIL_INTERNAL_ERROR, "Failed derive from per_commitment_secret %s", @@ -67,7 +71,7 @@ penalty_tx_create(const tal_t *ctx, &keyset.self_delayed_payment_key); tx = bitcoin_tx(ctx, chainparams, 1, 1, locktime); - bitcoin_tx_add_input(tx, commitment_txid, to_them_outnum, 0xFFFFFFFF, + bitcoin_tx_add_input(tx, &outpoint, 0xFFFFFFFF, NULL, to_them_sats, NULL, wscript); bitcoin_tx_add_output(tx, final_scriptpubkey, NULL, to_them_sats); diff --git a/closingd/closingd.c b/closingd/closingd.c index 883a14e95eef..10a8279d202f 100644 --- a/closingd/closingd.c +++ b/closingd/closingd.c @@ -53,9 +53,8 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx, struct per_peer_state *pps, const struct channel_id *channel_id, u8 *scriptpubkey[NUM_SIDES], - const struct bitcoin_txid *funding_txid, - unsigned int funding_txout, - struct amount_sat funding, + const struct bitcoin_outpoint *funding, + struct amount_sat funding_sats, const u8 *funding_wscript, const struct amount_sat out[NUM_SIDES], enum side opener, @@ -87,9 +86,8 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx, chainparams, scriptpubkey[LOCAL], scriptpubkey[REMOTE], funding_wscript, - funding_txid, - funding_txout, funding, + funding_sats, out_minus_fee[LOCAL], out_minus_fee[REMOTE], dust_limit); @@ -101,16 +99,14 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx, " dust_limit = %s" " LOCAL = %s" " REMOTE = %s", - type_to_string(tmpctx, struct amount_sat, &funding), + type_to_string(tmpctx, struct amount_sat, &funding_sats), type_to_string(tmpctx, struct amount_sat, &fee), type_to_string(tmpctx, struct amount_sat, &dust_limit), type_to_string(tmpctx, struct amount_sat, &out[LOCAL]), type_to_string(tmpctx, struct amount_sat, &out[REMOTE])); if (wrong_funding) - bitcoin_tx_input_set_txid(tx, 0, - &wrong_funding->txid, - wrong_funding->n); + bitcoin_tx_input_set_outpoint(tx, 0, wrong_funding); return tx; } @@ -150,9 +146,8 @@ static void send_offer(struct per_peer_state *pps, const struct pubkey funding_pubkey[NUM_SIDES], const u8 *funding_wscript, u8 *scriptpubkey[NUM_SIDES], - const struct bitcoin_txid *funding_txid, - unsigned int funding_txout, - struct amount_sat funding, + const struct bitcoin_outpoint *funding, + struct amount_sat funding_sats, const struct amount_sat out[NUM_SIDES], enum side opener, struct amount_sat our_dust_limit, @@ -173,9 +168,8 @@ static void send_offer(struct per_peer_state *pps, */ tx = close_tx(tmpctx, chainparams, pps, channel_id, scriptpubkey, - funding_txid, - funding_txout, funding, + funding_sats, funding_wscript, out, opener, fee_to_offer, our_dust_limit, @@ -247,9 +241,8 @@ receive_offer(struct per_peer_state *pps, const struct pubkey funding_pubkey[NUM_SIDES], const u8 *funding_wscript, u8 *scriptpubkey[NUM_SIDES], - const struct bitcoin_txid *funding_txid, - unsigned int funding_txout, - struct amount_sat funding, + const struct bitcoin_outpoint *funding, + struct amount_sat funding_sats, const struct amount_sat out[NUM_SIDES], enum side opener, struct amount_sat our_dust_limit, @@ -308,9 +301,8 @@ receive_offer(struct per_peer_state *pps, */ tx = close_tx(tmpctx, chainparams, pps, channel_id, scriptpubkey, - funding_txid, - funding_txout, funding, + funding_sats, funding_wscript, out, opener, received_fee, our_dust_limit, wrong_funding); @@ -339,9 +331,8 @@ receive_offer(struct per_peer_state *pps, */ trimmed = close_tx(tmpctx, chainparams, pps, channel_id, scriptpubkey, - funding_txid, - funding_txout, funding, + funding_sats, funding_wscript, trimming_out, opener, received_fee, our_dust_limit, @@ -582,23 +573,23 @@ static void closing_dev_memleak(const tal_t *ctx, static size_t closing_tx_weight_estimate(u8 *scriptpubkey[NUM_SIDES], const u8 *funding_wscript, const struct amount_sat *out, - struct amount_sat funding, + struct amount_sat funding_sats, struct amount_sat dust_limit) { /* We create a dummy close */ struct bitcoin_tx *tx; - struct bitcoin_txid dummy_txid; + struct bitcoin_outpoint dummy_funding; struct bitcoin_signature dummy_sig; struct privkey dummy_privkey; struct pubkey dummy_pubkey; u8 **witness; - memset(&dummy_txid, 0, sizeof(dummy_txid)); + memset(&dummy_funding, 0, sizeof(dummy_funding)); tx = create_close_tx(tmpctx, chainparams, scriptpubkey[LOCAL], scriptpubkey[REMOTE], funding_wscript, - &dummy_txid, 0, - funding, + &dummy_funding, + funding_sats, out[LOCAL], out[REMOTE], dust_limit); @@ -607,7 +598,7 @@ static size_t closing_tx_weight_estimate(u8 *scriptpubkey[NUM_SIDES], * tx. */ dummy_sig.sighash_type = SIGHASH_ALL; memset(&dummy_privkey, 1, sizeof(dummy_privkey)); - sign_hash(&dummy_privkey, &dummy_txid.shad, &dummy_sig.s); + sign_hash(&dummy_privkey, &dummy_funding.txid.shad, &dummy_sig.s); pubkey_from_privkey(&dummy_privkey, &dummy_pubkey); witness = bitcoin_witness_2of2(NULL, &dummy_sig, &dummy_sig, &dummy_pubkey, &dummy_pubkey); @@ -709,9 +700,8 @@ static void do_quickclose(struct amount_sat offer[NUM_SIDES], const struct pubkey funding_pubkey[NUM_SIDES], const u8 *funding_wscript, u8 *scriptpubkey[NUM_SIDES], - const struct bitcoin_txid *funding_txid, - unsigned int funding_txout, - struct amount_sat funding, + const struct bitcoin_outpoint *funding, + struct amount_sat funding_sats, const struct amount_sat out[NUM_SIDES], enum side opener, struct amount_sat our_dust_limit, @@ -788,8 +778,8 @@ static void do_quickclose(struct amount_sat offer[NUM_SIDES], offer[LOCAL] = offer[REMOTE]; send_offer(pps, chainparams, channel_id, funding_pubkey, funding_wscript, - scriptpubkey, funding_txid, funding_txout, - funding, out, opener, + scriptpubkey, funding, + funding_sats, out, opener, our_dust_limit, offer[LOCAL], wrong_funding, @@ -827,8 +817,8 @@ static void do_quickclose(struct amount_sat offer[NUM_SIDES], } send_offer(pps, chainparams, channel_id, funding_pubkey, funding_wscript, - scriptpubkey, funding_txid, funding_txout, - funding, out, opener, + scriptpubkey, funding, + funding_sats, out, opener, our_dust_limit, offer[LOCAL], wrong_funding, @@ -840,8 +830,8 @@ static void do_quickclose(struct amount_sat offer[NUM_SIDES], = receive_offer(pps, chainparams, channel_id, funding_pubkey, funding_wscript, - scriptpubkey, funding_txid, - funding_txout, funding, + scriptpubkey, funding, + funding_sats, out, opener, our_dust_limit, our_feerange->min_fee_satoshis, @@ -880,9 +870,9 @@ int main(int argc, char *argv[]) struct per_peer_state *pps; u8 *msg; struct pubkey funding_pubkey[NUM_SIDES]; - struct bitcoin_txid funding_txid, closing_txid; - u16 funding_txout; - struct amount_sat funding, out[NUM_SIDES]; + struct bitcoin_txid closing_txid; + struct bitcoin_outpoint funding; + struct amount_sat funding_sats, out[NUM_SIDES]; struct amount_sat our_dust_limit; struct amount_sat min_fee_to_accept, commitment_fee, offer[NUM_SIDES], max_fee_to_accept; @@ -908,8 +898,8 @@ int main(int argc, char *argv[]) &chainparams, &pps, &channel_id, - &funding_txid, &funding_txout, &funding, + &funding_sats, &funding_pubkey[LOCAL], &funding_pubkey[REMOTE], &opener, @@ -937,9 +927,10 @@ int main(int argc, char *argv[]) /* Start at what we consider a reasonable feerate for this tx. */ calc_fee_bounds(closing_tx_weight_estimate(scriptpubkey, funding_wscript, - out, funding, our_dust_limit), + out, funding_sats, + our_dust_limit), min_feerate, initial_feerate, max_feerate, - commitment_fee, funding, opener, + commitment_fee, funding_sats, opener, &min_fee_to_accept, &offer[LOCAL], &max_fee_to_accept); /* Write values into tlv for updated closing fee neg */ @@ -995,8 +986,8 @@ int main(int argc, char *argv[]) if (whose_turn == LOCAL) { send_offer(pps, chainparams, &channel_id, funding_pubkey, funding_wscript, - scriptpubkey, &funding_txid, funding_txout, - funding, out, opener, + scriptpubkey, &funding, + funding_sats, out, opener, our_dust_limit, offer[LOCAL], wrong_funding, @@ -1016,8 +1007,8 @@ int main(int argc, char *argv[]) = receive_offer(pps, chainparams, &channel_id, funding_pubkey, funding_wscript, - scriptpubkey, &funding_txid, - funding_txout, funding, + scriptpubkey, &funding, + funding_sats, out, opener, our_dust_limit, min_fee_to_accept, @@ -1030,8 +1021,8 @@ int main(int argc, char *argv[]) pps, &channel_id, funding_pubkey, funding_wscript, scriptpubkey, - &funding_txid, funding_txout, - funding, out, opener, + &funding, + funding_sats, out, opener, our_dust_limit, wrong_funding, &closing_txid, @@ -1062,8 +1053,8 @@ int main(int argc, char *argv[]) fee_negotiation_step_unit); send_offer(pps, chainparams, &channel_id, funding_pubkey, funding_wscript, - scriptpubkey, &funding_txid, funding_txout, - funding, out, opener, + scriptpubkey, &funding, + funding_sats, out, opener, our_dust_limit, offer[LOCAL], wrong_funding, @@ -1078,8 +1069,8 @@ int main(int argc, char *argv[]) = receive_offer(pps, chainparams, &channel_id, funding_pubkey, funding_wscript, - scriptpubkey, &funding_txid, - funding_txout, funding, + scriptpubkey, &funding, + funding_sats, out, opener, our_dust_limit, min_fee_to_accept, diff --git a/closingd/closingd_wire.csv b/closingd/closingd_wire.csv index b6555a056b03..a6b066d739a3 100644 --- a/closingd/closingd_wire.csv +++ b/closingd/closingd_wire.csv @@ -9,8 +9,7 @@ msgtype,closingd_init,2001 msgdata,closingd_init,chainparams,chainparams, msgdata,closingd_init,pps,per_peer_state, msgdata,closingd_init,channel_id,channel_id, -msgdata,closingd_init,funding_txid,bitcoin_txid, -msgdata,closingd_init,funding_txout,u16, +msgdata,closingd_init,funding,bitcoin_outpoint, msgdata,closingd_init,funding_satoshi,amount_sat, msgdata,closingd_init,local_fundingkey,pubkey, msgdata,closingd_init,remote_fundingkey,pubkey, diff --git a/common/channel_id.c b/common/channel_id.c index 504cb3033e69..726297fa4231 100644 --- a/common/channel_id.c +++ b/common/channel_id.c @@ -6,12 +6,12 @@ #include void derive_channel_id(struct channel_id *channel_id, - const struct bitcoin_txid *txid, u16 txout) + const struct bitcoin_outpoint *outpoint) { - BUILD_ASSERT(sizeof(*channel_id) == sizeof(*txid)); - memcpy(channel_id, txid, sizeof(*channel_id)); - channel_id->id[sizeof(*channel_id)-2] ^= txout >> 8; - channel_id->id[sizeof(*channel_id)-1] ^= txout; + BUILD_ASSERT(sizeof(*channel_id) == sizeof(outpoint->txid)); + memcpy(channel_id, &outpoint->txid, sizeof(*channel_id)); + channel_id->id[sizeof(*channel_id)-2] ^= outpoint->n >> 8; + channel_id->id[sizeof(*channel_id)-1] ^= outpoint->n; } void derive_channel_id_v2(struct channel_id *channel_id, diff --git a/common/channel_id.h b/common/channel_id.h index 9a3aa13e0495..81b6ef0248ea 100644 --- a/common/channel_id.h +++ b/common/channel_id.h @@ -4,7 +4,7 @@ #include #include -struct bitcoin_txid; +struct bitcoin_outpoint; struct pubkey; /* BOLT #2: @@ -22,7 +22,7 @@ STRUCTEQ_DEF(channel_id, 0, id); /* For v1 channel establishment */ void derive_channel_id(struct channel_id *channel_id, - const struct bitcoin_txid *txid, u16 txout); + const struct bitcoin_outpoint *outpoint); /* For v1 channel establishment */ void temporary_channel_id(struct channel_id *channel_id); diff --git a/common/close_tx.c b/common/close_tx.c index 6b58986ff17f..236d7ababce4 100644 --- a/common/close_tx.c +++ b/common/close_tx.c @@ -10,9 +10,8 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx, const u8 *our_script, const u8 *their_script, const u8 *funding_wscript, - const struct bitcoin_txid *anchor_txid, - unsigned int anchor_index, - struct amount_sat funding, + const struct bitcoin_outpoint *funding, + struct amount_sat funding_sats, struct amount_sat to_us, struct amount_sat to_them, struct amount_sat dust_limit) @@ -23,7 +22,7 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx, u8 *script; assert(amount_sat_add(&total_out, to_us, to_them)); - assert(amount_sat_less_eq(total_out, funding)); + assert(amount_sat_less_eq(total_out, funding_sats)); /* BOLT #3: * @@ -39,9 +38,9 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx, tx = bitcoin_tx(ctx, chainparams, 1, 2, 0); /* Our input spends the anchor tx output. */ - bitcoin_tx_add_input(tx, anchor_txid, anchor_index, + bitcoin_tx_add_input(tx, funding, BITCOIN_TX_DEFAULT_SEQUENCE, NULL, - funding, NULL, funding_wscript); + funding_sats, NULL, funding_wscript); if (amount_sat_greater_eq(to_us, dust_limit)) { script = tal_dup_talarr(tx, u8, our_script); diff --git a/common/close_tx.h b/common/close_tx.h index 445cd813232c..6f9886556fe5 100644 --- a/common/close_tx.h +++ b/common/close_tx.h @@ -3,8 +3,6 @@ #include "config.h" #include -struct pubkey; - /* Create close tx to spend the anchor tx output; doesn't fill in * input scriptsig. */ struct bitcoin_tx *create_close_tx(const tal_t *ctx, @@ -12,9 +10,8 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx, const u8 *our_script, const u8 *their_script, const u8 *funding_wscript, - const struct bitcoin_txid *anchor_txid, - unsigned int anchor_index, - struct amount_sat funding, + const struct bitcoin_outpoint *funding, + struct amount_sat funding_sats, struct amount_sat to_us, struct amount_sat to_them, struct amount_sat dust_limit); diff --git a/common/coin_mvt.c b/common/coin_mvt.c index 9e48398e8ffb..537c1231f485 100644 --- a/common/coin_mvt.c +++ b/common/coin_mvt.c @@ -59,8 +59,7 @@ struct channel_coin_mvt *new_channel_coin_mvt(const tal_t *ctx, static struct chain_coin_mvt *new_chain_coin_mvt(const tal_t *ctx, const char *account_name, const struct bitcoin_txid *tx_txid, - const struct bitcoin_txid *output_txid, - u32 vout, + const struct bitcoin_outpoint *outpoint, const struct sha256 *payment_hash TAKES, u32 blockheight, enum mvt_tag tag, struct amount_msat amount, @@ -75,8 +74,7 @@ static struct chain_coin_mvt *new_chain_coin_mvt(const tal_t *ctx, mvt->account_name = NULL; mvt->tx_txid = tx_txid; - mvt->output_txid = output_txid; - mvt->vout = vout; + mvt->outpoint = outpoint; /* for htlc's that are filled onchain, we also have a * preimage, NULL otherwise */ @@ -101,8 +99,7 @@ static struct chain_coin_mvt *new_chain_coin_mvt(const tal_t *ctx, static struct chain_coin_mvt *new_chain_coin_mvt_sat(const tal_t *ctx, const char *account_name, const struct bitcoin_txid *tx_txid, - const struct bitcoin_txid *output_txid, - u32 vout, + const struct bitcoin_outpoint *outpoint, const struct sha256 *payment_hash TAKES, u32 blockheight, enum mvt_tag tag, struct amount_sat amt_sat, @@ -114,28 +111,27 @@ static struct chain_coin_mvt *new_chain_coin_mvt_sat(const tal_t *ctx, assert(ok); return new_chain_coin_mvt(ctx, account_name, tx_txid, - output_txid, vout, payment_hash, + outpoint, payment_hash, blockheight, tag, amt_msat, is_credit); } struct chain_coin_mvt *new_coin_withdrawal(const tal_t *ctx, - const char *account_name, - const struct bitcoin_txid *tx_txid, - const struct bitcoin_txid *out_txid, - u32 vout, - u32 blockheight, - struct amount_msat amount) + const char *account_name, + const struct bitcoin_txid *tx_txid, + const struct bitcoin_outpoint *outpoint, + u32 blockheight, + struct amount_msat amount) { + assert(!amount_msat_eq(amount, AMOUNT_MSAT(7206000))); return new_chain_coin_mvt(ctx, account_name, tx_txid, - out_txid, vout, NULL, blockheight, + outpoint, NULL, blockheight, WITHDRAWAL, amount, false); } struct chain_coin_mvt *new_coin_withdrawal_sat(const tal_t *ctx, const char *account_name, const struct bitcoin_txid *tx_txid, - const struct bitcoin_txid *out_txid, - u32 vout, + const struct bitcoin_outpoint *outpoint, u32 blockheight, struct amount_sat amount) { @@ -145,7 +141,7 @@ struct chain_coin_mvt *new_coin_withdrawal_sat(const tal_t *ctx, ok = amount_sat_to_msat(&amt_msat, amount); assert(ok); - return new_coin_withdrawal(ctx, account_name, tx_txid, out_txid, vout, + return new_coin_withdrawal(ctx, account_name, tx_txid, outpoint, blockheight, amt_msat); } @@ -156,7 +152,7 @@ struct chain_coin_mvt *new_coin_chain_fees(const tal_t *ctx, struct amount_msat amount) { return new_chain_coin_mvt(ctx, account_name, tx_txid, - NULL, 0, NULL, blockheight, + NULL, NULL, blockheight, CHAIN_FEES, amount, false); } @@ -179,33 +175,32 @@ struct chain_coin_mvt *new_coin_chain_fees_sat(const tal_t *ctx, struct chain_coin_mvt *new_coin_journal_entry(const tal_t *ctx, const char *account_name, const struct bitcoin_txid *txid, - const struct bitcoin_txid *out_txid, - u32 vout, + const struct bitcoin_outpoint *outpoint, u32 blockheight, struct amount_msat amount, bool is_credit) { return new_chain_coin_mvt(ctx, account_name, txid, - out_txid, vout, NULL, + outpoint, NULL, blockheight, JOURNAL, amount, is_credit); } struct chain_coin_mvt *new_coin_deposit(const tal_t *ctx, const char *account_name, - const struct bitcoin_txid *txid, - u32 vout, u32 blockheight, + const struct bitcoin_outpoint *outpoint, + u32 blockheight, struct amount_msat amount) { - return new_chain_coin_mvt(ctx, account_name, txid, txid, - vout, NULL, blockheight, DEPOSIT, + /* FIXME: Why dup txid here? */ + return new_chain_coin_mvt(ctx, account_name, &outpoint->txid, outpoint, + NULL, blockheight, DEPOSIT, amount, true); } struct chain_coin_mvt *new_coin_deposit_sat(const tal_t *ctx, const char *account_name, - const struct bitcoin_txid *txid, - u32 vout, + const struct bitcoin_outpoint *outpoint, u32 blockheight, struct amount_sat amount) { @@ -215,14 +210,13 @@ struct chain_coin_mvt *new_coin_deposit_sat(const tal_t *ctx, ok = amount_sat_to_msat(&amt_msat, amount); assert(ok); - return new_coin_deposit(ctx, account_name, txid, - vout, blockheight, amt_msat); + return new_coin_deposit(ctx, account_name, outpoint, + blockheight, amt_msat); } struct chain_coin_mvt *new_coin_penalty_sat(const tal_t *ctx, const char *account_name, const struct bitcoin_txid *txid, - const struct bitcoin_txid *out_txid, - u32 vout, + const struct bitcoin_outpoint *outpoint, u32 blockheight, struct amount_sat amount) { @@ -233,8 +227,7 @@ struct chain_coin_mvt *new_coin_penalty_sat(const tal_t *ctx, assert(ok); return new_chain_coin_mvt(ctx, account_name, - txid, out_txid, - vout, NULL, + txid, outpoint, NULL, blockheight, PENALTY, amt_msat, false); } @@ -242,15 +235,14 @@ struct chain_coin_mvt *new_coin_penalty_sat(const tal_t *ctx, struct chain_coin_mvt *new_coin_onchain_htlc_sat(const tal_t *ctx, const char *account_name, const struct bitcoin_txid *txid, - const struct bitcoin_txid *out_txid, - u32 vout, + const struct bitcoin_outpoint *outpoint, struct sha256 payment_hash, u32 blockheight, struct amount_sat amount, bool is_credit) { return new_chain_coin_mvt_sat(ctx, account_name, - txid, out_txid, vout, + txid, outpoint, take(tal_dup(NULL, struct sha256, &payment_hash)), blockheight, ONCHAIN_HTLC, amount, is_credit); @@ -262,17 +254,17 @@ struct chain_coin_mvt *new_coin_pushed(const tal_t *ctx, u32 blockheight, struct amount_msat amount) { - return new_chain_coin_mvt(ctx, account_name, txid, NULL, 0, + return new_chain_coin_mvt(ctx, account_name, txid, NULL, NULL, blockheight, PUSHED, amount, false); } struct chain_coin_mvt *new_coin_spend_track(const tal_t *ctx, const struct bitcoin_txid *txid, - const struct bitcoin_txid *out_txid, - u32 vout, u32 blockheight) + const struct bitcoin_outpoint *outpoint, + u32 blockheight) { - return new_chain_coin_mvt_sat(ctx, "wallet", txid, out_txid, vout, + return new_chain_coin_mvt_sat(ctx, "wallet", txid, outpoint, NULL, blockheight, SPEND_TRACK, AMOUNT_SAT(0), false); } @@ -292,8 +284,7 @@ struct coin_mvt *finalize_chain_mvt(const tal_t *ctx, mvt->type = CHAIN_MVT; mvt->id.tx_txid = chain_mvt->tx_txid; - mvt->id.output_txid = chain_mvt->output_txid; - mvt->id.vout = chain_mvt->vout; + mvt->id.outpoint = chain_mvt->outpoint; mvt->id.payment_hash = chain_mvt->payment_hash; mvt->tag = chain_mvt->tag; mvt->credit = chain_mvt->credit; @@ -322,8 +313,7 @@ struct coin_mvt *finalize_channel_mvt(const tal_t *ctx, mvt->id.payment_hash = chan_mvt->payment_hash; mvt->id.part_id = chan_mvt->part_id; mvt->id.tx_txid = NULL; - mvt->id.output_txid = NULL; - mvt->id.vout = 0; + mvt->id.outpoint = NULL; mvt->tag = chan_mvt->tag; mvt->credit = chan_mvt->credit; mvt->debit = chan_mvt->debit; @@ -346,12 +336,11 @@ void towire_chain_coin_mvt(u8 **pptr, const struct chain_coin_mvt *mvt) towire_u16(pptr, 0); towire_bitcoin_txid(pptr, cast_const(struct bitcoin_txid *, mvt->tx_txid)); - if (mvt->output_txid) { + if (mvt->outpoint) { towire_bool(pptr, true); - towire_bitcoin_txid(pptr, cast_const(struct bitcoin_txid *, mvt->output_txid)); + towire_bitcoin_outpoint(pptr, mvt->outpoint); } else towire_bool(pptr, false); - towire_u32(pptr, mvt->vout); if (mvt->payment_hash) { towire_bool(pptr, true); towire_sha256(pptr, mvt->payment_hash); @@ -378,12 +367,13 @@ void fromwire_chain_coin_mvt(const u8 **cursor, size_t *max, struct chain_coin_m fromwire_bitcoin_txid(cursor, max, cast_const(struct bitcoin_txid *, mvt->tx_txid)); if (fromwire_bool(cursor, max)) { - mvt->output_txid = tal(mvt, struct bitcoin_txid); - fromwire_bitcoin_txid(cursor, max, - cast_const(struct bitcoin_txid *, mvt->output_txid)); + /* Read into non-const version */ + struct bitcoin_outpoint *outpoint + = tal(mvt, struct bitcoin_outpoint); + fromwire_bitcoin_outpoint(cursor, max, outpoint); + mvt->outpoint = outpoint; } else - mvt->output_txid = NULL; - mvt->vout = fromwire_u32(cursor, max); + mvt->outpoint = NULL; if (fromwire_bool(cursor, max)) { mvt->payment_hash = tal(mvt, struct sha256); fromwire_sha256(cursor, max, mvt->payment_hash); diff --git a/common/coin_mvt.h b/common/coin_mvt.h index efda8ef90934..7c406c0f09ea 100644 --- a/common/coin_mvt.h +++ b/common/coin_mvt.h @@ -51,8 +51,7 @@ struct chain_coin_mvt { /* account_id */ const char *account_name; const struct bitcoin_txid *tx_txid; - const struct bitcoin_txid *output_txid; - u32 vout; + const struct bitcoin_outpoint *outpoint; /* some on-chain movements have a payment hash */ struct sha256 *payment_hash; @@ -74,8 +73,7 @@ struct mvt_id { struct sha256 *payment_hash; u64 *part_id; const struct bitcoin_txid *tx_txid; - const struct bitcoin_txid *output_txid; - u32 vout; + const struct bitcoin_outpoint *outpoint; }; struct coin_mvt { @@ -119,17 +117,15 @@ struct channel_coin_mvt *new_channel_coin_mvt(const tal_t *ctx, bool is_credit); struct chain_coin_mvt *new_coin_withdrawal(const tal_t *ctx, - const char *account_name, - const struct bitcoin_txid *tx_txid, - const struct bitcoin_txid *out_txid, - u32 vout, - u32 blockheight, - struct amount_msat amount); + const char *account_name, + const struct bitcoin_txid *tx_txid, + const struct bitcoin_outpoint *outpoint, + u32 blockheight, + struct amount_msat amount); struct chain_coin_mvt *new_coin_withdrawal_sat(const tal_t *ctx, const char *account_name, const struct bitcoin_txid *tx_txid, - const struct bitcoin_txid *out_txid, - u32 vout, + const struct bitcoin_outpoint *outpoint, u32 blockheight, struct amount_sat amount); struct chain_coin_mvt *new_coin_chain_fees(const tal_t *ctx, @@ -145,43 +141,39 @@ struct chain_coin_mvt *new_coin_chain_fees_sat(const tal_t *ctx, struct chain_coin_mvt *new_coin_journal_entry(const tal_t *ctx, const char *account_name, const struct bitcoin_txid *txid, - const struct bitcoin_txid *out_txid, - u32 vout, + const struct bitcoin_outpoint *outpoint, u32 blockheight, struct amount_msat amount, bool is_credit); struct chain_coin_mvt *new_coin_deposit(const tal_t *ctx, const char *account_name, - const struct bitcoin_txid *txid, - u32 vout, u32 blockheight, + const struct bitcoin_outpoint *outpoint, + u32 blockheight, struct amount_msat amount); struct chain_coin_mvt *new_coin_deposit_sat(const tal_t *ctx, const char *account_name, - const struct bitcoin_txid *txid, - u32 vout, + const struct bitcoin_outpoint *outpoint, u32 blockheight, struct amount_sat amount); struct chain_coin_mvt *new_coin_penalty_sat(const tal_t *ctx, const char *account_name, const struct bitcoin_txid *txid, - const struct bitcoin_txid *out_txid, - u32 vout, + const struct bitcoin_outpoint *outpoint, u32 blockheight, struct amount_sat amount); struct chain_coin_mvt *new_coin_onchain_htlc_sat(const tal_t *ctx, const char *account_name, const struct bitcoin_txid *txid, - const struct bitcoin_txid *out_txid, - u32 vout, + const struct bitcoin_outpoint *outpoint, struct sha256 payment_hash, u32 blockheight, struct amount_sat amount, bool is_credit); struct chain_coin_mvt *new_coin_spend_track(const tal_t *ctx, const struct bitcoin_txid *txid, - const struct bitcoin_txid *out_txid, - u32 vout, u32 blockheight); + const struct bitcoin_outpoint *outpoint, + u32 blockheight); struct chain_coin_mvt *new_coin_pushed(const tal_t *ctx, const char *account_name, const struct bitcoin_txid *txid, diff --git a/common/htlc_tx.c b/common/htlc_tx.c index d3569f38e6da..53ec9ab13a1f 100644 --- a/common/htlc_tx.c +++ b/common/htlc_tx.c @@ -5,8 +5,7 @@ static struct bitcoin_tx *htlc_tx(const tal_t *ctx, const struct chainparams *chainparams, - const struct bitcoin_txid *commit_txid, - unsigned int commit_output_number, + const struct bitcoin_outpoint *commit, const u8 *commit_wscript, struct amount_msat msat, u16 to_self_delay, @@ -46,7 +45,7 @@ static struct bitcoin_tx *htlc_tx(const tal_t *ctx, * * `txin[0]` sequence: `0` (set to `1` for `option_anchors`) */ amount = amount_msat_to_sat_round_down(msat); - bitcoin_tx_add_input(tx, commit_txid, commit_output_number, + bitcoin_tx_add_input(tx, commit, option_anchor_outputs ? 1 : 0, NULL, amount, NULL, commit_wscript); @@ -75,8 +74,7 @@ static struct bitcoin_tx *htlc_tx(const tal_t *ctx, struct bitcoin_tx *htlc_success_tx(const tal_t *ctx, const struct chainparams *chainparams, - const struct bitcoin_txid *commit_txid, - unsigned int commit_output_number, + const struct bitcoin_outpoint *commit, const u8 *commit_wscript, struct amount_msat htlc_msatoshi, u16 to_self_delay, @@ -87,7 +85,7 @@ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx, /* BOLT #3: * * locktime: `0` for HTLC-success, `cltv_expiry` for HTLC-timeout */ - return htlc_tx(ctx, chainparams, commit_txid, commit_output_number, + return htlc_tx(ctx, chainparams, commit, commit_wscript, htlc_msatoshi, to_self_delay, &keyset->self_revocation_key, @@ -128,8 +126,7 @@ void htlc_success_tx_add_witness(struct bitcoin_tx *htlc_success, struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx, const struct chainparams *chainparams, - const struct bitcoin_txid *commit_txid, - unsigned int commit_output_number, + const struct bitcoin_outpoint *commit, const u8 *commit_wscript, struct amount_msat htlc_msatoshi, u32 cltv_expiry, @@ -141,7 +138,7 @@ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx, /* BOLT #3: * * locktime: `0` for HTLC-success, `cltv_expiry` for HTLC-timeout */ - return htlc_tx(ctx, chainparams, commit_txid, commit_output_number, + return htlc_tx(ctx, chainparams, commit, commit_wscript, htlc_msatoshi, to_self_delay, &keyset->self_revocation_key, &keyset->self_delayed_payment_key, diff --git a/common/htlc_tx.h b/common/htlc_tx.h index 6ffea256c091..f982757eaa1a 100644 --- a/common/htlc_tx.h +++ b/common/htlc_tx.h @@ -6,7 +6,7 @@ #include struct bitcoin_signature; -struct bitcoin_txid; +struct bitcoin_outpoint; struct keyset; struct preimage; struct pubkey; @@ -82,8 +82,7 @@ static inline struct amount_sat htlc_success_fee(u32 feerate_per_kw, * output; doesn't fill in input witness. */ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx, const struct chainparams *chainparams, - const struct bitcoin_txid *commit_txid, - unsigned int commit_output_number, + const struct bitcoin_outpoint *commit, const u8 *commit_wscript, struct amount_msat htlc_msatoshi, u16 to_self_delay, @@ -106,8 +105,7 @@ void htlc_success_tx_add_witness(struct bitcoin_tx *htlc_success, * output; doesn't fill in input witness. */ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx, const struct chainparams *chainparams, - const struct bitcoin_txid *commit_txid, - unsigned int commit_output_number, + const struct bitcoin_outpoint *commit, const u8 *commit_wscript, struct amount_msat htlc_msatoshi, u32 cltv_expiry, diff --git a/common/initial_channel.c b/common/initial_channel.c index 28c99ff058c1..cae1ad140201 100644 --- a/common/initial_channel.c +++ b/common/initial_channel.c @@ -12,12 +12,11 @@ struct channel *new_initial_channel(const tal_t *ctx, const struct channel_id *cid, - const struct bitcoin_txid *funding_txid, - unsigned int funding_txout, + const struct bitcoin_outpoint *funding, u32 minimum_depth, const struct height_states *height_states TAKES, u32 lease_expiry, - struct amount_sat funding, + struct amount_sat funding_sats, struct amount_msat local_msatoshi, const struct fee_states *fee_states TAKES, const struct channel_config *local, @@ -34,13 +33,12 @@ struct channel *new_initial_channel(const tal_t *ctx, struct amount_msat remote_msatoshi; channel->cid = *cid; - channel->funding_txid = *funding_txid; - channel->funding_txout = funding_txout; - channel->funding = funding; + channel->funding = *funding; + channel->funding_sats = funding_sats; channel->minimum_depth = minimum_depth; channel->lease_expiry = lease_expiry; if (!amount_sat_sub_msat(&remote_msatoshi, - channel->funding, local_msatoshi)) + channel->funding_sats, local_msatoshi)) return tal_free(channel); channel->opener = opener; @@ -120,9 +118,8 @@ struct bitcoin_tx *initial_channel_tx(const tal_t *ctx, &channel->funding_pubkey[side], &channel->funding_pubkey[!side]); - init_tx = initial_commit_tx(ctx, &channel->funding_txid, - channel->funding_txout, - channel->funding, + init_tx = initial_commit_tx(ctx, &channel->funding, + channel->funding_sats, channel->funding_pubkey, channel->opener, /* They specify our to_self_delay and v.v. */ @@ -203,7 +200,7 @@ static char *fmt_channel(const tal_t *ctx, const struct channel *channel) " local=%s," " remote=%s }", type_to_string(tmpctx, struct amount_sat, - &channel->funding), + &channel->funding_sats), side_to_str(channel->opener), fmt_channel_view(ctx, &channel->view[LOCAL]), fmt_channel_view(ctx, &channel->view[REMOTE])); diff --git a/common/initial_channel.h b/common/initial_channel.h index 7dc75eade2b3..713d55f5fc76 100644 --- a/common/initial_channel.h +++ b/common/initial_channel.h @@ -26,14 +26,13 @@ struct channel { struct channel_id cid; /* Funding txid and output. */ - struct bitcoin_txid funding_txid; - unsigned int funding_txout; + struct bitcoin_outpoint funding; /* Keys used to spend funding tx. */ struct pubkey funding_pubkey[NUM_SIDES]; /* satoshis in from commitment tx */ - struct amount_sat funding; + struct amount_sat funding_sats; /* confirmations needed for locking funding */ u32 minimum_depth; @@ -77,12 +76,11 @@ struct channel { * new_initial_channel: Given initial fees and funding, what is initial state? * @ctx: tal context to allocate return value from. * @cid: The channel's id. - * @funding_txid: The commitment transaction id. - * @funding_txout: The commitment transaction output number. + * @funding: The commitment transaction id/outnum * @minimum_depth: The minimum confirmations needed for funding transaction. * @height_states: The blockheight update states. * @lease_expiry: Block the lease expires. - * @funding_satoshis: The commitment transaction amount. + * @funding_sats: The commitment transaction amount. * @local_msatoshi: The amount for the local side (remainder goes to remote) * @fee_states: The fee update states. * @local: local channel configuration @@ -99,12 +97,11 @@ struct channel { */ struct channel *new_initial_channel(const tal_t *ctx, const struct channel_id *cid, - const struct bitcoin_txid *funding_txid, - unsigned int funding_txout, + const struct bitcoin_outpoint *funding, u32 minimum_depth, const struct height_states *height_states TAKES, u32 lease_expiry, - struct amount_sat funding, + struct amount_sat funding_sats, struct amount_msat local_msatoshi, const struct fee_states *fee_states TAKES, const struct channel_config *local, diff --git a/common/initial_commit_tx.c b/common/initial_commit_tx.c index 347a6dd969c1..b2c9e956d06e 100644 --- a/common/initial_commit_tx.c +++ b/common/initial_commit_tx.c @@ -71,9 +71,8 @@ void tx_add_anchor_output(struct bitcoin_tx *tx, } struct bitcoin_tx *initial_commit_tx(const tal_t *ctx, - const struct bitcoin_txid *funding_txid, - unsigned int funding_txout, - struct amount_sat funding, + const struct bitcoin_outpoint *funding, + struct amount_sat funding_sats, const struct pubkey funding_key[NUM_SIDES], enum side opener, u16 to_self_delay, @@ -107,7 +106,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx, if (!amount_msat_add(&total_pay, self_pay, other_pay)) abort(); - assert(!amount_msat_greater_sat(total_pay, funding)); + assert(!amount_msat_greater_sat(total_pay, funding_sats)); /* BOLT #3: * @@ -319,8 +318,8 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx, * * `txin[0]` script bytes: 0 */ sequence = (0x80000000 | ((obscured_commitment_number>>24) & 0xFFFFFF)); - bitcoin_tx_add_input(tx, funding_txid, funding_txout, sequence, - NULL, funding, NULL, funding_wscript); + bitcoin_tx_add_input(tx, funding, sequence, + NULL, funding_sats, NULL, funding_wscript); if (direct_outputs != NULL) { direct_outputs[LOCAL] = direct_outputs[REMOTE] = NULL; diff --git a/common/initial_commit_tx.h b/common/initial_commit_tx.h index c5b6bca12990..798c5ac4a594 100644 --- a/common/initial_commit_tx.h +++ b/common/initial_commit_tx.h @@ -7,7 +7,7 @@ #include #include -struct bitcoin_txid; +struct bitcoin_outpoint; struct keyset; struct wally_tx_output; @@ -84,7 +84,7 @@ static inline struct amount_sat commit_tx_base_fee(u32 feerate_per_kw, /** * initial_commit_tx: create (unsigned) commitment tx to spend the funding tx output * @ctx: context to allocate transaction and @htlc_map from. - * @funding_txid, @funding_out, @funding: funding outpoint. + * @funding, @funding_sats: funding outpoint and amount * @funding_wscript: scriptPubkey of the funding output * @funding_keys: funding bitcoin keys * @opener: is the LOCAL or REMOTE paying the fee? @@ -105,9 +105,8 @@ static inline struct amount_sat commit_tx_base_fee(u32 feerate_per_kw, * transaction, so we carefully use the terms "self" and "other" here. */ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx, - const struct bitcoin_txid *funding_txid, - unsigned int funding_txout, - struct amount_sat funding, + const struct bitcoin_outpoint *funding, + struct amount_sat funding_sats, const struct pubkey funding_key[NUM_SIDES], enum side opener, u16 to_self_delay, diff --git a/common/psbt_open.c b/common/psbt_open.c index 5ed339f0fd0f..b7a6f330c9ee 100644 --- a/common/psbt_open.c +++ b/common/psbt_open.c @@ -99,11 +99,11 @@ static const u8 *linearize_output(const tal_t *ctx, { struct wally_psbt *psbt = create_psbt(NULL, 1, 1, 0); size_t byte_len; - struct bitcoin_txid txid; + struct bitcoin_outpoint outpoint; /* Add a 'fake' input so this will linearize the tx */ - memset(&txid, 0, sizeof(txid)); - psbt_append_input(psbt, &txid, 0, 0, NULL, NULL, NULL); + memset(&outpoint, 0, sizeof(outpoint)); + psbt_append_input(psbt, &outpoint, 0, NULL, NULL, NULL); tal_wally_start(); if (wally_tx_add_output(psbt->tx, tx_out) != WALLY_OK) diff --git a/common/test/run-psbt_diff.c b/common/test/run-psbt_diff.c index 4aebab49cb2c..9312010d6237 100644 --- a/common/test/run-psbt_diff.c +++ b/common/test/run-psbt_diff.c @@ -92,14 +92,14 @@ static void add_in_out_with_serial(struct wally_psbt *psbt, size_t serial_id, size_t default_value) { - struct bitcoin_txid txid; + struct bitcoin_outpoint outpoint; u8 *script; struct amount_sat sat; struct wally_psbt_input *in; struct wally_psbt_output *out; - memset(&txid, default_value, sizeof(txid)); - in = psbt_append_input(psbt, &txid, default_value, default_value, + memset(&outpoint, default_value, sizeof(outpoint)); + in = psbt_append_input(psbt, &outpoint, default_value, NULL, NULL, NULL); if (!in) abort(); diff --git a/common/utxo.c b/common/utxo.c index 72da524216de..ba1fb2863cb0 100644 --- a/common/utxo.c +++ b/common/utxo.c @@ -7,8 +7,7 @@ void towire_utxo(u8 **pptr, const struct utxo *utxo) /* Is this a unilateral close output and needs the * close_info? */ bool is_unilateral_close = utxo->close_info != NULL; - towire_bitcoin_txid(pptr, &utxo->txid); - towire_u32(pptr, utxo->outnum); + towire_bitcoin_outpoint(pptr, &utxo->outpoint); towire_amount_sat(pptr, utxo->amount); towire_u32(pptr, utxo->keyindex); towire_bool(pptr, utxo->is_p2sh); @@ -32,8 +31,7 @@ struct utxo *fromwire_utxo(const tal_t *ctx, const u8 **ptr, size_t *max) { struct utxo *utxo = tal(ctx, struct utxo); - fromwire_bitcoin_txid(ptr, max, &utxo->txid); - utxo->outnum = fromwire_u32(ptr, max); + fromwire_bitcoin_outpoint(ptr, max, &utxo->outpoint); utxo->amount = fromwire_amount_sat(ptr, max); utxo->keyindex = fromwire_u32(ptr, max); utxo->is_p2sh = fromwire_bool(ptr, max); diff --git a/common/utxo.h b/common/utxo.h index 415bdd80c816..e175a36e0e14 100644 --- a/common/utxo.h +++ b/common/utxo.h @@ -32,8 +32,7 @@ enum output_status { }; struct utxo { - struct bitcoin_txid txid; - u32 outnum; + struct bitcoin_outpoint outpoint; struct amount_sat amount; u32 keyindex; bool is_p2sh; diff --git a/devtools/mkclose.c b/devtools/mkclose.c index b9d9f7abd7d8..eb2ada40d6df 100644 --- a/devtools/mkclose.c +++ b/devtools/mkclose.c @@ -50,8 +50,7 @@ int main(int argc, char *argv[]) struct pubkey funding_pubkey[NUM_SIDES], outkey[NUM_SIDES]; struct privkey funding_privkey[NUM_SIDES]; struct amount_sat funding_amount; - struct bitcoin_txid funding_txid; - unsigned int funding_outnum; + struct bitcoin_outpoint funding; u32 feerate_per_kw; struct amount_sat fee; struct bitcoin_signature local_sig, remote_sig; @@ -81,10 +80,10 @@ int main(int argc, char *argv[]) argnum = 1; if (!bitcoin_txid_from_hex(argv[argnum], - strlen(argv[argnum]), &funding_txid)) + strlen(argv[argnum]), &funding.txid)) errx(1, "Bad funding-txid"); argnum++; - funding_outnum = atoi(argv[argnum++]); + funding.n = atoi(argv[argnum++]); if (!parse_amount_sat(&funding_amount, argv[argnum], strlen(argv[argnum]))) errx(1, "Bad funding-amount"); argnum++; @@ -165,7 +164,7 @@ int main(int argc, char *argv[]) tal_hex(NULL, funding_wscript)); /* Our input spends the anchor tx output. */ - bitcoin_tx_add_input(tx, &funding_txid, funding_outnum, + bitcoin_tx_add_input(tx, &funding, BITCOIN_TX_DEFAULT_SEQUENCE, NULL, funding_amount, NULL, funding_wscript); diff --git a/devtools/mkcommit.c b/devtools/mkcommit.c index 0493822306d9..2c3cdeada08f 100644 --- a/devtools/mkcommit.c +++ b/devtools/mkcommit.c @@ -248,8 +248,7 @@ int main(int argc, char *argv[]) u64 commitnum; struct amount_sat funding_amount; struct channel_id cid; - struct bitcoin_txid funding_txid; - unsigned int funding_outnum; + struct bitcoin_outpoint funding; u32 feerate_per_kw; struct pubkey local_per_commit_point, remote_per_commit_point; struct bitcoin_signature local_sig, remote_sig; @@ -313,10 +312,10 @@ int main(int argc, char *argv[]) argnum = 1; commitnum = atol(argv[argnum++]); if (!bitcoin_txid_from_hex(argv[argnum], - strlen(argv[argnum]), &funding_txid)) + strlen(argv[argnum]), &funding.txid)) errx(1, "Bad funding-txid"); argnum++; - funding_outnum = atoi(argv[argnum++]); + funding.n = atoi(argv[argnum++]); if (!parse_amount_sat(&funding_amount, argv[argnum], strlen(argv[argnum]))) errx(1, "Bad funding-amount"); argnum++; @@ -387,7 +386,7 @@ int main(int argc, char *argv[]) &remotebase, &funding_remotekey, commitnum); /* FIXME: option for v2? */ - derive_channel_id(&cid, &funding_txid, funding_outnum); + derive_channel_id(&cid, &funding); if (option_anchor_outputs) channel_type = channel_type_anchor_outputs(NULL); @@ -398,7 +397,7 @@ int main(int argc, char *argv[]) channel = new_full_channel(NULL, &cid, - &funding_txid, funding_outnum, 1, + &funding, 1, take(new_height_states(NULL, fee_payer, &blockheight)), 0, /* Defaults to no lease */ diff --git a/devtools/mkfunding.c b/devtools/mkfunding.c index c4e2da8d5586..0eba19538035 100644 --- a/devtools/mkfunding.c +++ b/devtools/mkfunding.c @@ -42,7 +42,7 @@ static struct bitcoin_tx *tx_spending_utxo(const tal_t *ctx, nlocktime); assert(!utxo->is_p2sh); - bitcoin_tx_add_input(tx, &utxo->txid, utxo->outnum, + bitcoin_tx_add_input(tx, &utxo->outpoint, nsequence, NULL, utxo->amount, utxo->scriptPubkey, NULL); @@ -99,10 +99,10 @@ int main(int argc, char *argv[]) argnum = 1; if (!bitcoin_txid_from_hex(argv[argnum], - strlen(argv[argnum]), &input.txid)) + strlen(argv[argnum]), &input.outpoint.txid)) errx(1, "Bad input-txid"); argnum++; - input.outnum = atoi(argv[argnum++]); + input.outpoint.n = atoi(argv[argnum++]); if (!parse_amount_sat(&input.amount, argv[argnum], strlen(argv[argnum]))) errx(1, "Bad input-amount"); argnum++; diff --git a/hsmd/libhsmd.c b/hsmd/libhsmd.c index 8a358bcc8dd2..c06db8d4b0b3 100644 --- a/hsmd/libhsmd.c +++ b/hsmd/libhsmd.c @@ -375,7 +375,7 @@ static void sign_our_inputs(struct utxo **utxos, struct wally_psbt *psbt) struct pubkey pubkey; if (!wally_tx_input_spends(&psbt->tx->inputs[j], - &utxo->txid, utxo->outnum)) + &utxo->outpoint)) continue; hsm_key_for_utxo(&privkey, &pubkey, utxo); diff --git a/lightningd/bitcoind.c b/lightningd/bitcoind.c index 1c67914b54c7..2a6e41689865 100644 --- a/lightningd/bitcoind.c +++ b/lightningd/bitcoind.c @@ -543,7 +543,7 @@ static void getutxout_callback(const char *buf, const jsmntok_t *toks, } void bitcoind_getutxout_(struct bitcoind *bitcoind, - const struct bitcoin_txid *txid, const u32 outnum, + const struct bitcoin_outpoint *outpoint, void (*cb)(struct bitcoind *bitcoind, const struct bitcoin_tx_output *txout, void *arg), @@ -558,8 +558,8 @@ void bitcoind_getutxout_(struct bitcoind *bitcoind, req = jsonrpc_request_start(bitcoind, "getutxout", bitcoind->log, NULL, getutxout_callback, call); - json_add_txid(req->stream, "txid", txid); - json_add_num(req->stream, "vout", outnum); + json_add_txid(req->stream, "txid", &outpoint->txid); + json_add_num(req->stream, "vout", outpoint->n); jsonrpc_request_end(req); bitcoin_plugin_send(bitcoind, req); } @@ -599,7 +599,7 @@ process_getfilteredblock_step2(struct bitcoind *bitcoind, call->current_outpoint++; if (call->current_outpoint < tal_count(call->outpoints)) { o = call->outpoints[call->current_outpoint]; - bitcoind_getutxout(bitcoind, &o->txid, o->outnum, + bitcoind_getutxout(bitcoind, &o->outpoint, process_getfilteredblock_step2, call); } else { /* If there were no more outpoints to check, we call the callback. */ @@ -645,10 +645,10 @@ static void process_getfilteredblock_step1(struct bitcoind *bitcoind, if (amount_asset_is_main(&amount) && is_p2wsh(script, NULL)) { /* This is an interesting output, remember it. */ o = tal(call->outpoints, struct filteredblock_outpoint); - bitcoin_txid(tx, &o->txid); + bitcoin_txid(tx, &o->outpoint.txid); + o->outpoint.n = j; o->amount = amount_asset_to_sat(&amount); o->txindex = i; - o->outnum = j; o->scriptPubKey = tal_steal(o, script); tal_arr_expand(&call->outpoints, o); } else { @@ -667,7 +667,7 @@ static void process_getfilteredblock_step1(struct bitcoind *bitcoind, * store the one's that are unspent in * call->result->outpoints. */ o = call->outpoints[call->current_outpoint]; - bitcoind_getutxout(bitcoind, &o->txid, o->outnum, + bitcoind_getutxout(bitcoind, &o->outpoint, process_getfilteredblock_step2, call); } } diff --git a/lightningd/bitcoind.h b/lightningd/bitcoind.h index 1e04fb6835c5..ef3f1876e6b5 100644 --- a/lightningd/bitcoind.h +++ b/lightningd/bitcoind.h @@ -39,8 +39,7 @@ struct bitcoind { /* A single outpoint in a filtered block */ struct filteredblock_outpoint { - struct bitcoin_txid txid; - u32 outnum; + struct bitcoin_outpoint outpoint; u32 txindex; const u8 *scriptPubKey; struct amount_sat amount; @@ -150,13 +149,13 @@ void bitcoind_getrawblockbyheight_(struct bitcoind *bitcoind, (arg)) void bitcoind_getutxout_(struct bitcoind *bitcoind, - const struct bitcoin_txid *txid, const u32 outnum, + const struct bitcoin_outpoint *outpoint, void (*cb)(struct bitcoind *bitcoind, const struct bitcoin_tx_output *txout, void *arg), void *arg); -#define bitcoind_getutxout(bitcoind_, txid_, vout_, cb, arg) \ - bitcoind_getutxout_((bitcoind_), (txid_), (vout_), \ +#define bitcoind_getutxout(bitcoind_, outpoint_, cb, arg) \ + bitcoind_getutxout_((bitcoind_), (outpoint_), \ typesafe_cb_preargs(void, void *, \ (cb), (arg), \ struct bitcoind *, \ diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index 09702f179c17..e3a9899ba78a 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -299,10 +299,11 @@ static void watch_for_utxo_reconfirmation(struct chain_topology *topo, assert(unconfirmed[i]->close_info != NULL); assert(unconfirmed[i]->blockheight == NULL); - if (find_txwatch(topo, &unconfirmed[i]->txid, NULL)) + if (find_txwatch(topo, &unconfirmed[i]->outpoint.txid, NULL)) continue; - notleak(watch_txid(topo, topo, NULL, &unconfirmed[i]->txid, + notleak(watch_txid(topo, topo, NULL, + &unconfirmed[i]->outpoint.txid, closeinfo_txid_confirmed)); } } @@ -654,25 +655,24 @@ static void updates_complete(struct chain_topology *topo) static void record_utxo_spent(struct lightningd *ld, const struct bitcoin_txid *txid, - const struct bitcoin_txid *utxo_txid, - u32 vout, u32 blockheight, + const struct bitcoin_outpoint *outpoint, + u32 blockheight, struct amount_sat *input_amt) { struct utxo *utxo; struct chain_coin_mvt *mvt; u8 *ctx = tal(NULL, u8); - utxo = wallet_utxo_get(ctx, ld->wallet, utxo_txid, vout); + utxo = wallet_utxo_get(ctx, ld->wallet, outpoint); if (!utxo) { - log_broken(ld->log, "No record of utxo %s:%d", - type_to_string(tmpctx, struct bitcoin_txid, - utxo_txid), - vout); + log_broken(ld->log, "No record of utxo %s", + type_to_string(tmpctx, struct bitcoin_outpoint, + outpoint)); return; } *input_amt = utxo->amount; - mvt = new_coin_spend_track(ctx, txid, utxo_txid, vout, blockheight); + mvt = new_coin_spend_track(ctx, txid, outpoint, blockheight); notify_chain_mvt(ld, mvt); tal_free(ctx); } @@ -680,20 +680,23 @@ static void record_utxo_spent(struct lightningd *ld, static void record_outputs_as_withdraws(const tal_t *ctx, struct lightningd *ld, const struct bitcoin_tx *tx, - struct bitcoin_txid *txid, + const struct bitcoin_txid *txid, u32 blockheight) { struct chain_coin_mvt *mvt; - for (size_t i = 0; i < tx->wtx->num_outputs; i++) { + struct bitcoin_outpoint outpoint; + + outpoint.txid = *txid; + for (outpoint.n = 0; outpoint.n < tx->wtx->num_outputs; outpoint.n++) { struct amount_asset asset; struct amount_sat outval; - if (elements_tx_output_is_fee(tx, i)) + if (elements_tx_output_is_fee(tx, outpoint.n)) continue; - asset = bitcoin_tx_output_get_amount(tx, i); + asset = bitcoin_tx_output_get_amount(tx, outpoint.n); assert(amount_asset_is_main(&asset)); outval = amount_asset_to_sat(&asset); mvt = new_coin_withdrawal_sat(ctx, "wallet", txid, - txid, i, blockheight, + &outpoint, blockheight, outval); notify_chain_mvt(ld, mvt); } @@ -701,7 +704,7 @@ static void record_outputs_as_withdraws(const tal_t *ctx, static void record_tx_outs_and_fees(struct lightningd *ld, const struct bitcoin_tx *tx, - struct bitcoin_txid *txid, + const struct bitcoin_txid *txid, u32 blockheight, struct amount_sat inputs_total, bool our_tx) @@ -728,7 +731,7 @@ static void record_tx_outs_and_fees(struct lightningd *ld, /* We don't have detailed withdrawal info for this tx, * so we log the wallet withdrawal as a single entry */ mvt = new_coin_withdrawal_sat(ctx, "wallet", txid, NULL, - 0, blockheight, out_val); + blockheight, out_val); notify_chain_mvt(ld, mvt); goto log_fee; } @@ -763,23 +766,21 @@ static void topo_update_spends(struct chain_topology *topo, struct block *b) txid = b->txids[i]; for (size_t j = 0; j < tx->wtx->num_inputs; j++) { - const struct wally_tx_input *input = &tx->wtx->inputs[j]; - struct bitcoin_txid outpoint_txid; + struct bitcoin_outpoint outpoint; bool our_spend; - bitcoin_tx_input_get_txid(tx, j, &outpoint_txid); + bitcoin_tx_input_get_outpoint(tx, j, &outpoint); our_spend = wallet_outpoint_spend( - topo->ld->wallet, tmpctx, b->height, &outpoint_txid, - input->index); + topo->ld->wallet, tmpctx, b->height, &outpoint); our_tx &= our_spend; includes_our_spend |= our_spend; if (our_spend) { struct amount_sat input_amt; bool ok; - record_utxo_spent(topo->ld, &txid, &outpoint_txid, - input->index, b->height, &input_amt); + record_utxo_spent(topo->ld, &txid, &outpoint, + b->height, &input_amt); ok = amount_sat_add(&inputs_total, inputs_total, input_amt); assert(ok); } @@ -804,15 +805,21 @@ static void topo_add_utxos(struct chain_topology *topo, struct block *b) { for (size_t i = 0; i < tal_count(b->full_txs); i++) { const struct bitcoin_tx *tx = b->full_txs[i]; - for (size_t j = 0; j < tx->wtx->num_outputs; j++) { - if (tx->wtx->outputs[j].features & WALLY_TX_IS_COINBASE) + struct bitcoin_outpoint outpoint; + + bitcoin_txid(tx, &outpoint.txid); + for (outpoint.n = 0; + outpoint.n < tx->wtx->num_outputs; + outpoint.n++) { + if (tx->wtx->outputs[outpoint.n].features + & WALLY_TX_IS_COINBASE) continue; - const u8 *script = bitcoin_tx_output_get_script(tmpctx, tx, j); - struct amount_asset amt = bitcoin_tx_output_get_amount(tx, j); + const u8 *script = bitcoin_tx_output_get_script(tmpctx, tx, outpoint.n); + struct amount_asset amt = bitcoin_tx_output_get_amount(tx, outpoint.n); if (amount_asset_is_main(&amt) && is_p2wsh(script, NULL)) { - wallet_utxoset_add(topo->ld->wallet, tx, j, + wallet_utxoset_add(topo->ld->wallet, &outpoint, b->height, i, script, amount_asset_to_sat(&amt)); } diff --git a/lightningd/channel.c b/lightningd/channel.c index 3e6076d396a1..13b7ba8ed330 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -144,8 +144,7 @@ static void destroy_inflight(struct channel_inflight *inflight) struct channel_inflight * new_inflight(struct channel *channel, - const struct bitcoin_txid funding_txid, - u16 funding_outnum, + const struct bitcoin_outpoint *funding_outpoint, u32 funding_feerate, struct amount_sat total_funds, struct amount_sat our_funds, @@ -163,9 +162,8 @@ new_inflight(struct channel *channel, struct funding_info *funding = tal(inflight, struct funding_info); - funding->txid = funding_txid; + funding->outpoint = *funding_outpoint; funding->total_funds = total_funds; - funding->outnum = funding_outnum; funding->feerate = funding_feerate; funding->our_funds = our_funds; @@ -312,9 +310,8 @@ struct channel *new_channel(struct peer *peer, u64 dbid, u64 next_index_local, u64 next_index_remote, u64 next_htlc_id, - const struct bitcoin_txid *funding_txid, - u16 funding_outnum, - struct amount_sat funding, + const struct bitcoin_outpoint *funding, + struct amount_sat funding_sats, struct amount_msat push, struct amount_sat our_funds, bool remote_funding_locked, @@ -396,9 +393,8 @@ struct channel *new_channel(struct peer *peer, u64 dbid, channel->next_index[LOCAL] = next_index_local; channel->next_index[REMOTE] = next_index_remote; channel->next_htlc_id = next_htlc_id; - channel->funding_txid = *funding_txid; - channel->funding_outnum = funding_outnum; - channel->funding = funding; + channel->funding = *funding; + channel->funding_sats = funding_sats; channel->push = push; channel->our_funds = our_funds; channel->remote_funding_locked = remote_funding_locked; @@ -514,7 +510,7 @@ struct channel_inflight *channel_inflight_find(struct channel *channel, { struct channel_inflight *inflight; list_for_each(&channel->inflights, inflight, list) { - if (bitcoin_txid_eq(txid, &inflight->funding->txid)) + if (bitcoin_txid_eq(txid, &inflight->funding->outpoint.txid)) return inflight; } diff --git a/lightningd/channel.h b/lightningd/channel.h index ba0075f31727..76a73d5b47ae 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -19,8 +19,7 @@ struct billboard { }; struct funding_info { - struct bitcoin_txid txid; - u16 outnum; + struct bitcoin_outpoint outpoint; u32 feerate; struct amount_sat total_funds; @@ -117,10 +116,9 @@ struct channel { u64 next_index[NUM_SIDES]; u64 next_htlc_id; - /* Funding txid and amounts */ - struct bitcoin_txid funding_txid; - u16 funding_outnum; - struct amount_sat funding; + /* Funding outpoint and amount */ + struct bitcoin_outpoint funding; + struct amount_sat funding_sats; /* Our original funds, in funding amount */ struct amount_sat our_funds; @@ -258,9 +256,8 @@ struct channel *new_channel(struct peer *peer, u64 dbid, u64 next_index_local, u64 next_index_remote, u64 next_htlc_id, - const struct bitcoin_txid *funding_txid, - u16 funding_outnum, - struct amount_sat funding, + const struct bitcoin_outpoint *funding, + struct amount_sat funding_sats, struct amount_msat push, struct amount_sat our_funds, bool remote_funding_locked, @@ -310,10 +307,9 @@ struct channel *new_channel(struct peer *peer, u64 dbid, /* new_inflight - Create a new channel_inflight for a channel */ struct channel_inflight * new_inflight(struct channel *channel, - const struct bitcoin_txid funding_txid, - u16 funding_outnum, + const struct bitcoin_outpoint *funding_outpoint, u32 funding_feerate, - struct amount_sat funding, + struct amount_sat funding_sat, struct amount_sat our_funds, struct wally_psbt *funding_psbt STEALS, struct bitcoin_tx *last_tx STEALS, diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index 66d960929502..ea169e304e9d 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -138,10 +138,11 @@ void channel_record_open(struct channel *channel) /* FIXME: logic here will change for dual funded channels */ if (channel->opener == LOCAL) { - if (!amount_sat_to_msat(&channel_open_amt, channel->funding)) + if (!amount_sat_to_msat(&channel_open_amt, + channel->funding_sats)) fatal("Unable to convert funding %s to msat", type_to_string(tmpctx, struct amount_sat, - &channel->funding)); + &channel->funding_sats)); /* if we pushed sats, we should decrement that * from the channel balance */ @@ -150,7 +151,7 @@ void channel_record_open(struct channel *channel) type_to_string(tmpctx, struct channel_id, &channel->cid), - &channel->funding_txid, + &channel->funding.txid, blockheight, channel->push); notify_chain_mvt(channel->peer->ld, mvt); } @@ -164,8 +165,7 @@ void channel_record_open(struct channel *channel) mvt = new_coin_deposit(ctx, type_to_string(tmpctx, struct channel_id, &channel->cid), - &channel->funding_txid, - channel->funding_outnum, + &channel->funding, blockheight, channel_open_amt); notify_chain_mvt(channel->peer->ld, mvt); tal_free(ctx); @@ -648,9 +648,8 @@ void peer_start_channeld(struct channel *channel, chainparams, ld->our_features, &channel->cid, - &channel->funding_txid, - channel->funding_outnum, - channel->funding, + &channel->funding, + channel->funding_sats, channel->minimum_depth, get_block_height(ld->topology), channel->blockheight_states, @@ -858,7 +857,7 @@ void channel_notify_new_block(struct lightningd *ld, "loss of funds.", block_height - channel->first_blocknum, type_to_string(tmpctx, struct bitcoin_txid, - &channel->funding_txid)); + &channel->funding.txid)); /* FIXME: Send an error packet for this case! */ /* And forget it. */ delete_channel(channel); @@ -967,7 +966,7 @@ struct command_result *cancel_channel_before_broadcast(struct command *cmd, * type into DB before broadcast). */ enum wallet_tx_type type; if (wallet_transaction_type(cmd->ld->wallet, - &cancel_channel->funding_txid, + &cancel_channel->funding.txid, &type)) return command_fail(cmd, FUNDING_CANCEL_NOT_SAFE, "Has the funding transaction been" @@ -991,8 +990,7 @@ struct command_result *cancel_channel_before_broadcast(struct command *cmd, * is broadcast by external wallet and the transaction hasn't * been onchain. */ bitcoind_getutxout(cmd->ld->topology->bitcoind, - &cancel_channel->funding_txid, - cancel_channel->funding_outnum, + &cancel_channel->funding, process_check_funding_broadcast, notleak(tal_steal(NULL, cc))); return command_still_pending(cmd); diff --git a/lightningd/closing_control.c b/lightningd/closing_control.c index 0adf12ad6eab..eef5e921cfc3 100644 --- a/lightningd/closing_control.c +++ b/lightningd/closing_control.c @@ -197,8 +197,8 @@ static bool closing_fee_is_acceptable(struct lightningd *ld, bool feerate_unknown; /* Calculate actual fee (adds in eliminated outputs) */ - fee = calc_tx_fee(channel->funding, tx); - last_fee = calc_tx_fee(channel->funding, channel->last_tx); + fee = calc_tx_fee(channel->funding_sats, tx); + last_fee = calc_tx_fee(channel->funding_sats, channel->last_tx); log_debug(channel->log, "Their actual closing tx fee is %s" " vs previous %s", @@ -421,7 +421,7 @@ void peer_start_closingd(struct channel *channel, if (!*max_feerate) *max_feerate = final_commit_feerate; /* No other limit on fees */ - feelimit = channel->funding; + feelimit = channel->funding_sats; } else max_feerate = NULL; @@ -440,10 +440,10 @@ void peer_start_closingd(struct channel *channel, */ /* What is not ours is theirs */ if (!amount_sat_sub_msat(&their_msat, - channel->funding, channel->our_msat)) { + channel->funding_sats, channel->our_msat)) { log_broken(channel->log, "our_msat overflow funding %s minus %s", type_to_string(tmpctx, struct amount_sat, - &channel->funding), + &channel->funding_sats), type_to_string(tmpctx, struct amount_msat, &channel->our_msat)); channel_fail_permanent(channel, @@ -456,9 +456,8 @@ void peer_start_closingd(struct channel *channel, chainparams, pps, &channel->cid, - &channel->funding_txid, - channel->funding_outnum, - channel->funding, + &channel->funding, + channel->funding_sats, &channel->local_funding_pubkey, &channel->channel_info.remote_fundingkey, channel->opener, diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index ea490748d5c5..5fdf7d5b19f4 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -932,13 +932,13 @@ openchannel2_sign_hook_cb(struct openchannel2_psbt_payload *payload STEALS) /* Check that we've got the same / correct PSBT */ psbt_txid(NULL, payload->psbt, &txid, NULL); - if (!bitcoin_txid_eq(&inflight->funding->txid, &txid)) { + if (!bitcoin_txid_eq(&inflight->funding->outpoint.txid, &txid)) { log_broken(channel->log, "PSBT's txid does not match. %s != %s", type_to_string(tmpctx, struct bitcoin_txid, &txid), type_to_string(tmpctx, struct bitcoin_txid, - &inflight->funding->txid)); + &inflight->funding->outpoint.txid)); msg = towire_dualopend_fail(NULL, "Peer error with PSBT" " signatures."); goto send_msg; @@ -1057,8 +1057,7 @@ wallet_update_channel(struct lightningd *ld, struct channel *channel, struct bitcoin_tx *remote_commit STEALS, struct bitcoin_signature *remote_commit_sig, - const struct bitcoin_txid *funding_txid, - u16 funding_outnum, + const struct bitcoin_outpoint *funding, struct amount_sat total_funding, struct amount_sat our_funding, u32 funding_feerate, @@ -1080,9 +1079,8 @@ wallet_update_channel(struct lightningd *ld, assert(channel->unsaved_dbid == 0); assert(channel->dbid != 0); - channel->funding_txid = *funding_txid; - channel->funding_outnum = funding_outnum; - channel->funding = total_funding; + channel->funding = *funding; + channel->funding_sats = total_funding; channel->our_funds = our_funding; channel->our_msat = our_msat; channel->msat_to_us_min = our_msat; @@ -1109,10 +1107,9 @@ wallet_update_channel(struct lightningd *ld, /* Add open attempt to channel's inflights */ inflight = new_inflight(channel, - channel->funding_txid, - channel->funding_outnum, + &channel->funding, funding_feerate, - channel->funding, + channel->funding_sats, channel->our_funds, psbt, channel->last_tx, @@ -1133,8 +1130,7 @@ wallet_commit_channel(struct lightningd *ld, struct channel *channel, struct bitcoin_tx *remote_commit, struct bitcoin_signature *remote_commit_sig, - const struct bitcoin_txid *funding_txid, - u16 funding_outnum, + const struct bitcoin_outpoint *funding, struct amount_sat total_funding, struct amount_sat our_funding, struct channel_info *channel_info, @@ -1174,9 +1170,8 @@ wallet_commit_channel(struct lightningd *ld, channel->dbid = channel->unsaved_dbid; channel->unsaved_dbid = 0; - channel->funding_txid = *funding_txid; - channel->funding_outnum = funding_outnum; - channel->funding = total_funding; + channel->funding = *funding; + channel->funding_sats = total_funding; channel->our_funds = our_funding; channel->our_msat = our_msat; channel->msat_to_us_min = our_msat; @@ -1231,10 +1226,9 @@ wallet_commit_channel(struct lightningd *ld, /* Open attempt to channel's inflights */ inflight = new_inflight(channel, - channel->funding_txid, - channel->funding_outnum, + &channel->funding, funding_feerate, - channel->funding, + channel->funding_sats, channel->our_funds, psbt, channel->last_tx, @@ -1505,8 +1499,8 @@ static void handle_peer_tx_sigs_sent(struct subd *dualopend, /* Tell plugins about the success */ notify_channel_opened(dualopend->ld, &channel->peer->id, - &channel->funding, - &channel->funding_txid, + &channel->funding_sats, + &channel->funding.txid, &channel->remote_funding_locked); /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2 @@ -1651,7 +1645,7 @@ void dualopen_tell_depth(struct subd *dualopend, /* Are we there yet? */ if (to_go == 0) { assert(channel->scid); - assert(bitcoin_txid_eq(&channel->funding_txid, txid)); + assert(bitcoin_txid_eq(&channel->funding.txid, txid)); channel_set_billboard(channel, false, tal_fmt(tmpctx, "Funding depth reached" @@ -1876,8 +1870,8 @@ static void handle_peer_tx_sigs_msg(struct subd *dualopend, /* Tell plugins about the success */ notify_channel_opened(dualopend->ld, &channel->peer->id, - &channel->funding, - &channel->funding_txid, + &channel->funding_sats, + &channel->funding.txid, &channel->remote_funding_locked); /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2 @@ -2007,12 +2001,12 @@ static void handle_validate_rbf(struct subd *dualopend, for (size_t i = 0; i < candidate_psbt->num_inputs; i++) { struct wally_tx_input *input = &candidate_psbt->tx->inputs[i]; - struct bitcoin_txid in_txid; + struct bitcoin_outpoint outpoint; - wally_tx_input_get_txid(input, &in_txid); + wally_tx_input_get_outpoint(input, &outpoint); if (!psbt_has_input(inflight->funding_psbt, - &in_txid, input->index)) + &outpoint)) inputs_present[i] = false; } } @@ -2308,13 +2302,13 @@ json_openchannel_signed(struct command *cmd, /* Verify that the psbt's txid matches that of the * funding txid for this channel */ psbt_txid(NULL, psbt, &txid, NULL); - if (!bitcoin_txid_eq(&txid, &channel->funding_txid)) + if (!bitcoin_txid_eq(&txid, &channel->funding.txid)) return command_fail(cmd, FUNDING_PSBT_INVALID, "Txid for passed in PSBT does not match" " funding txid for channel. Expected %s, " "received %s", type_to_string(tmpctx, struct bitcoin_txid, - &channel->funding_txid), + &channel->funding.txid), type_to_string(tmpctx, struct bitcoin_txid, &txid)); @@ -2325,14 +2319,15 @@ json_openchannel_signed(struct command *cmd, return command_fail(cmd, LIGHTNINGD, "Open attempt for channel not found"); - if (!bitcoin_txid_eq(&txid, &inflight->funding->txid)) + if (!bitcoin_txid_eq(&txid, &inflight->funding->outpoint.txid)) return command_fail(cmd, LIGHTNINGD, "Current inflight transaction is %s," " not %s", type_to_string(tmpctx, struct bitcoin_txid, &txid), type_to_string(tmpctx, struct bitcoin_txid, - &inflight->funding->txid)); + &inflight->funding + ->outpoint.txid)); if (inflight->funding_psbt && psbt_is_finalized(inflight->funding_psbt)) return command_fail(cmd, FUNDING_STATE_INVALID, @@ -2709,8 +2704,8 @@ static void handle_commit_received(struct subd *dualopend, struct channel_info channel_info; struct bitcoin_tx *remote_commit; struct bitcoin_signature remote_commit_sig; - struct bitcoin_txid funding_txid; - u16 funding_outnum, lease_chan_max_ppt; + struct bitcoin_outpoint funding; + u16 lease_chan_max_ppt; u32 feerate_funding, feerate_commitment, lease_expiry, lease_chan_max_msat, lease_blockheight_start; struct amount_sat total_funding, funding_ours; @@ -2736,8 +2731,7 @@ static void handle_commit_received(struct subd *dualopend, &channel_info.theirbase.delayed_payment, &channel_info.remote_per_commit, &channel_info.remote_fundingkey, - &funding_txid, - &funding_outnum, + &funding, &total_funding, &funding_ours, &channel->channel_flags, @@ -2779,8 +2773,7 @@ static void handle_commit_received(struct subd *dualopend, if (!(inflight = wallet_commit_channel(ld, channel, remote_commit, &remote_commit_sig, - &funding_txid, - funding_outnum, + &funding, total_funding, funding_ours, &channel_info, @@ -2819,8 +2812,7 @@ static void handle_commit_received(struct subd *dualopend, if (!(inflight = wallet_update_channel(ld, channel, remote_commit, &remote_commit_sig, - &funding_txid, - funding_outnum, + &funding, total_funding, funding_ours, feerate_funding, @@ -2861,7 +2853,7 @@ static void handle_commit_received(struct subd *dualopend, json_add_psbt(response, "psbt", psbt); json_add_bool(response, "commitments_secured", true); /* For convenience sake, we include the funding outnum */ - json_add_num(response, "funding_outnum", funding_outnum); + json_add_num(response, "funding_outnum", funding.n); if (oa->our_upfront_shutdown_script) { json_add_hex_talarr(response, "close_to", oa->our_upfront_shutdown_script); @@ -3264,10 +3256,9 @@ void peer_restart_dualopend(struct peer *peer, &channel->local_funding_pubkey, &channel->channel_info.remote_fundingkey, channel->minimum_depth, - &inflight->funding->txid, - inflight->funding->outnum, + &inflight->funding->outpoint, inflight->funding->feerate, - channel->funding, + channel->funding_sats, channel->our_msat, &channel->channel_info.theirbase, &channel->channel_info.remote_per_commit, diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 77008c226f86..fd9caec3afa5 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -57,7 +57,7 @@ static void got_filteredblock(struct bitcoind *bitcoind, u32 txindex = short_channel_id_txnum(scid); for (size_t i=0; ioutpoints); i++) { o = fb->outpoints[i]; - if (o->txindex == txindex && o->outnum == outnum) { + if (o->txindex == txindex && o->outpoint.n == outnum) { fbo = o; break; } diff --git a/lightningd/invoice.c b/lightningd/invoice.c index 109fbf9b49c0..07d176aa16b3 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -585,7 +585,7 @@ static struct route_info **select_inchan(const tal_t *ctx, if (!amount_sat_add(&cumulative_reserve, candidates[i].c->our_config.channel_reserve, candidates[i].c->channel_info.their_config.channel_reserve) - || !amount_sat_to_msat(&capacity, candidates[i].c->funding) + || !amount_sat_to_msat(&capacity, candidates[i].c->funding_sats) || !amount_msat_sub_sat(&capacity, capacity, cumulative_reserve)) { log_broken(ld->log, "Channel %s capacity overflow!", type_to_string(tmpctx, struct short_channel_id, candidates[i].c->scid)); diff --git a/lightningd/notification.c b/lightningd/notification.c index 31782ceace02..fa2e38b09aea 100644 --- a/lightningd/notification.c +++ b/lightningd/notification.c @@ -194,6 +194,7 @@ void notify_invoice_creation(struct lightningd *ld, struct amount_msat *amount, plugins_notify(ld->plugins, take(n)); } +/* FIXME: Use outpoint here! */ static void channel_opened_notification_serialize(struct json_stream *stream, struct node_id *node_id, struct amount_sat *funding_sat, @@ -437,11 +438,11 @@ static void json_mvt_id(struct json_stream *stream, enum mvt_type mvt_type, /* some chain ledger entries aren't associated with a utxo * e.g. journal updates (due to penalty/state loss) and * chain_fee entries */ - if (id->output_txid) { + if (id->outpoint) { json_add_string(stream, "utxo_txid", type_to_string(tmpctx, struct bitcoin_txid, - id->output_txid)); - json_add_u32(stream, "vout", id->vout); + &id->outpoint->txid)); + json_add_u32(stream, "vout", id->outpoint->n); } /* on-chain htlcs include a payment hash */ diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index b29c5ce0aede..242ab495e8f7 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -185,18 +185,18 @@ static enum watch_result onchain_txo_watched(struct channel *channel, static void watch_tx_and_outputs(struct channel *channel, const struct bitcoin_tx *tx) { - struct bitcoin_txid txid; + struct bitcoin_outpoint outpoint; struct txwatch *txw; struct lightningd *ld = channel->peer->ld; - bitcoin_txid(tx, &txid); + bitcoin_txid(tx, &outpoint.txid); /* Make txwatch a parent of txo watches, so we can unwatch together. */ txw = watch_tx(channel->owner, ld->topology, channel, tx, onchain_tx_watched); - for (size_t i = 0; i < tx->wtx->num_outputs; i++) - watch_txo(txw, ld->topology, channel, &txid, i, + for (outpoint.n = 0; outpoint.n < tx->wtx->num_outputs; outpoint.n++) + watch_txo(txw, ld->topology, channel, &outpoint, onchain_txo_watched); } @@ -381,14 +381,14 @@ static void onchain_add_utxo(struct channel *channel, const u8 *msg) { struct chain_coin_mvt *mvt; u32 blockheight; - struct bitcoin_txid txid; - u32 outnum, csv_lock; + struct bitcoin_outpoint outpoint; + u32 csv_lock; struct amount_sat amount; struct pubkey *commitment_point; u8 *scriptPubkey; if (!fromwire_onchaind_add_utxo( - tmpctx, msg, &txid, &outnum, &commitment_point, + tmpctx, msg, &outpoint, &commitment_point, &amount, &blockheight, &scriptPubkey, &csv_lock)) { log_broken(channel->log, @@ -399,32 +399,30 @@ static void onchain_add_utxo(struct channel *channel, const u8 *msg) assert(blockheight); outpointfilter_add(channel->peer->ld->wallet->owned_outpoints, - &txid, outnum); - log_debug(channel->log, "adding utxo to watch %s:%u, csv %u", - type_to_string(tmpctx, struct bitcoin_txid, &txid), - outnum, csv_lock); + &outpoint); + log_debug(channel->log, "adding utxo to watch %s, csv %u", + type_to_string(tmpctx, struct bitcoin_outpoint, &outpoint), + csv_lock); wallet_add_onchaind_utxo(channel->peer->ld->wallet, - &txid, outnum, scriptPubkey, + &outpoint, scriptPubkey, blockheight, amount, channel, commitment_point, csv_lock); - mvt = new_coin_deposit_sat(msg, "wallet", &txid, - outnum, blockheight, amount); + mvt = new_coin_deposit_sat(msg, "wallet", &outpoint, blockheight, amount); notify_chain_mvt(channel->peer->ld, mvt); } static void onchain_annotate_txout(struct channel *channel, const u8 *msg) { - struct bitcoin_txid txid; + struct bitcoin_outpoint outpoint; enum wallet_tx_type type; - u32 outnum; - if (!fromwire_onchaind_annotate_txout(msg, &txid, &outnum, &type)) + if (!fromwire_onchaind_annotate_txout(msg, &outpoint, &type)) fatal("onchaind gave invalid onchain_annotate_txout " "message: %s", tal_hex(msg, msg)); - wallet_annotate_txout(channel->peer->ld->wallet, &txid, outnum, type, + wallet_annotate_txout(channel->peer->ld->wallet, &outpoint, type, channel->dbid); } @@ -636,7 +634,7 @@ enum watch_result onchaind_funding_spent(struct channel *channel, for (size_t i = 0; i < 3; i++) { if (!feerates[i]) { /* We have at least one data point: the last tx's feerate. */ - struct amount_sat fee = channel->funding; + struct amount_sat fee = channel->funding_sats; for (size_t i = 0; i < channel->last_tx->wtx->num_outputs; i++) { struct amount_asset asset = @@ -649,7 +647,7 @@ enum watch_result onchaind_funding_spent(struct channel *channel, " funding %s tx %s", type_to_string(tmpctx, struct amount_sat, - &channel->funding), + &channel->funding_sats), type_to_string(tmpctx, struct bitcoin_tx, channel->last_tx)); @@ -669,7 +667,7 @@ enum watch_result onchaind_funding_spent(struct channel *channel, msg = towire_onchaind_init(channel, &channel->their_shachain.chain, chainparams, - channel->funding, + channel->funding_sats, channel->our_msat, &channel->channel_info.old_remote_per_commit, &channel->channel_info.remote_per_commit, diff --git a/lightningd/opening_common.h b/lightningd/opening_common.h index 27ad45d5bbc8..8def23c573de 100644 --- a/lightningd/opening_common.h +++ b/lightningd/opening_common.h @@ -65,7 +65,7 @@ struct funding_channel { struct wallet_tx *wtx; struct amount_msat push; - struct amount_sat funding; + struct amount_sat funding_sats; u8 channel_flags; const u8 *our_upfront_shutdown_script; diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index 855805533c0f..3b5b6e61debb 100644 --- a/lightningd/opening_control.c +++ b/lightningd/opening_control.c @@ -50,7 +50,7 @@ void json_add_uncommitted_channel(struct json_stream *response, } /* These should never fail. */ - if (amount_sat_to_msat(&total, uc->fc->funding) + if (amount_sat_to_msat(&total, uc->fc->funding_sats) && amount_msat_sub(&ours, total, uc->fc->push)) { json_add_amount_msat_compat(response, ours, "msatoshi_to_us", "to_us_msat"); @@ -80,9 +80,8 @@ wallet_commit_channel(struct lightningd *ld, struct channel_id *cid, struct bitcoin_tx *remote_commit, struct bitcoin_signature *remote_commit_sig, - const struct bitcoin_txid *funding_txid, - u16 funding_outnum, - struct amount_sat funding, + const struct bitcoin_outpoint *funding, + struct amount_sat funding_sats, struct amount_msat push, u8 channel_flags, struct channel_info *channel_info, @@ -111,15 +110,15 @@ wallet_commit_channel(struct lightningd *ld, } if (uc->fc) { - if (!amount_sat_sub_msat(&our_msat, funding, push)) { + if (!amount_sat_sub_msat(&our_msat, funding_sats, push)) { log_broken(uc->log, "push %s exceeds funding %s", type_to_string(tmpctx, struct amount_msat, &push), type_to_string(tmpctx, struct amount_sat, - &funding)); + &funding_sats)); return NULL; } - local_funding = funding; + local_funding = funding_sats; } else { our_msat = push; local_funding = AMOUNT_SAT(0); @@ -166,9 +165,8 @@ wallet_commit_channel(struct lightningd *ld, &uc->our_config, uc->minimum_depth, 1, 1, 0, - funding_txid, - funding_outnum, funding, + funding_sats, push, local_funding, false, /* !remote_funding_locked */ @@ -332,8 +330,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp, { struct channel_info channel_info; struct channel_id cid; - struct bitcoin_txid funding_txid; - u16 funding_txout; + struct bitcoin_outpoint funding; struct bitcoin_signature remote_commit_sig; struct bitcoin_tx *remote_commit; u32 feerate; @@ -360,8 +357,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp, &channel_info.remote_per_commit, &fc->uc->minimum_depth, &channel_info.remote_fundingkey, - &funding_txid, - &funding_txout, + &funding, &feerate, &fc->uc->our_config.channel_reserve, &remote_upfront_shutdown_script, @@ -382,7 +378,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp, &channel_info.remote_per_commit)); /* Saved with channel to disk */ - derive_channel_id(&cid, &funding_txid, funding_txout); + derive_channel_id(&cid, &funding); /* old_remote_per_commit not valid yet, copy valid one. */ channel_info.old_remote_per_commit = channel_info.remote_per_commit; @@ -392,9 +388,8 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp, &cid, remote_commit, &remote_commit_sig, - &funding_txid, - funding_txout, - fc->funding, + &funding, + fc->funding_sats, fc->push, fc->channel_flags, &channel_info, @@ -435,9 +430,8 @@ static void opening_fundee_finished(struct subd *openingd, struct bitcoin_tx *remote_commit; struct channel_id cid; struct lightningd *ld = openingd->ld; - struct bitcoin_txid funding_txid; - u16 funding_outnum; - struct amount_sat funding; + struct bitcoin_outpoint funding; + struct amount_sat funding_sats; struct amount_msat push; u32 feerate; u8 channel_flags; @@ -464,9 +458,8 @@ static void opening_fundee_finished(struct subd *openingd, &channel_info.theirbase.delayed_payment, &channel_info.remote_per_commit, &channel_info.remote_fundingkey, - &funding_txid, - &funding_outnum, &funding, + &funding_sats, &push, &channel_flags, &feerate, @@ -493,7 +486,7 @@ static void opening_fundee_finished(struct subd *openingd, goto failed; } - derive_channel_id(&cid, &funding_txid, funding_outnum); + derive_channel_id(&cid, &funding); /* old_remote_per_commit not valid yet, copy valid one. */ channel_info.old_remote_per_commit = channel_info.remote_per_commit; @@ -503,9 +496,8 @@ static void opening_fundee_finished(struct subd *openingd, &cid, remote_commit, &remote_commit_sig, - &funding_txid, - funding_outnum, - funding, + &funding, + funding_sats, push, channel_flags, &channel_info, @@ -521,13 +513,13 @@ static void opening_fundee_finished(struct subd *openingd, log_debug(channel->log, "Watching funding tx %s", type_to_string(reply, struct bitcoin_txid, - &channel->funding_txid)); + &channel->funding.txid)); channel_watch_funding(ld, channel); /* Tell plugins about the success */ - notify_channel_opened(ld, &channel->peer->id, &channel->funding, - &channel->funding_txid, &channel->remote_funding_locked); + notify_channel_opened(ld, &channel->peer->id, &channel->funding_sats, + &channel->funding.txid, &channel->remote_funding_locked); if (pbase) wallet_penalty_base_add(ld->wallet, channel->dbid, pbase); @@ -1054,14 +1046,14 @@ static struct command_result *json_fundchannel_complete(struct command *cmd, if (!chainparams->is_elements && !amount_sat_eq(amount_sat(funding_psbt->tx->outputs [*funding_txout_num].satoshi), - fc->funding)) + fc->funding_sats)) return command_fail(cmd, FUNDING_PSBT_INVALID, "Output to open channel is %"PRIu64"sat," " should be %s", funding_psbt->tx->outputs [*funding_txout_num].satoshi, type_to_string(tmpctx, struct amount_sat, - &fc->funding)); + &fc->funding_sats)); funding_txid = tal(cmd, struct bitcoin_txid); psbt_txid(NULL, funding_psbt, funding_txid, NULL); @@ -1165,7 +1157,7 @@ static struct command_result *json_fundchannel_start(struct command *cmd, type_to_string(tmpctx, struct amount_msat, push_msat), type_to_string(tmpctx, struct amount_sat, amount)); - fc->funding = *amount; + fc->funding_sats = *amount; if (!feerate_per_kw) { feerate_per_kw = tal(cmd, u32); *feerate_per_kw = opening_feerate(cmd->ld->topology); diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 0e3d28d2cc63..e06c262eac56 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -579,7 +579,8 @@ struct amount_msat channel_amount_receivable(const struct channel *channel) struct amount_msat their_msat, receivable; /* Compute how much we can receive via this channel in one payment */ - if (!amount_sat_sub_msat(&their_msat, channel->funding, channel->our_msat)) + if (!amount_sat_sub_msat(&their_msat, + channel->funding_sats, channel->our_msat)) their_msat = AMOUNT_MSAT(0); if (!amount_msat_sub_sat(&receivable, @@ -653,7 +654,7 @@ static void json_add_channel(struct lightningd *ld, json_add_string(response, "channel_id", type_to_string(tmpctx, struct channel_id, &channel->cid)); - json_add_txid(response, "funding_txid", &channel->funding_txid); + json_add_txid(response, "funding_txid", &channel->funding.txid); if (!list_empty(&channel->inflights)) { struct channel_inflight *initial, *inflight; @@ -690,9 +691,9 @@ static void json_add_channel(struct lightningd *ld, json_object_start(response, NULL); json_add_txid(response, "funding_txid", - &inflight->funding->txid); + &inflight->funding->outpoint.txid); json_add_num(response, "funding_outnum", - inflight->funding->outnum); + inflight->funding->outpoint.n); json_add_string(response, "feerate", tal_fmt(tmpctx, "%d%s", inflight->funding->feerate, @@ -743,12 +744,12 @@ static void json_add_channel(struct lightningd *ld, json_add_string(response, NULL, "option_anchor_outputs"); json_array_end(response); - if (!amount_sat_sub(&peer_funded_sats, channel->funding, + if (!amount_sat_sub(&peer_funded_sats, channel->funding_sats, channel->our_funds)) { log_broken(channel->log, "Overflow subtracing funding %s, our funds %s", type_to_string(tmpctx, struct amount_sat, - &channel->funding), + &channel->funding_sats), type_to_string(tmpctx, struct amount_sat, &channel->our_funds)); peer_funded_sats = AMOUNT_SAT(0); @@ -791,11 +792,11 @@ static void json_add_channel(struct lightningd *ld, json_add_sat_only(response, "remote_msat", peer_funded_sats); json_object_end(response); - if (!amount_sat_to_msat(&funding_msat, channel->funding)) { + if (!amount_sat_to_msat(&funding_msat, channel->funding_sats)) { log_broken(channel->log, "Overflow converting funding %s", type_to_string(tmpctx, struct amount_sat, - &channel->funding)); + &channel->funding_sats)); funding_msat = AMOUNT_MSAT(0); } json_add_amount_msat_compat(response, channel->our_msat, @@ -1203,14 +1204,14 @@ static bool check_funding_tx(const struct bitcoin_tx *tx, * actually contain the funding output). As of v2 (where * RBF is introduced), this isn't a problem so much as * both sides have full access to the funding transaction */ - if (check_funding_details(tx, wscript, channel->funding, - channel->funding_outnum)) + if (check_funding_details(tx, wscript, channel->funding_sats, + channel->funding.n)) return true; list_for_each(&channel->inflights, inflight, list) { if (check_funding_details(tx, wscript, inflight->funding->total_funds, - inflight->funding->outnum)) + inflight->funding->outpoint.n)) return true; } return false; @@ -1222,9 +1223,8 @@ static void update_channel_from_inflight(struct lightningd *ld, { struct wally_psbt *psbt_copy; - channel->funding_txid = inflight->funding->txid; - channel->funding_outnum = inflight->funding->outnum; - channel->funding = inflight->funding->total_funds; + channel->funding = inflight->funding->outpoint; + channel->funding_sats = inflight->funding->total_funds; channel->our_funds = inflight->funding->our_funds; /* Lease infos ! */ @@ -1306,17 +1306,17 @@ static enum watch_result funding_depth_cb(struct lightningd *ld, update_channel_from_inflight(ld, channel, inf); } - wallet_annotate_txout(ld->wallet, txid, channel->funding_outnum, + wallet_annotate_txout(ld->wallet, &channel->funding, TX_CHANNEL_FUNDING, channel->dbid); loc = wallet_transaction_locate(tmpctx, ld->wallet, txid); if (!mk_short_channel_id(&scid, loc->blkheight, loc->index, - channel->funding_outnum)) { + channel->funding.n)) { channel_fail_permanent(channel, REASON_LOCAL, "Invalid funding scid %u:%u:%u", loc->blkheight, loc->index, - channel->funding_outnum); + channel->funding.n); return DELETE_WATCH; } @@ -1373,8 +1373,7 @@ void channel_watch_wrong_funding(struct lightningd *ld, struct channel *channel) if (channel->shutdown_wrong_funding) { /* FIXME: Remove arg from cb? */ watch_txo(channel, ld->topology, channel, - &channel->shutdown_wrong_funding->txid, - channel->shutdown_wrong_funding->n, + channel->shutdown_wrong_funding, funding_spent); } } @@ -1383,9 +1382,9 @@ void channel_watch_funding(struct lightningd *ld, struct channel *channel) { /* FIXME: Remove arg from cb? */ watch_txid(channel, ld->topology, channel, - &channel->funding_txid, funding_depth_cb); + &channel->funding.txid, funding_depth_cb); watch_txo(channel, ld->topology, channel, - &channel->funding_txid, channel->funding_outnum, + &channel->funding, funding_spent); channel_watch_wrong_funding(ld, channel); } @@ -1396,10 +1395,9 @@ static void channel_watch_inflight(struct lightningd *ld, { /* FIXME: Remove arg from cb? */ watch_txid(channel, ld->topology, channel, - &inflight->funding->txid, funding_depth_cb); + &inflight->funding->outpoint.txid, funding_depth_cb); watch_txo(channel, ld->topology, channel, - &inflight->funding->txid, - inflight->funding->outnum, + &inflight->funding->outpoint, funding_spent); } @@ -1574,8 +1572,8 @@ static void activate_peer(struct peer *peer, u32 delay) list_for_each(&channel->inflights, inflight, list) { /* Don't double watch the txid that's also in * channel->funding_txid */ - if (bitcoin_txid_eq(&channel->funding_txid, - &inflight->funding->txid)) + if (bitcoin_txid_eq(&channel->funding.txid, + &inflight->funding->outpoint.txid)) continue; channel_watch_inflight(ld, channel, inflight); @@ -2096,7 +2094,7 @@ static struct command_result *json_sign_last_tx(struct command *cmd, &inflight->last_sig); json_object_start(response, NULL); json_add_txid(response, "funding_txid", - &inflight->funding->txid); + &inflight->funding->outpoint.txid); remove_sig(inflight->last_tx); json_add_tx(response, "tx", channel->last_tx); json_object_end(response); @@ -2240,7 +2238,7 @@ static void process_dev_forget_channel(struct bitcoind *bitcoind UNUSED, response = json_stream_success(forget->cmd); json_add_bool(response, "forced", forget->force); json_add_bool(response, "funding_unspent", txout != NULL); - json_add_txid(response, "funding_txid", &forget->channel->funding_txid); + json_add_txid(response, "funding_txid", &forget->channel->funding.txid); /* Set error so we don't try to reconnect. */ forget->channel->error = towire_errorfmt(forget->channel, @@ -2316,8 +2314,7 @@ static struct command_result *json_dev_forget_channel(struct command *cmd, if (!channel_unsaved(forget->channel)) bitcoind_getutxout(cmd->ld->topology->bitcoind, - &forget->channel->funding_txid, - forget->channel->funding_outnum, + &forget->channel->funding, process_dev_forget_channel, forget); return command_still_pending(cmd); } diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index b182cc01ad53..6a3e6d055989 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -15,7 +15,7 @@ struct channel *active_channel_by_scid(struct lightningd *ld UNNEEDED, { fprintf(stderr, "active_channel_by_scid called!\n"); abort(); } /* Generated stub for bitcoind_getutxout_ */ void bitcoind_getutxout_(struct bitcoind *bitcoind UNNEEDED, - const struct bitcoin_txid *txid UNNEEDED, const u32 outnum UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, void (*cb)(struct bitcoind *bitcoind UNNEEDED, const struct bitcoin_tx_output *txout UNNEEDED, void *arg) UNNEEDED, @@ -676,8 +676,9 @@ u8 *towire_warningfmt(const tal_t *ctx UNNEEDED, const char *version(void) { fprintf(stderr, "version called!\n"); abort(); } /* Generated stub for wallet_annotate_txout */ -void wallet_annotate_txout(struct wallet *w UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, - int outnum UNNEEDED, enum wallet_tx_type type UNNEEDED, u64 channel UNNEEDED) +void wallet_annotate_txout(struct wallet *w UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, + enum wallet_tx_type type UNNEEDED, u64 channel UNNEEDED) { fprintf(stderr, "wallet_annotate_txout called!\n"); abort(); } /* Generated stub for wallet_channel_save */ void wallet_channel_save(struct wallet *w UNNEEDED, struct channel *chan UNNEEDED) @@ -820,8 +821,7 @@ struct txwatch *watch_txid(const tal_t *ctx UNNEEDED, struct txowatch *watch_txo(const tal_t *ctx UNNEEDED, struct chain_topology *topo UNNEEDED, struct channel *channel UNNEEDED, - const struct bitcoin_txid *txid UNNEEDED, - unsigned int output UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, enum watch_result (*cb)(struct channel *channel UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, size_t input_num UNNEEDED, @@ -870,7 +870,7 @@ static struct channel *add_peer(struct lightningd *ld, int n, c->opener = LOCAL; c->peer = peer; /* Channel has incoming capacity n*1000 - 1 millisatoshi */ - c->funding.satoshis = n+1; + c->funding_sats.satoshis = n+1; c->our_msat = AMOUNT_MSAT(1); c->our_config.channel_reserve = AMOUNT_SAT(1); c->our_config.htlc_minimum = AMOUNT_MSAT(0); diff --git a/lightningd/watch.c b/lightningd/watch.c index 123d6e0369e5..ca7f0acdef88 100644 --- a/lightningd/watch.c +++ b/lightningd/watch.c @@ -187,8 +187,7 @@ struct txwatch *watch_tx(const tal_t *ctx, struct txowatch *watch_txo(const tal_t *ctx, struct chain_topology *topo, struct channel *channel, - const struct bitcoin_txid *txid, - unsigned int output, + const struct bitcoin_outpoint *outpoint, enum watch_result (*cb)(struct channel *channel, const struct bitcoin_tx *tx, size_t input_num, @@ -197,8 +196,7 @@ struct txowatch *watch_txo(const tal_t *ctx, struct txowatch *w = tal(ctx, struct txowatch); w->topo = topo; - w->out.txid = *txid; - w->out.n = output; + w->out = *outpoint; w->channel = channel; w->cb = cb; diff --git a/lightningd/watch.h b/lightningd/watch.h index 348c50fbf6c8..35d818e892c5 100644 --- a/lightningd/watch.h +++ b/lightningd/watch.h @@ -53,8 +53,7 @@ struct txwatch *watch_tx(const tal_t *ctx, struct txowatch *watch_txo(const tal_t *ctx, struct chain_topology *topo, struct channel *channel, - const struct bitcoin_txid *txid, - unsigned int output, + const struct bitcoin_outpoint *outpoint, enum watch_result (*cb)(struct channel *channel, const struct bitcoin_tx *tx, size_t input_num, diff --git a/onchaind/onchaind.c b/onchaind/onchaind.c index 39836e1c426d..b2973a4fecd9 100644 --- a/onchaind/onchaind.c +++ b/onchaind/onchaind.c @@ -99,11 +99,10 @@ struct resolution { struct tracked_output { enum tx_type tx_type; - struct bitcoin_txid txid; + struct bitcoin_outpoint outpoint; u32 tx_blockheight; /* FIXME: Convert all depths to blocknums, then just get new blk msgs */ u32 depth; - u32 outnum; struct amount_sat sat; enum output_type output_type; @@ -197,7 +196,7 @@ static void record_their_successful_cheat(const struct bitcoin_txid *txid, /* They successfully spent a delayed_to_them output * that we were expecting to revoke */ mvt = new_coin_penalty_sat(NULL, NULL, - txid, &out->txid, out->outnum, + txid, &out->outpoint, blockheight, out->sat); send_coin_mvt(take(mvt)); @@ -215,8 +214,8 @@ static void record_htlc_fulfilled(const struct bitcoin_txid *txid, * * since we really don't know if this was a 'routed' or 'destination' * htlc here, we record it as a 'deposit/withdrawal' type */ - mvt = new_coin_onchain_htlc_sat(NULL, NULL, txid, &out->txid, - out->outnum, out->payment_hash, + mvt = new_coin_onchain_htlc_sat(NULL, NULL, txid, &out->outpoint, + out->payment_hash, blockheight, out->sat, we_fulfilled); send_coin_mvt(take(mvt)); @@ -266,10 +265,9 @@ static void add_amt(struct amount_sat *sum, struct amount_sat amt) sum)); } -static void record_mutual_closure(const struct bitcoin_txid *txid, +static void record_mutual_closure(const struct bitcoin_outpoint *outpoint, u32 blockheight, - struct amount_sat our_out, - int output_num) + struct amount_sat our_out) { struct amount_msat chain_fees, output_msat; @@ -293,15 +291,16 @@ static void record_mutual_closure(const struct bitcoin_txid *txid, &our_msat)); if (!amount_msat_eq(AMOUNT_MSAT(0), chain_fees)) - update_ledger_chain_fees_msat(txid, blockheight, chain_fees); + update_ledger_chain_fees_msat(&outpoint->txid, blockheight, chain_fees); /* If we have no output, we exit early */ if (amount_msat_eq(AMOUNT_MSAT(0), output_msat)) return; - assert(output_num > -1); /* Otherwise, we record the channel withdrawal */ - send_coin_mvt(take(new_coin_withdrawal(NULL, NULL, txid, txid, output_num, + /* FIXME: WHy dup txid? */ + send_coin_mvt(take(new_coin_withdrawal(NULL, NULL, &outpoint->txid, + outpoint, blockheight, output_msat))); } @@ -337,7 +336,7 @@ static void record_chain_fees_unilateral(const struct bitcoin_txid *txid, /* Log the difference and update our_msat */ send_coin_mvt(take(new_coin_journal_entry(NULL, NULL, txid, - NULL, 0, blockheight, + NULL, blockheight, missing, true))); if (!amount_msat_add(&our_msat, our_msat, missing)) status_failed(STATUS_FAIL_INTERNAL_ERROR, @@ -370,8 +369,8 @@ static void record_coin_loss(const struct bitcoin_txid *txid, struct chain_coin_mvt *mvt; /* We don't for sure know that it's a 'penalty' * but we write it as that anyway... */ - mvt = new_coin_penalty_sat(NULL, NULL, txid, &out->txid, - out->outnum, blockheight, out->sat); + mvt = new_coin_penalty_sat(NULL, NULL, txid, &out->outpoint, + blockheight, out->sat); send_coin_mvt(take(mvt)); } @@ -392,8 +391,8 @@ static void record_channel_withdrawal_minus_fees(const struct bitcoin_txid *tx_t &out->sat)); send_coin_mvt(take(new_coin_withdrawal_sat( - NULL, NULL, tx_txid, &out->txid, - out->outnum, blockheight, emitted_amt))); + NULL, NULL, tx_txid, &out->outpoint, + blockheight, emitted_amt))); } @@ -684,7 +683,7 @@ static struct bitcoin_tx *tx_to_us(const tal_t *ctx, u8 **witness; tx = bitcoin_tx(ctx, chainparams, 1, 1, locktime); - bitcoin_tx_add_input(tx, &out->txid, out->outnum, to_self_delay, + bitcoin_tx_add_input(tx, &out->outpoint, to_self_delay, NULL, out->sat, NULL, wscript); bitcoin_tx_add_output( @@ -775,8 +774,7 @@ replace_penalty_tx_to_us(const tal_t *ctx, /* The penalty tx input. */ const struct wally_tx_input *input; /* Specs of the penalty tx input. */ - struct bitcoin_txid input_txid; - u32 input_outnum; + struct bitcoin_outpoint input_outpoint; u8 *input_wscript; u8 *input_element; struct amount_sat input_amount; @@ -791,8 +789,8 @@ replace_penalty_tx_to_us(const tal_t *ctx, /* Get the single input of the penalty tx. */ input = &penalty_tx->wtx->inputs[0]; /* Extract the input-side data. */ - bitcoin_tx_input_get_txid(penalty_tx, 0, &input_txid); - input_outnum = input->index; + bitcoin_tx_input_get_txid(penalty_tx, 0, &input_outpoint.txid); + input_outpoint.n = input->index; input_wscript = tal_dup_arr(tmpctx, u8, input->witness->items[2].witness, input->witness->items[2].witness_len, @@ -806,7 +804,7 @@ replace_penalty_tx_to_us(const tal_t *ctx, /* Create the replacement. */ tx = bitcoin_tx(ctx, chainparams, 1, 1, /*locktime*/ 0); /* Reconstruct the input. */ - bitcoin_tx_add_input(tx, &input_txid, input_outnum, + bitcoin_tx_add_input(tx, &input_outpoint, BITCOIN_TX_RBF_SEQUENCE, NULL, input_amount, NULL, input_wscript); /* Reconstruct the output with a smaller amount. */ @@ -997,10 +995,9 @@ static void hsm_get_per_commitment_point(struct pubkey *per_commitment_point) static struct tracked_output * new_tracked_output(struct tracked_output ***outs, - const struct bitcoin_txid *txid, + const struct bitcoin_outpoint *outpoint, u32 tx_blockheight, enum tx_type tx_type, - u32 outnum, struct amount_sat sat, enum output_type output_type, const struct htlc_stub *htlc, @@ -1009,17 +1006,15 @@ new_tracked_output(struct tracked_output ***outs, { struct tracked_output *out = tal(*outs, struct tracked_output); - status_debug("Tracking output %u of %s: %s/%s", - outnum, - type_to_string(tmpctx, struct bitcoin_txid, txid), + status_debug("Tracking output %s: %s/%s", + type_to_string(tmpctx, struct bitcoin_outpoint, outpoint), tx_type_name(tx_type), output_type_name(output_type)); out->tx_type = tx_type; - out->txid = *txid; + out->outpoint = *outpoint; out->tx_blockheight = tx_blockheight; out->depth = 0; - out->outnum = outnum; out->sat = sat; out->output_type = output_type; out->proposal = NULL; @@ -1040,14 +1035,14 @@ new_tracked_output(struct tracked_output ***outs, static void ignore_output(struct tracked_output *out) { - status_debug("Ignoring output %u of %s: %s/%s", - out->outnum, - type_to_string(tmpctx, struct bitcoin_txid, &out->txid), + status_debug("Ignoring output %s: %s/%s", + type_to_string(tmpctx, struct bitcoin_outpoint, + &out->outpoint), tx_type_name(out->tx_type), output_type_name(out->output_type)); out->resolved = tal(out, struct resolution); - out->resolved->txid = out->txid; + out->resolved->txid = out->outpoint.txid; out->resolved->depth = 0; out->resolved->tx_type = SELF; } @@ -1488,22 +1483,22 @@ static void billboard_update(struct tracked_output **outs) /* If we've broadcast and not seen yet, this happens */ if (best->proposal->depth_required <= best->depth) { peer_billboard(false, - "%u outputs unresolved: waiting confirmation that we spent %s (%s:%u) using %s", + "%u outputs unresolved: waiting confirmation that we spent %s (%s) using %s", num_not_irrevocably_resolved(outs), output_type_name(best->output_type), - type_to_string(tmpctx, struct bitcoin_txid, - &best->txid), - best->outnum, + type_to_string(tmpctx, + struct bitcoin_outpoint, + &best->outpoint), tx_type_name(best->proposal->tx_type)); } else { peer_billboard(false, - "%u outputs unresolved: in %u blocks will spend %s (%s:%u) using %s", + "%u outputs unresolved: in %u blocks will spend %s (%s) using %s", num_not_irrevocably_resolved(outs), best->proposal->depth_required - best->depth, output_type_name(best->output_type), - type_to_string(tmpctx, struct bitcoin_txid, - &best->txid), - best->outnum, + type_to_string(tmpctx, + struct bitcoin_outpoint, + &best->outpoint), tx_type_name(best->proposal->tx_type)); } return; @@ -1544,7 +1539,8 @@ static void unwatch_txid(const struct bitcoin_txid *txid) } static void handle_htlc_onchain_fulfill(struct tracked_output *out, - const struct tx_parts *tx_parts) + const struct tx_parts *tx_parts, + const struct bitcoin_outpoint *htlc_outpoint) { const struct wally_tx_witness_item *preimage_item; struct preimage preimage; @@ -1561,14 +1557,14 @@ static void handle_htlc_onchain_fulfill(struct tracked_output *out, * ... `txin[0]` witness stack: `0 * ` for HTLC-success */ - if (tx_parts->inputs[0]->witness->num_items != 5) /* +1 for wscript */ + if (tx_parts->inputs[htlc_outpoint->n]->witness->num_items != 5) /* +1 for wscript */ status_failed(STATUS_FAIL_INTERNAL_ERROR, "%s/%s spent with weird witness %zu", tx_type_name(out->tx_type), output_type_name(out->output_type), - tx_parts->inputs[0]->witness->num_items); + tx_parts->inputs[htlc_outpoint->n]->witness->num_items); - preimage_item = &tx_parts->inputs[0]->witness->items[3]; + preimage_item = &tx_parts->inputs[htlc_outpoint->n]->witness->items[3]; } else if (out->tx_type == OUR_UNILATERAL) { /* BOLT #3: * @@ -1576,14 +1572,14 @@ static void handle_htlc_onchain_fulfill(struct tracked_output *out, * * */ - if (tx_parts->inputs[0]->witness->num_items != 3) /* +1 for wscript */ + if (tx_parts->inputs[htlc_outpoint->n]->witness->num_items != 3) /* +1 for wscript */ status_failed(STATUS_FAIL_INTERNAL_ERROR, "%s/%s spent with weird witness %zu", tx_type_name(out->tx_type), output_type_name(out->output_type), - tx_parts->inputs[0]->witness->num_items); + tx_parts->inputs[htlc_outpoint->n]->witness->num_items); - preimage_item = &tx_parts->inputs[0]->witness->items[1]; + preimage_item = &tx_parts->inputs[htlc_outpoint->n]->witness->items[1]; } else status_failed(STATUS_FAIL_INTERNAL_ERROR, "onchain_fulfill for %s/%s?", @@ -1641,6 +1637,7 @@ static void handle_htlc_onchain_fulfill(struct tracked_output *out, static void resolve_htlc_tx(struct tracked_output ***outs, size_t out_index, const struct tx_parts *htlc_tx, + size_t input_num, u32 tx_blockheight, bool is_replay) { @@ -1648,6 +1645,7 @@ static void resolve_htlc_tx(struct tracked_output ***outs, struct bitcoin_tx *tx; struct amount_sat amt; struct amount_asset asset; + struct bitcoin_outpoint outpoint; enum tx_type tx_type = OUR_DELAYED_RETURN_TO_WALLET; u8 *wscript = bitcoin_wscript_htlc_tx(htlc_tx, to_self_delay[LOCAL], &keyset->self_revocation_key, @@ -1663,15 +1661,18 @@ static void resolve_htlc_tx(struct tracked_output ***outs, * `to_self_delay` field) before spending that HTLC-timeout * output. */ - asset = wally_tx_output_get_amount(htlc_tx->outputs[0]); + outpoint.txid = htlc_tx->txid; + outpoint.n = input_num; + + asset = wally_tx_output_get_amount(htlc_tx->outputs[outpoint.n]); assert(amount_asset_is_main(&asset)); amt = amount_asset_to_sat(&asset); - out = new_tracked_output(outs, &htlc_tx->txid, - tx_blockheight, - (*outs)[out_index]->resolved->tx_type, - 0, amt, - DELAYED_OUTPUT_TO_US, - NULL, NULL, NULL); + out = new_tracked_output(outs, &outpoint, + tx_blockheight, + (*outs)[out_index]->resolved->tx_type, + amt, + DELAYED_OUTPUT_TO_US, + NULL, NULL, NULL); /* BOLT #3: * @@ -1703,6 +1704,7 @@ static void steal_htlc_tx(struct tracked_output *out, const struct tx_parts *htlc_tx, u32 htlc_tx_blockheight, enum tx_type htlc_tx_type, + const struct bitcoin_outpoint *htlc_outpoint, bool is_replay) { struct bitcoin_tx *tx; @@ -1711,19 +1713,18 @@ static void steal_htlc_tx(struct tracked_output *out, struct amount_asset asset; struct amount_sat htlc_out_amt, fees; - u8 *wscript = bitcoin_wscript_htlc_tx(htlc_tx, to_self_delay[LOCAL], + u8 *wscript = bitcoin_wscript_htlc_tx(htlc_tx, to_self_delay[REMOTE], &keyset->self_revocation_key, &keyset->self_delayed_payment_key); - asset = wally_tx_output_get_amount(htlc_tx->outputs[0]); + asset = wally_tx_output_get_amount(htlc_tx->outputs[htlc_outpoint->n]); assert(amount_asset_is_main(&asset)); htlc_out_amt = amount_asset_to_sat(&asset); htlc_out = new_tracked_output(outs, - &htlc_tx->txid, htlc_tx_blockheight, + htlc_outpoint, htlc_tx_blockheight, htlc_tx_type, - /* htlc tx's only have 1 output */ - 0, htlc_out_amt, + htlc_out_amt, DELAYED_CHEAT_OUTPUT_TO_THEM, &out->htlc, wscript, NULL); /* BOLT #3: @@ -1762,11 +1763,11 @@ static void steal_htlc_tx(struct tracked_output *out, propose_resolution(htlc_out, tx, 0, tx_type, is_replay); } -static void onchain_annotate_txout(const struct bitcoin_txid *txid, u32 outnum, +static void onchain_annotate_txout(const struct bitcoin_outpoint *outpoint, enum wallet_tx_type type) { wire_sync_write(REQ_FD, take(towire_onchaind_annotate_txout( - tmpctx, txid, outnum, type))); + tmpctx, outpoint, type))); } static void onchain_annotate_txin(const struct bitcoin_txid *txid, u32 innum, @@ -1785,11 +1786,13 @@ static void output_spent(struct tracked_output ***outs, { for (size_t i = 0; i < tal_count(*outs); i++) { struct tracked_output *out = (*outs)[i]; + struct bitcoin_outpoint htlc_outpoint; + if (out->resolved) continue; if (!wally_tx_input_spends(tx_parts->inputs[input_num], - &out->txid, out->outnum)) + &out->outpoint)) continue; /* Was this our resolution? */ @@ -1797,7 +1800,7 @@ static void output_spent(struct tracked_output ***outs, /* If it's our htlc tx, we need to resolve that, too. */ if (out->resolved->tx_type == OUR_HTLC_SUCCESS_TX || out->resolved->tx_type == OUR_HTLC_TIMEOUT_TX) - resolve_htlc_tx(outs, i, tx_parts, + resolve_htlc_tx(outs, i, tx_parts, input_num, tx_blockheight, is_replay); if (!is_replay) @@ -1807,6 +1810,9 @@ static void output_spent(struct tracked_output ***outs, return; } + htlc_outpoint.txid = tx_parts->txid; + htlc_outpoint.n = input_num; + switch (out->output_type) { case OUTPUT_TO_US: case DELAYED_OUTPUT_TO_US: @@ -1820,13 +1826,15 @@ static void output_spent(struct tracked_output ***outs, if (out->tx_type == THEIR_REVOKED_UNILATERAL) { /* we've actually got a 'new' output here */ steal_htlc_tx(out, outs, tx_parts, - tx_blockheight, THEIR_HTLC_TIMEOUT_TO_THEM, + tx_blockheight, + THEIR_HTLC_TIMEOUT_TO_THEM, + &htlc_outpoint, is_replay); } else { /* We ignore this timeout tx, since we should * resolve by ignoring once we reach depth. */ onchain_annotate_txout( - &tx_parts->txid, out->outnum, + &htlc_outpoint, TX_CHANNEL_HTLC_TIMEOUT | TX_THEIRS); } break; @@ -1846,10 +1854,13 @@ static void output_spent(struct tracked_output ***outs, * - MUST extract the payment preimage from the * HTLC-success transaction input witness. */ - handle_htlc_onchain_fulfill(out, tx_parts); + handle_htlc_onchain_fulfill(out, tx_parts, + &htlc_outpoint); if (out->tx_type == THEIR_REVOKED_UNILATERAL) { steal_htlc_tx(out, outs, tx_parts, - tx_blockheight, OUR_HTLC_FULFILL_TO_THEM, + tx_blockheight, + OUR_HTLC_FULFILL_TO_THEM, + &htlc_outpoint, is_replay); } else { /* BOLT #5: @@ -1869,7 +1880,7 @@ static void output_spent(struct tracked_output ***outs, tx_blockheight, false); onchain_annotate_txout( - &tx_parts->txid, out->outnum, + &htlc_outpoint, TX_CHANNEL_HTLC_SUCCESS | TX_THEIRS); } break; @@ -1969,7 +1980,7 @@ static void tx_new_depth(struct tracked_output **outs, for (i = 0; i < tal_count(outs); i++) { /* Update output depth. */ - if (bitcoin_txid_eq(&outs[i]->txid, txid)) + if (bitcoin_txid_eq(&outs[i]->outpoint.txid, txid)) outs[i]->depth = depth; /* Is this tx resolving an output? */ @@ -1983,7 +1994,7 @@ static void tx_new_depth(struct tracked_output **outs, /* Otherwise, is this something we have a pending * resolution for? */ if (outs[i]->proposal - && bitcoin_txid_eq(&outs[i]->txid, txid) + && bitcoin_txid_eq(&outs[i]->outpoint.txid, txid) && depth >= outs[i]->proposal->depth_required) { proposal_meets_depth(outs[i], is_replay); } @@ -1991,7 +2002,7 @@ static void tx_new_depth(struct tracked_output **outs, /* Otherwise, is this an output whose proposed resolution * we should RBF? */ if (outs[i]->proposal - && bitcoin_txid_eq(&outs[i]->txid, txid) + && bitcoin_txid_eq(&outs[i]->outpoint.txid, txid) && proposal_is_rbfable(outs[i]->proposal)) proposal_should_rbf(outs[i], is_replay); } @@ -2082,8 +2093,7 @@ static void handle_preimage(struct tracked_output **outs, struct amount_sat, &outs[i]->sat)); tx = htlc_success_tx(outs[i], chainparams, - &outs[i]->txid, - outs[i]->outnum, + &outs[i]->outpoint, outs[i]->wscript, htlc_amount, to_self_delay[LOCAL], @@ -2242,6 +2252,7 @@ static void handle_mutual_close(struct tracked_output **outs, resolved_by_other(outs[0], &tx->txid, MUTUAL_CLOSE); if (!is_replay) { + struct bitcoin_outpoint outpoint; /* It's possible there's no to_us output */ if (our_outnum > -1) { struct amount_asset asset; @@ -2251,8 +2262,9 @@ static void handle_mutual_close(struct tracked_output **outs, } else our_out = AMOUNT_SAT(0); - record_mutual_closure(&tx->txid, tx_blockheight, - our_out, our_outnum); + outpoint.txid = tx->txid; + outpoint.n = our_outnum; + record_mutual_closure(&outpoint, tx_blockheight, our_out); } wait_for_resolved(outs); @@ -2326,7 +2338,7 @@ static size_t resolve_our_htlc_ourcommit(struct tracked_output *out, * HTLC-timeout transaction. */ tx = htlc_timeout_tx(tmpctx, chainparams, - &out->txid, out->outnum, + &out->outpoint, htlc_scripts[matches[i]], htlc_amount, htlcs[matches[i]].cltv_expiry, to_self_delay[LOCAL], 0, keyset, @@ -2579,9 +2591,8 @@ static u8 *scriptpubkey_to_remote(const tal_t *ctx, } static void our_unilateral_to_us(struct tracked_output ***outs, - const struct tx_parts *tx, + const struct bitcoin_outpoint *outpoint, u32 tx_blockheight, - size_t index, struct amount_sat amt, u16 sequence, const u8 *local_scriptpubkey, @@ -2604,8 +2615,8 @@ static void our_unilateral_to_us(struct tracked_output ***outs, * node's `to_self_delay` field) before spending * the output. */ - out = new_tracked_output(outs, &tx->txid, tx_blockheight, - OUR_UNILATERAL, index, + out = new_tracked_output(outs, outpoint, tx_blockheight, + OUR_UNILATERAL, amt, DELAYED_OUTPUT_TO_US, NULL, NULL, NULL); @@ -2730,6 +2741,10 @@ static void handle_our_unilateral(const struct tx_parts *tx, size_t which_htlc; struct amount_asset asset = wally_tx_output_get_amount(tx->outputs[i]); struct amount_sat amt; + struct bitcoin_outpoint outpoint; + + outpoint.txid = tx->txid; + outpoint.n = i; assert(amount_asset_is_main(&asset)); amt = amount_asset_to_sat(&asset); @@ -2740,8 +2755,8 @@ static void handle_our_unilateral(const struct tx_parts *tx, /* An empty script simply means that that this is a * fee output. */ out = new_tracked_output(&outs, - &tx->txid, tx_blockheight, - OUR_UNILATERAL, i, + &outpoint, tx_blockheight, + OUR_UNILATERAL, amt, ELEMENTS_FEE, NULL, NULL, NULL); @@ -2750,8 +2765,8 @@ static void handle_our_unilateral(const struct tx_parts *tx, } else if (script[LOCAL] && wally_tx_output_scripteq(tx->outputs[i], script[LOCAL])) { - our_unilateral_to_us(&outs, tx, tx_blockheight, - i, amt, to_self_delay[LOCAL], + our_unilateral_to_us(&outs, &outpoint, tx_blockheight, + amt, to_self_delay[LOCAL], script[LOCAL], local_wscript, is_replay); @@ -2769,8 +2784,9 @@ static void handle_our_unilateral(const struct tx_parts *tx, * node, as `to_remote` is considered *resolved* * by the commitment transaction itself. */ - out = new_tracked_output(&outs, &tx->txid, tx_blockheight, - OUR_UNILATERAL, i, + out = new_tracked_output(&outs, &outpoint, + tx_blockheight, + OUR_UNILATERAL, amt, OUTPUT_TO_THEM, NULL, NULL, NULL); @@ -2783,9 +2799,9 @@ static void handle_our_unilateral(const struct tx_parts *tx, && wally_tx_output_scripteq(tx->outputs[i], anchor[LOCAL])) { /* FIXME: We should be able to spend this! */ - out = new_tracked_output(&outs, &tx->txid, + out = new_tracked_output(&outs, &outpoint, tx_blockheight, - OUR_UNILATERAL, i, + OUR_UNILATERAL, amt, ANCHOR_TO_US, NULL, NULL, NULL); @@ -2796,9 +2812,9 @@ static void handle_our_unilateral(const struct tx_parts *tx, if (anchor[REMOTE] && wally_tx_output_scripteq(tx->outputs[i], anchor[REMOTE])) { - out = new_tracked_output(&outs, &tx->txid, + out = new_tracked_output(&outs, &outpoint, tx_blockheight, - OUR_UNILATERAL, i, + OUR_UNILATERAL, amt, ANCHOR_TO_THEM, NULL, NULL, NULL); @@ -2833,9 +2849,9 @@ static void handle_our_unilateral(const struct tx_parts *tx, script[LOCAL])) continue; - our_unilateral_to_us(&outs, tx, + our_unilateral_to_us(&outs, &outpoint, tx_blockheight, - i, amt, + amt, max_unsigned(to_self_delay[LOCAL], csv), script[LOCAL], local_wscript, @@ -2868,8 +2884,10 @@ static void handle_our_unilateral(const struct tx_parts *tx, * node, as `to_remote` is considered *resolved* * by the commitment transaction itself. */ - out = new_tracked_output(&outs, &tx->txid, tx_blockheight, - OUR_UNILATERAL, i, + out = new_tracked_output(&outs, + &outpoint, + tx_blockheight, + OUR_UNILATERAL, amt, OUTPUT_TO_THEM, NULL, NULL, NULL); @@ -2885,7 +2903,7 @@ static void handle_our_unilateral(const struct tx_parts *tx, if (found) continue; - onchain_annotate_txout(&tx->txid, i, TX_CHANNEL_PENALTY | TX_THEIRS); + onchain_annotate_txout(&outpoint, TX_CHANNEL_PENALTY | TX_THEIRS); status_failed(STATUS_FAIL_INTERNAL_ERROR, "Could not find resolution for output %zu", i); @@ -2898,9 +2916,9 @@ static void handle_our_unilateral(const struct tx_parts *tx, * in [HTLC Output Handling: Local Commitment, * Local Offers] */ - out = new_tracked_output(&outs, &tx->txid, + out = new_tracked_output(&outs, &outpoint, tx_blockheight, - OUR_UNILATERAL, i, + OUR_UNILATERAL, amt, OUR_HTLC, NULL, NULL, @@ -2912,9 +2930,9 @@ static void handle_our_unilateral(const struct tx_parts *tx, is_replay); add_amt(&our_outs, amt); } else { - out = new_tracked_output(&outs, &tx->txid, + out = new_tracked_output(&outs, &outpoint, tx_blockheight, - OUR_UNILATERAL, i, + OUR_UNILATERAL, amt, THEIR_HTLC, NULL, NULL, @@ -3002,14 +3020,14 @@ static void steal_htlc(struct tracked_output *out, bool is_replay) /* Tell wallet that we have discovered a UTXO from a to-remote output, * which it can spend with a little additional info we give here. */ static void tell_wallet_to_remote(const struct tx_parts *tx, - unsigned int outnum, + const struct bitcoin_outpoint *outpoint, u32 tx_blockheight, const u8 *scriptpubkey, const struct pubkey *per_commit_point, bool option_static_remotekey, u32 csv_lock) { - struct amount_asset asset = wally_tx_output_get_amount(tx->outputs[outnum]); + struct amount_asset asset = wally_tx_output_get_amount(tx->outputs[outpoint->n]); struct amount_sat amt; assert(amount_asset_is_main(&asset)); @@ -3021,7 +3039,7 @@ static void tell_wallet_to_remote(const struct tx_parts *tx, per_commit_point = NULL; wire_sync_write(REQ_FD, - take(towire_onchaind_add_utxo(NULL, &tx->txid, outnum, + take(towire_onchaind_add_utxo(NULL, outpoint, per_commit_point, amt, tx_blockheight, @@ -3056,14 +3074,14 @@ static void update_ledger_cheat(const struct bitcoin_txid *txid, /* add the difference to our ledger balance */ send_coin_mvt(take(new_coin_journal_entry(NULL, NULL, txid, - &out->txid, out->outnum, + &out->outpoint, blockheight, amt, true))); } static void their_unilateral_local(struct tracked_output ***outs, const struct tx_parts *tx, + const struct bitcoin_outpoint *outpoint, u32 tx_blockheight, - size_t index, struct amount_sat amt, const u8 *local_scriptpubkey, enum tx_type tx_type, @@ -3080,10 +3098,10 @@ static void their_unilateral_local(struct tracked_output ***outs, * commitment transaction itself. */ out = new_tracked_output(outs, - &tx->txid, + outpoint, tx_blockheight, tx_type, - index, amt, + amt, OUTPUT_TO_US, NULL, NULL, NULL); @@ -3092,7 +3110,7 @@ static void their_unilateral_local(struct tracked_output ***outs, if (!is_replay) record_channel_withdrawal(&tx->txid, tx_blockheight, out); - tell_wallet_to_remote(tx, index, + tell_wallet_to_remote(tx, outpoint, tx_blockheight, local_scriptpubkey, remote_per_commitment_point, @@ -3252,6 +3270,11 @@ static void handle_their_cheat(const struct tx_parts *tx, size_t which_htlc; struct amount_asset asset = wally_tx_output_get_amount(tx->outputs[i]); struct amount_sat amt; + struct bitcoin_outpoint outpoint; + + outpoint.txid = tx->txid; + outpoint.n = i; + assert(amount_asset_is_main(&asset)); amt = amount_asset_to_sat(&asset); @@ -3259,8 +3282,9 @@ static void handle_their_cheat(const struct tx_parts *tx, && tx->outputs[i]->script_len == 0) { /* An empty script simply means that that this is a * fee output. */ - out = new_tracked_output(&outs, &tx->txid, tx_blockheight, - THEIR_REVOKED_UNILATERAL, i, + out = new_tracked_output(&outs, &outpoint, + tx_blockheight, + THEIR_REVOKED_UNILATERAL, amt, ELEMENTS_FEE, NULL, NULL, NULL); @@ -3271,8 +3295,9 @@ static void handle_their_cheat(const struct tx_parts *tx, if (script[LOCAL] && wally_tx_output_scripteq(tx->outputs[i], script[LOCAL])) { - their_unilateral_local(&outs, tx, tx_blockheight, - i, amt, script[LOCAL], + their_unilateral_local(&outs, tx, &outpoint, + tx_blockheight, + amt, script[LOCAL], THEIR_REVOKED_UNILATERAL, is_replay, 1); script[LOCAL] = NULL; @@ -3287,8 +3312,9 @@ static void handle_their_cheat(const struct tx_parts *tx, * - MUST *resolve* the _remote node's main output_ by * spending it using the revocation private key. */ - out = new_tracked_output(&outs, &tx->txid, tx_blockheight, - THEIR_REVOKED_UNILATERAL, i, + out = new_tracked_output(&outs, &outpoint, + tx_blockheight, + THEIR_REVOKED_UNILATERAL, amt, DELAYED_CHEAT_OUTPUT_TO_THEM, NULL, NULL, NULL); @@ -3301,9 +3327,9 @@ static void handle_their_cheat(const struct tx_parts *tx, && wally_tx_output_scripteq(tx->outputs[i], anchor[LOCAL])) { /* FIXME: We should be able to spend this! */ - out = new_tracked_output(&outs, &tx->txid, + out = new_tracked_output(&outs, &outpoint, tx_blockheight, - THEIR_REVOKED_UNILATERAL, i, + THEIR_REVOKED_UNILATERAL, amt, ANCHOR_TO_US, NULL, NULL, NULL); @@ -3314,9 +3340,9 @@ static void handle_their_cheat(const struct tx_parts *tx, if (anchor[REMOTE] && wally_tx_output_scripteq(tx->outputs[i], anchor[REMOTE])) { - out = new_tracked_output(&outs, &tx->txid, + out = new_tracked_output(&outs, &outpoint, tx_blockheight, - THEIR_REVOKED_UNILATERAL, i, + THEIR_REVOKED_UNILATERAL, amt, ANCHOR_TO_THEM, NULL, NULL, NULL); @@ -3345,8 +3371,9 @@ static void handle_their_cheat(const struct tx_parts *tx, continue; their_unilateral_local(&outs, tx, + &outpoint, tx_blockheight, - i, amt, + amt, script[LOCAL], THEIR_REVOKED_UNILATERAL, is_replay, @@ -3374,8 +3401,10 @@ static void handle_their_cheat(const struct tx_parts *tx, if (!wally_tx_output_scripteq(tx->outputs[i], script[REMOTE])) continue; - out = new_tracked_output(&outs, &tx->txid, tx_blockheight, - THEIR_REVOKED_UNILATERAL, i, + out = new_tracked_output(&outs, + &outpoint, + tx_blockheight, + THEIR_REVOKED_UNILATERAL, amt, DELAYED_CHEAT_OUTPUT_TO_THEM, NULL, NULL, NULL); @@ -3406,9 +3435,9 @@ static void handle_their_cheat(const struct tx_parts *tx, * * spend the *commitment tx* once the HTLC timeout has passed. * * spend the *HTLC-success tx*, if the remote node has published it. */ - out = new_tracked_output(&outs, &tx->txid, + out = new_tracked_output(&outs, &outpoint, tx_blockheight, - THEIR_REVOKED_UNILATERAL, i, + THEIR_REVOKED_UNILATERAL, amt, OUR_HTLC, &htlcs[which_htlc], @@ -3417,9 +3446,9 @@ static void handle_their_cheat(const struct tx_parts *tx, steal_htlc(out, is_replay); add_amt(&total_outs, amt); } else { - out = new_tracked_output(&outs, &tx->txid, + out = new_tracked_output(&outs, &outpoint, tx_blockheight, - THEIR_REVOKED_UNILATERAL, i, + THEIR_REVOKED_UNILATERAL, amt, THEIR_HTLC, &htlcs[which_htlc], @@ -3580,15 +3609,21 @@ static void handle_their_unilateral(const struct tx_parts *tx, size_t which_htlc; struct amount_asset asset = wally_tx_output_get_amount(tx->outputs[i]); struct amount_sat amt; + struct bitcoin_outpoint outpoint; + assert(amount_asset_is_main(&asset)); amt = amount_asset_to_sat(&asset); + outpoint.txid = tx->txid; + outpoint.n = i; + if (chainparams->is_elements && tx->outputs[i]->script_len == 0) { /* An empty script simply means that that this is a * fee output. */ - out = new_tracked_output(&outs, &tx->txid, tx_blockheight, - THEIR_UNILATERAL, i, + out = new_tracked_output(&outs, &outpoint, + tx_blockheight, + THEIR_UNILATERAL, amt, ELEMENTS_FEE, NULL, NULL, NULL); @@ -3597,8 +3632,9 @@ static void handle_their_unilateral(const struct tx_parts *tx, } else if (script[LOCAL] && wally_tx_output_scripteq(tx->outputs[i], script[LOCAL])) { - their_unilateral_local(&outs, tx, tx_blockheight, - i, amt, script[LOCAL], + their_unilateral_local(&outs, tx, &outpoint, + tx_blockheight, + amt, script[LOCAL], THEIR_UNILATERAL, is_replay, 1); @@ -3617,8 +3653,9 @@ static void handle_their_unilateral(const struct tx_parts *tx, * - Note: `to_local` is considered *resolved* by the * commitment transaction itself. */ - out = new_tracked_output(&outs, &tx->txid, tx_blockheight, - THEIR_UNILATERAL, i, + out = new_tracked_output(&outs, &outpoint, + tx_blockheight, + THEIR_UNILATERAL, amt, DELAYED_OUTPUT_TO_THEM, NULL, NULL, NULL); @@ -3630,9 +3667,9 @@ static void handle_their_unilateral(const struct tx_parts *tx, && wally_tx_output_scripteq(tx->outputs[i], anchor[LOCAL])) { /* FIXME: We should be able to spend this! */ - out = new_tracked_output(&outs, &tx->txid, + out = new_tracked_output(&outs, &outpoint, tx_blockheight, - THEIR_UNILATERAL, i, + THEIR_UNILATERAL, amt, ANCHOR_TO_US, NULL, NULL, NULL); @@ -3643,9 +3680,9 @@ static void handle_their_unilateral(const struct tx_parts *tx, if (anchor[REMOTE] && wally_tx_output_scripteq(tx->outputs[i], anchor[REMOTE])) { - out = new_tracked_output(&outs, &tx->txid, + out = new_tracked_output(&outs, &outpoint, tx_blockheight, - THEIR_UNILATERAL, i, + THEIR_UNILATERAL, amt, ANCHOR_TO_THEM, NULL, NULL, NULL); @@ -3676,8 +3713,9 @@ static void handle_their_unilateral(const struct tx_parts *tx, continue; their_unilateral_local(&outs, tx, + &outpoint, tx_blockheight, - i, amt, + amt, script[LOCAL], THEIR_UNILATERAL, is_replay, csv); @@ -3705,8 +3743,10 @@ static void handle_their_unilateral(const struct tx_parts *tx, if (!wally_tx_output_scripteq(tx->outputs[i], script[REMOTE])) continue; - out = new_tracked_output(&outs, &tx->txid, tx_blockheight, - THEIR_UNILATERAL, i, + out = new_tracked_output(&outs, + &outpoint, + tx_blockheight, + THEIR_UNILATERAL, amt, DELAYED_OUTPUT_TO_THEM, NULL, NULL, NULL); @@ -3732,9 +3772,9 @@ static void handle_their_unilateral(const struct tx_parts *tx, * [HTLC Output Handling: Remote Commitment, * Local Offers] */ - out = new_tracked_output(&outs, &tx->txid, + out = new_tracked_output(&outs, &outpoint, tx_blockheight, - THEIR_UNILATERAL, i, + THEIR_UNILATERAL, amt, OUR_HTLC, NULL, NULL, @@ -3746,9 +3786,9 @@ static void handle_their_unilateral(const struct tx_parts *tx, is_replay); add_amt(&our_outs, amt); } else { - out = new_tracked_output(&outs, &tx->txid, + out = new_tracked_output(&outs, &outpoint, tx_blockheight, - THEIR_UNILATERAL, i, + THEIR_UNILATERAL, amt, THEIR_HTLC, NULL, NULL, @@ -3811,7 +3851,7 @@ static void update_ledger_unknown(const struct bitcoin_txid *txid, } else is_credit = true; - send_coin_mvt(take(new_coin_journal_entry(NULL, NULL, txid, NULL, 0, + send_coin_mvt(take(new_coin_journal_entry(NULL, NULL, txid, NULL, blockheight, diff, is_credit))); } @@ -3866,10 +3906,14 @@ static void handle_unknown_commitment(const struct tx_parts *tx, struct amount_asset asset = wally_tx_output_get_amount(tx->outputs[i]); struct amount_sat amt; int which_script; + struct bitcoin_outpoint outpoint; assert(amount_asset_is_main(&asset)); amt = amount_asset_to_sat(&asset); + outpoint.txid = tx->txid; + outpoint.n = i; + /* Elements can have empty output scripts (fee output) */ if (local_scripts[0] && wally_tx_output_scripteq(tx->outputs[i], local_scripts[0])) @@ -3889,9 +3933,10 @@ static void handle_unknown_commitment(const struct tx_parts *tx, * - Note: `to_remote` is considered *resolved* by the * commitment transaction itself. */ - out = new_tracked_output(&outs, &tx->txid, tx_blockheight, + out = new_tracked_output(&outs, &outpoint, + tx_blockheight, UNKNOWN_UNILATERAL, - i, amt, + amt, OUTPUT_TO_US, NULL, NULL, NULL); ignore_output(out); @@ -3900,7 +3945,7 @@ static void handle_unknown_commitment(const struct tx_parts *tx, add_amt(&amt_salvaged, amt); - tell_wallet_to_remote(tx, i, + tell_wallet_to_remote(tx, &outpoint, tx_blockheight, local_scripts[which_script], possible_remote_per_commitment_point, @@ -3965,9 +4010,10 @@ int main(int argc, char *argv[]) struct shachain shachain; struct tx_parts *tx; struct tracked_output **outs; - struct bitcoin_txid our_broadcast_txid, tmptxid; + struct bitcoin_outpoint funding; + struct bitcoin_txid our_broadcast_txid; struct bitcoin_signature *remote_htlc_sigs; - struct amount_sat funding; + struct amount_sat funding_sats; u64 num_htlcs; u8 *scriptpubkey[NUM_SIDES]; struct htlc_stub *htlcs; @@ -3987,7 +4033,7 @@ int main(int argc, char *argv[]) if (!fromwire_onchaind_init(tmpctx, msg, &shachain, &chainparams, - &funding, + &funding_sats, &our_msat, &old_remote_per_commit_point, &remote_per_commit_point, @@ -4049,12 +4095,12 @@ int main(int argc, char *argv[]) asort(htlcs, tal_count(htlcs), cmp_htlc_cltv, NULL); outs = tal_arr(ctx, struct tracked_output *, 0); - wally_tx_input_get_txid(tx->inputs[0], &tmptxid); - new_tracked_output(&outs, &tmptxid, + wally_tx_input_get_txid(tx->inputs[0], &funding.txid); + funding.n = tx->inputs[0]->index; + new_tracked_output(&outs, &funding, 0, /* We don't care about funding blockheight */ FUNDING_TRANSACTION, - tx->inputs[0]->index, - funding, + funding_sats, FUNDING_OUTPUT, NULL, NULL, NULL); status_debug("Remote per-commit point: %s", @@ -4064,7 +4110,7 @@ int main(int argc, char *argv[]) type_to_string(tmpctx, struct pubkey, &old_remote_per_commit_point)); - trim_maximum_feerate(funding, tx); + trim_maximum_feerate(funding_sats, tx); /* BOLT #5: * diff --git a/onchaind/onchaind_wire.csv b/onchaind/onchaind_wire.csv index 694ac7498dd4..ee24243af263 100644 --- a/onchaind/onchaind_wire.csv +++ b/onchaind/onchaind_wire.csv @@ -112,8 +112,7 @@ msgtype,onchaind_all_irrevocably_resolved,5011 # onchaind->master: hey, I identified an UTXO you'll want to track msgtype,onchaind_add_utxo,5012 -msgdata,onchaind_add_utxo,prev_out_tx,bitcoin_txid, -msgdata,onchaind_add_utxo,prev_out_index,u32, +msgdata,onchaind_add_utxo,prev_out,bitcoin_outpoint, msgdata,onchaind_add_utxo,per_commit_point,?pubkey, msgdata,onchaind_add_utxo,value,amount_sat, msgdata,onchaind_add_utxo,blockheight,u32, @@ -131,8 +130,7 @@ msgdata,onchaind_dev_memleak_reply,leak,bool, # that we tracked automatically but only onchaind knows how to classify their # transactions. msgtype,onchaind_annotate_txout,5035 -msgdata,onchaind_annotate_txout,txid,bitcoin_txid, -msgdata,onchaind_annotate_txout,outnum,u32, +msgdata,onchaind_annotate_txout,outpoint,bitcoin_outpoint, msgdata,onchaind_annotate_txout,type,enum wallet_tx_type, msgtype,onchaind_annotate_txin,5036 diff --git a/onchaind/test/run-grind_feerate-bug.c b/onchaind/test/run-grind_feerate-bug.c index e8e7f30929f6..9d393069b530 100644 --- a/onchaind/test/run-grind_feerate-bug.c +++ b/onchaind/test/run-grind_feerate-bug.c @@ -101,8 +101,7 @@ u8 *htlc_received_wscript(const tal_t *ctx UNNEEDED, /* Generated stub for htlc_success_tx */ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx UNNEEDED, const struct chainparams *chainparams UNNEEDED, - const struct bitcoin_txid *commit_txid UNNEEDED, - unsigned int commit_output_number UNNEEDED, + const struct bitcoin_outpoint *commit UNNEEDED, const u8 *commit_wscript UNNEEDED, struct amount_msat htlc_msatoshi UNNEEDED, u16 to_self_delay UNNEEDED, @@ -131,8 +130,7 @@ struct chain_coin_mvt *new_coin_chain_fees_sat(const tal_t *ctx UNNEEDED, struct chain_coin_mvt *new_coin_journal_entry(const tal_t *ctx UNNEEDED, const char *account_name UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, - const struct bitcoin_txid *out_txid UNNEEDED, - u32 vout UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, u32 blockheight UNNEEDED, struct amount_msat amount UNNEEDED, bool is_credit UNNEEDED) @@ -141,8 +139,7 @@ struct chain_coin_mvt *new_coin_journal_entry(const tal_t *ctx UNNEEDED, struct chain_coin_mvt *new_coin_onchain_htlc_sat(const tal_t *ctx UNNEEDED, const char *account_name UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, - const struct bitcoin_txid *out_txid UNNEEDED, - u32 vout UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, struct sha256 payment_hash UNNEEDED, u32 blockheight UNNEEDED, struct amount_sat amount UNNEEDED, @@ -152,26 +149,23 @@ struct chain_coin_mvt *new_coin_onchain_htlc_sat(const tal_t *ctx UNNEEDED, struct chain_coin_mvt *new_coin_penalty_sat(const tal_t *ctx UNNEEDED, const char *account_name UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, - const struct bitcoin_txid *out_txid UNNEEDED, - u32 vout UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, u32 blockheight UNNEEDED, struct amount_sat amount UNNEEDED) { fprintf(stderr, "new_coin_penalty_sat called!\n"); abort(); } /* Generated stub for new_coin_withdrawal */ struct chain_coin_mvt *new_coin_withdrawal(const tal_t *ctx UNNEEDED, - const char *account_name UNNEEDED, - const struct bitcoin_txid *tx_txid UNNEEDED, - const struct bitcoin_txid *out_txid UNNEEDED, - u32 vout UNNEEDED, - u32 blockheight UNNEEDED, - struct amount_msat amount UNNEEDED) + const char *account_name UNNEEDED, + const struct bitcoin_txid *tx_txid UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, + u32 blockheight UNNEEDED, + struct amount_msat amount UNNEEDED) { fprintf(stderr, "new_coin_withdrawal called!\n"); abort(); } /* Generated stub for new_coin_withdrawal_sat */ struct chain_coin_mvt *new_coin_withdrawal_sat(const tal_t *ctx UNNEEDED, const char *account_name UNNEEDED, const struct bitcoin_txid *tx_txid UNNEEDED, - const struct bitcoin_txid *out_txid UNNEEDED, - u32 vout UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, u32 blockheight UNNEEDED, struct amount_sat amount UNNEEDED) { fprintf(stderr, "new_coin_withdrawal_sat called!\n"); abort(); } @@ -224,7 +218,7 @@ u8 *towire_hsmd_sign_penalty_to_us(const tal_t *ctx UNNEEDED, const struct secre u8 *towire_hsmd_sign_remote_htlc_to_us(const tal_t *ctx UNNEEDED, const struct pubkey *remote_per_commitment_point UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, bool option_anchor_outputs UNNEEDED) { fprintf(stderr, "towire_hsmd_sign_remote_htlc_to_us called!\n"); abort(); } /* Generated stub for towire_onchaind_add_utxo */ -u8 *towire_onchaind_add_utxo(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *prev_out_tx UNNEEDED, u32 prev_out_index UNNEEDED, const struct pubkey *per_commit_point UNNEEDED, struct amount_sat value UNNEEDED, u32 blockheight UNNEEDED, const u8 *scriptpubkey UNNEEDED, u32 csv_lock UNNEEDED) +u8 *towire_onchaind_add_utxo(const tal_t *ctx UNNEEDED, const struct bitcoin_outpoint *prev_out UNNEEDED, const struct pubkey *per_commit_point UNNEEDED, struct amount_sat value UNNEEDED, u32 blockheight UNNEEDED, const u8 *scriptpubkey UNNEEDED, u32 csv_lock UNNEEDED) { fprintf(stderr, "towire_onchaind_add_utxo called!\n"); abort(); } /* Generated stub for towire_onchaind_all_irrevocably_resolved */ u8 *towire_onchaind_all_irrevocably_resolved(const tal_t *ctx UNNEEDED) @@ -233,7 +227,7 @@ u8 *towire_onchaind_all_irrevocably_resolved(const tal_t *ctx UNNEEDED) u8 *towire_onchaind_annotate_txin(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, u32 innum UNNEEDED, enum wallet_tx_type type UNNEEDED) { fprintf(stderr, "towire_onchaind_annotate_txin called!\n"); abort(); } /* Generated stub for towire_onchaind_annotate_txout */ -u8 *towire_onchaind_annotate_txout(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, u32 outnum UNNEEDED, enum wallet_tx_type type UNNEEDED) +u8 *towire_onchaind_annotate_txout(const tal_t *ctx UNNEEDED, const struct bitcoin_outpoint *outpoint UNNEEDED, enum wallet_tx_type type UNNEEDED) { fprintf(stderr, "towire_onchaind_annotate_txout called!\n"); abort(); } /* Generated stub for towire_onchaind_broadcast_tx */ u8 *towire_onchaind_broadcast_tx(const tal_t *ctx UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, enum wallet_tx_type type UNNEEDED, bool is_rbf UNNEEDED) @@ -349,8 +343,7 @@ static void signature_from_hex(const char *hex, struct bitcoin_signature *sig) * an example tx, so just mangle that. */ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx, const struct chainparams *chainparams, - const struct bitcoin_txid *commit_txid UNNEEDED, - unsigned int commit_output_number UNNEEDED, + const struct bitcoin_outpoint *commit UNNEEDED, const u8* commit_wscript, struct amount_msat htlc_msatoshi, u32 cltv_expiry, @@ -401,8 +394,8 @@ int main(int argc, char *argv[]) /* talz keeps valgrind happy. */ out = talz(tmpctx, struct tracked_output); - bitcoin_txid_from_hex("722983619428e0759d41c75cc29cd6184b09b335a0a20437964155ecc6382aa0", strlen("722983619428e0759d41c75cc29cd6184b09b335a0a20437964155ecc6382aa0"), &out->txid); - out->outnum = 0; + bitcoin_txid_from_hex("722983619428e0759d41c75cc29cd6184b09b335a0a20437964155ecc6382aa0", strlen("722983619428e0759d41c75cc29cd6184b09b335a0a20437964155ecc6382aa0"), &out->outpoint.txid); + out->outpoint.n = 0; if (!parse_amount_sat(&out->sat, "3215967sat", strlen("3215967sat"))) abort(); signature_from_hex("3045022100917efdc8577e8578aef5e513fad25edbb55921466e8ffccb05ce8bb05a54ae6902205c2fded9d7bfc290920821bfc828720bc24287f3dad9a62fb4f806e2404ed0f401", &remotesig); diff --git a/onchaind/test/run-grind_feerate.c b/onchaind/test/run-grind_feerate.c index 5cc725f6fdb0..c89cca79ec02 100644 --- a/onchaind/test/run-grind_feerate.c +++ b/onchaind/test/run-grind_feerate.c @@ -103,8 +103,7 @@ u8 *htlc_received_wscript(const tal_t *ctx UNNEEDED, /* Generated stub for htlc_success_tx */ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx UNNEEDED, const struct chainparams *chainparams UNNEEDED, - const struct bitcoin_txid *commit_txid UNNEEDED, - unsigned int commit_output_number UNNEEDED, + const struct bitcoin_outpoint *commit UNNEEDED, const u8 *commit_wscript UNNEEDED, struct amount_msat htlc_msatoshi UNNEEDED, u16 to_self_delay UNNEEDED, @@ -115,8 +114,7 @@ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx UNNEEDED, /* Generated stub for htlc_timeout_tx */ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx UNNEEDED, const struct chainparams *chainparams UNNEEDED, - const struct bitcoin_txid *commit_txid UNNEEDED, - unsigned int commit_output_number UNNEEDED, + const struct bitcoin_outpoint *commit UNNEEDED, const u8 *commit_wscript UNNEEDED, struct amount_msat htlc_msatoshi UNNEEDED, u32 cltv_expiry UNNEEDED, @@ -155,8 +153,7 @@ struct chain_coin_mvt *new_coin_chain_fees_sat(const tal_t *ctx UNNEEDED, struct chain_coin_mvt *new_coin_journal_entry(const tal_t *ctx UNNEEDED, const char *account_name UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, - const struct bitcoin_txid *out_txid UNNEEDED, - u32 vout UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, u32 blockheight UNNEEDED, struct amount_msat amount UNNEEDED, bool is_credit UNNEEDED) @@ -165,8 +162,7 @@ struct chain_coin_mvt *new_coin_journal_entry(const tal_t *ctx UNNEEDED, struct chain_coin_mvt *new_coin_onchain_htlc_sat(const tal_t *ctx UNNEEDED, const char *account_name UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, - const struct bitcoin_txid *out_txid UNNEEDED, - u32 vout UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, struct sha256 payment_hash UNNEEDED, u32 blockheight UNNEEDED, struct amount_sat amount UNNEEDED, @@ -176,26 +172,23 @@ struct chain_coin_mvt *new_coin_onchain_htlc_sat(const tal_t *ctx UNNEEDED, struct chain_coin_mvt *new_coin_penalty_sat(const tal_t *ctx UNNEEDED, const char *account_name UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, - const struct bitcoin_txid *out_txid UNNEEDED, - u32 vout UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, u32 blockheight UNNEEDED, struct amount_sat amount UNNEEDED) { fprintf(stderr, "new_coin_penalty_sat called!\n"); abort(); } /* Generated stub for new_coin_withdrawal */ struct chain_coin_mvt *new_coin_withdrawal(const tal_t *ctx UNNEEDED, - const char *account_name UNNEEDED, - const struct bitcoin_txid *tx_txid UNNEEDED, - const struct bitcoin_txid *out_txid UNNEEDED, - u32 vout UNNEEDED, - u32 blockheight UNNEEDED, - struct amount_msat amount UNNEEDED) + const char *account_name UNNEEDED, + const struct bitcoin_txid *tx_txid UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, + u32 blockheight UNNEEDED, + struct amount_msat amount UNNEEDED) { fprintf(stderr, "new_coin_withdrawal called!\n"); abort(); } /* Generated stub for new_coin_withdrawal_sat */ struct chain_coin_mvt *new_coin_withdrawal_sat(const tal_t *ctx UNNEEDED, const char *account_name UNNEEDED, const struct bitcoin_txid *tx_txid UNNEEDED, - const struct bitcoin_txid *out_txid UNNEEDED, - u32 vout UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, u32 blockheight UNNEEDED, struct amount_sat amount UNNEEDED) { fprintf(stderr, "new_coin_withdrawal_sat called!\n"); abort(); } @@ -254,7 +247,7 @@ u8 *towire_hsmd_sign_penalty_to_us(const tal_t *ctx UNNEEDED, const struct secre u8 *towire_hsmd_sign_remote_htlc_to_us(const tal_t *ctx UNNEEDED, const struct pubkey *remote_per_commitment_point UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, bool option_anchor_outputs UNNEEDED) { fprintf(stderr, "towire_hsmd_sign_remote_htlc_to_us called!\n"); abort(); } /* Generated stub for towire_onchaind_add_utxo */ -u8 *towire_onchaind_add_utxo(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *prev_out_tx UNNEEDED, u32 prev_out_index UNNEEDED, const struct pubkey *per_commit_point UNNEEDED, struct amount_sat value UNNEEDED, u32 blockheight UNNEEDED, const u8 *scriptpubkey UNNEEDED, u32 csv_lock UNNEEDED) +u8 *towire_onchaind_add_utxo(const tal_t *ctx UNNEEDED, const struct bitcoin_outpoint *prev_out UNNEEDED, const struct pubkey *per_commit_point UNNEEDED, struct amount_sat value UNNEEDED, u32 blockheight UNNEEDED, const u8 *scriptpubkey UNNEEDED, u32 csv_lock UNNEEDED) { fprintf(stderr, "towire_onchaind_add_utxo called!\n"); abort(); } /* Generated stub for towire_onchaind_all_irrevocably_resolved */ u8 *towire_onchaind_all_irrevocably_resolved(const tal_t *ctx UNNEEDED) @@ -263,7 +256,7 @@ u8 *towire_onchaind_all_irrevocably_resolved(const tal_t *ctx UNNEEDED) u8 *towire_onchaind_annotate_txin(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, u32 innum UNNEEDED, enum wallet_tx_type type UNNEEDED) { fprintf(stderr, "towire_onchaind_annotate_txin called!\n"); abort(); } /* Generated stub for towire_onchaind_annotate_txout */ -u8 *towire_onchaind_annotate_txout(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, u32 outnum UNNEEDED, enum wallet_tx_type type UNNEEDED) +u8 *towire_onchaind_annotate_txout(const tal_t *ctx UNNEEDED, const struct bitcoin_outpoint *outpoint UNNEEDED, enum wallet_tx_type type UNNEEDED) { fprintf(stderr, "towire_onchaind_annotate_txout called!\n"); abort(); } /* Generated stub for towire_onchaind_broadcast_tx */ u8 *towire_onchaind_broadcast_tx(const tal_t *ctx UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, enum wallet_tx_type type UNNEEDED, bool is_rbf UNNEEDED) diff --git a/onchaind/test/run-onchainstress.c b/onchaind/test/run-onchainstress.c index 0044a3e9feb8..e79e6d50a8a2 100644 --- a/onchaind/test/run-onchainstress.c +++ b/onchaind/test/run-onchainstress.c @@ -49,19 +49,17 @@ struct htable *memleak_find_allocations(const tal_t *ctx UNNEEDED, struct chain_coin_mvt *new_coin_penalty_sat(const tal_t *ctx UNNEEDED, const char *account_name UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, - const struct bitcoin_txid *out_txid UNNEEDED, - u32 vout UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, u32 blockheight UNNEEDED, struct amount_sat amount UNNEEDED) { fprintf(stderr, "new_coin_penalty_sat called!\n"); abort(); } /* Generated stub for new_coin_withdrawal */ struct chain_coin_mvt *new_coin_withdrawal(const tal_t *ctx UNNEEDED, - const char *account_name UNNEEDED, - const struct bitcoin_txid *tx_txid UNNEEDED, - const struct bitcoin_txid *out_txid UNNEEDED, - u32 vout UNNEEDED, - u32 blockheight UNNEEDED, - struct amount_msat amount UNNEEDED) + const char *account_name UNNEEDED, + const struct bitcoin_txid *tx_txid UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, + u32 blockheight UNNEEDED, + struct amount_msat amount UNNEEDED) { fprintf(stderr, "new_coin_withdrawal called!\n"); abort(); } /* Generated stub for status_failed */ void status_failed(enum status_failreason code UNNEEDED, @@ -91,7 +89,6 @@ void towire_utxo(u8 **pptr UNNEEDED, const struct utxo *utxo UNNEEDED) const char *version(void) { fprintf(stderr, "version called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ - #if DEVELOPER /* Generated stub for dev_disconnect_init */ void dev_disconnect_init(int fd UNNEEDED) @@ -150,8 +147,7 @@ struct chain_coin_mvt *new_coin_chain_fees_sat(const tal_t *ctx UNNEEDED, struct chain_coin_mvt *new_coin_journal_entry(const tal_t *ctx UNNEEDED, const char *account_name UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, - const struct bitcoin_txid *out_txid UNNEEDED, - u32 vout UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, u32 blockheight UNNEEDED, struct amount_msat amount UNNEEDED, bool is_credit UNNEEDED) @@ -161,8 +157,7 @@ struct chain_coin_mvt *new_coin_journal_entry(const tal_t *ctx UNNEEDED, struct chain_coin_mvt *new_coin_onchain_htlc_sat(const tal_t *ctx UNNEEDED, const char *account_name UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, - const struct bitcoin_txid *out_txid UNNEEDED, - u32 vout UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, struct sha256 payment_hash UNNEEDED, u32 blockheight UNNEEDED, struct amount_sat amount UNNEEDED, @@ -173,8 +168,7 @@ struct chain_coin_mvt *new_coin_onchain_htlc_sat(const tal_t *ctx UNNEEDED, struct chain_coin_mvt *new_coin_withdrawal_sat(const tal_t *ctx UNNEEDED, const char *account_name UNNEEDED, const struct bitcoin_txid *tx_txid UNNEEDED, - const struct bitcoin_txid *out_txid UNNEEDED, - u32 vout UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, u32 blockheight UNNEEDED, struct amount_sat amount UNNEEDED) { diff --git a/openingd/dualopend.c b/openingd/dualopend.c index 7b8497d3423a..022c52e7312c 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -82,8 +82,7 @@ struct tx_state { u32 tx_locktime; u32 feerate_per_kw_funding; - struct bitcoin_txid funding_txid; - u16 funding_txout; + struct bitcoin_outpoint funding; /* This is a cluster of fields in open_channel and accept_channel which * indicate the restrictions each side places on the channel. */ @@ -545,7 +544,7 @@ static size_t psbt_output_weight(struct wally_psbt *psbt, varint_size(psbt->tx->outputs[outnum].script_len)) * 4; } -static bool find_txout(struct wally_psbt *psbt, const u8 *wscript, u16 *funding_txout) +static bool find_txout(struct wally_psbt *psbt, const u8 *wscript, u32 *funding_txout) { for (size_t i = 0; i < psbt->num_outputs; i++) { if (memeq(wscript, tal_bytelen(wscript), psbt->tx->outputs[i].script, @@ -571,7 +570,7 @@ static char *check_balances(const tal_t *ctx, initiator_diff, accepter_diff; bool ok; - u16 funding_outnum = psbt->num_outputs; + u32 funding_outnum = psbt->num_outputs; size_t accepter_weight = 0; @@ -904,7 +903,7 @@ static u8 *psbt_to_tx_sigs_msg(const tal_t *ctx, state->our_role); return towire_tx_signatures(ctx, &state->channel_id, - &state->tx_state->funding_txid, + &state->tx_state->funding.txid, ws); } @@ -951,7 +950,7 @@ static void handle_tx_sigs(struct state *state, const u8 *msg) &txid)); - if (!bitcoin_txid_eq(&tx_state->funding_txid, &txid)) + if (!bitcoin_txid_eq(&tx_state->funding.txid, &txid)) open_err_warn(state, "tx_signatures for %s received," "working on funding_txid %s", @@ -960,7 +959,7 @@ static void handle_tx_sigs(struct state *state, const u8 *msg) &txid), type_to_string(tmpctx, struct bitcoin_txid, - &tx_state->funding_txid)); + &tx_state->funding.txid)); /* We put the PSBT + sigs all together */ for (size_t i = 0; i < tx_state->psbt->num_inputs; i++) { @@ -1006,13 +1005,13 @@ static void handle_send_tx_sigs(struct state *state, const u8 *msg) /* Check that we've got the same / correct PSBT */ psbt_txid(NULL, psbt, &txid, NULL); - if (!bitcoin_txid_eq(&txid, &tx_state->funding_txid)) + if (!bitcoin_txid_eq(&txid, &tx_state->funding.txid)) status_failed(STATUS_FAIL_INTERNAL_ERROR, "TXID for passed in PSBT does not match" " funding txid for channel. Expected %s, " "received %s", type_to_string(tmpctx, struct bitcoin_txid, - &tx_state->funding_txid), + &tx_state->funding.txid), type_to_string(tmpctx, struct bitcoin_txid, &txid)); @@ -1339,17 +1338,17 @@ static bool run_tx_interactive(struct state *state, switch (t) { case WIRE_TX_ADD_INPUT: { const u8 *tx_bytes, *redeemscript; - u32 outnum, sequence; + u32 sequence; size_t len; struct bitcoin_tx *tx; - struct bitcoin_txid txid; + struct bitcoin_outpoint outpoint; struct amount_sat amt; if (!fromwire_tx_add_input(tmpctx, msg, &cid, &serial_id, cast_const2(u8 **, &tx_bytes), - &outnum, &sequence, + &outpoint.n, &sequence, cast_const2(u8 **, &redeemscript))) open_err_fatal(state, @@ -1395,10 +1394,10 @@ static bool run_tx_interactive(struct state *state, if (!tx || len != 0) open_err_warn(state, "%s", "Invalid tx sent."); - if (outnum >= tx->wtx->num_outputs) + if (outpoint.n >= tx->wtx->num_outputs) open_err_warn(state, "Invalid tx outnum sent. %u", - outnum); + outpoint.n); /* * BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: * The receiving node: ... @@ -1406,7 +1405,7 @@ static bool run_tx_interactive(struct state *state, * - the `prevtx_out` input of `prevtx` is * not an `OP_0` to `OP_16` followed by a single push */ - if (!is_segwit_output(&tx->wtx->outputs[outnum], + if (!is_segwit_output(&tx->wtx->outputs[outpoint.n], redeemscript)) open_err_warn(state, "Invalid tx sent. Not SegWit %s", @@ -1422,15 +1421,14 @@ static bool run_tx_interactive(struct state *state, * identical to a previously added (and not * removed) input's */ - bitcoin_txid(tx, &txid); - if (psbt_has_input(psbt, &txid, outnum)) + bitcoin_txid(tx, &outpoint.txid); + if (psbt_has_input(psbt, &outpoint)) open_err_warn(state, - "Unable to add input %s:%d- " + "Unable to add input %s- " "already present", type_to_string(tmpctx, - struct bitcoin_txid, - &txid), - outnum); + struct bitcoin_outpoint, + &outpoint)); /* * BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2: @@ -1438,17 +1436,16 @@ static bool run_tx_interactive(struct state *state, * - MUST add all received inputs to the transaction */ struct wally_psbt_input *in = - psbt_append_input(psbt, &txid, outnum, + psbt_append_input(psbt, &outpoint, sequence, NULL, NULL, redeemscript); if (!in) open_err_warn(state, - "Unable to add input %s:%d", + "Unable to add input %s", type_to_string(tmpctx, - struct bitcoin_txid, - &txid), - outnum); + struct bitcoin_outpoint, + &outpoint)); tal_wally_start(); wally_psbt_input_set_utxo(in, tx->wtx); @@ -1457,7 +1454,7 @@ static bool run_tx_interactive(struct state *state, if (is_elements(chainparams)) { struct amount_asset asset; - bitcoin_tx_output_get_amount_sat(tx, outnum, + bitcoin_tx_output_get_amount_sat(tx, outpoint.n, &amt); /* FIXME: persist asset tags */ @@ -1465,7 +1462,7 @@ static bool run_tx_interactive(struct state *state, chainparams->fee_asset_tag); /* FIXME: persist nonces */ psbt_elements_input_set_asset(psbt, - outnum, + outpoint.n, &asset); } @@ -1695,8 +1692,7 @@ static void revert_channel_state(struct state *state) state->our_features, state->their_features); state->channel = new_initial_channel(state, &state->channel_id, - &tx_state->funding_txid, - tx_state->funding_txout, + &tx_state->funding, state->minimum_depth, take(new_height_states(NULL, opener, &tx_state->blockheight)), @@ -1739,7 +1735,7 @@ static u8 *accepter_commits(struct state *state, const struct channel_type *type; /* Find the funding transaction txid */ - psbt_txid(NULL, tx_state->psbt, &tx_state->funding_txid, NULL); + psbt_txid(NULL, tx_state->psbt, &tx_state->funding.txid, NULL); wscript = bitcoin_redeem_2of2(state, &state->our_funding_pubkey, @@ -1748,7 +1744,7 @@ static u8 *accepter_commits(struct state *state, /* Figure out the txout */ if (!find_txout(tx_state->psbt, scriptpubkey_p2wsh(tmpctx, wscript), - &tx_state->funding_txout)) + &tx_state->funding.n)) open_err_warn(state, "Expected output %s not found on funding tx %s", tal_hex(tmpctx, @@ -1801,8 +1797,7 @@ static u8 *accepter_commits(struct state *state, state->our_features, state->their_features); state->channel = new_initial_channel(state, &state->channel_id, - &tx_state->funding_txid, - tx_state->funding_txout, + &tx_state->funding, state->minimum_depth, take(new_height_states(NULL, REMOTE, &tx_state->blockheight)), @@ -1873,7 +1868,7 @@ static u8 *accepter_commits(struct state *state, * the funding tx doesn't match up */ type_to_string(tmpctx, struct bitcoin_txid, - &tx_state->funding_txid), + &tx_state->funding.txid), type_to_string(tmpctx, struct wally_psbt, tx_state->psbt)); @@ -1926,8 +1921,7 @@ static u8 *accepter_commits(struct state *state, &state->their_points.delayed_payment, &state->first_per_commitment_point[REMOTE], &state->their_funding_pubkey, - &tx_state->funding_txid, - tx_state->funding_txout, + &tx_state->funding, total, tx_state->accepter_funding, state->channel_flags, @@ -2373,11 +2367,11 @@ static u8 *opener_commits(struct state *state, wscript = bitcoin_redeem_2of2(tmpctx, &state->our_funding_pubkey, &state->their_funding_pubkey); - psbt_txid(NULL, tx_state->psbt, &tx_state->funding_txid, NULL); + psbt_txid(NULL, tx_state->psbt, &tx_state->funding.txid, NULL); /* Figure out the txout */ if (!find_txout(tx_state->psbt, scriptpubkey_p2wsh(tmpctx, wscript), - &tx_state->funding_txout)) { + &tx_state->funding.n)) { *err_reason = tal_fmt(tmpctx, "Expected output %s not" " found on funding tx %s", tal_hex(tmpctx, @@ -2416,8 +2410,7 @@ static u8 *opener_commits(struct state *state, state->our_features, state->their_features); state->channel = new_initial_channel(state, &cid, - &tx_state->funding_txid, - tx_state->funding_txout, + &tx_state->funding, state->minimum_depth, take(new_height_states(NULL, LOCAL, &state->tx_state->blockheight)), @@ -2555,7 +2548,7 @@ static u8 *opener_commits(struct state *state, * funding tx doesn't match up */ type_to_string(tmpctx, struct bitcoin_txid, - &tx_state->funding_txid), + &tx_state->funding.txid), type_to_string(tmpctx, struct wally_psbt, tx_state->psbt)); @@ -2584,8 +2577,7 @@ static u8 *opener_commits(struct state *state, &state->their_points.delayed_payment, &state->first_per_commitment_point[REMOTE], &state->their_funding_pubkey, - &tx_state->funding_txid, - tx_state->funding_txout, + &tx_state->funding, total, tx_state->opener_funding, state->channel_flags, @@ -3016,7 +3008,7 @@ static void rbf_wrap_up(struct state *state, master_badmsg(WIRE_DUALOPEND_RBF_VALID, msg); /* Find the funding transaction txid */ - psbt_txid(NULL, tx_state->psbt, &tx_state->funding_txid, NULL); + psbt_txid(NULL, tx_state->psbt, &tx_state->funding.txid, NULL); if (state->our_role == TX_ACCEPTER) /* FIXME: lease fee rate !? */ @@ -3816,8 +3808,7 @@ int main(int argc, char *argv[]) &state->our_funding_pubkey, &state->their_funding_pubkey, &state->minimum_depth, - &state->tx_state->funding_txid, - &state->tx_state->funding_txout, + &state->tx_state->funding, &state->tx_state->feerate_per_kw_funding, &total_funding, &our_msat, @@ -3847,8 +3838,7 @@ int main(int argc, char *argv[]) state->their_features); state->channel = new_initial_channel(state, &state->channel_id, - &state->tx_state->funding_txid, - state->tx_state->funding_txout, + &state->tx_state->funding, state->minimum_depth, take(new_height_states(NULL, opener, &state->tx_state->blockheight)), diff --git a/openingd/dualopend_wire.csv b/openingd/dualopend_wire.csv index 35f6274fc8e5..75fbb4d5bdf4 100644 --- a/openingd/dualopend_wire.csv +++ b/openingd/dualopend_wire.csv @@ -45,8 +45,7 @@ msgdata,dualopend_reinit,our_basepoints,basepoints, msgdata,dualopend_reinit,our_funding_pubkey,pubkey, msgdata,dualopend_reinit,their_funding_pubkey,pubkey, msgdata,dualopend_reinit,minimum_depth,u32, -msgdata,dualopend_reinit,funding_txid,bitcoin_txid, -msgdata,dualopend_reinit,funding_txout,u16, +msgdata,dualopend_reinit,funding,bitcoin_outpoint, msgdata,dualopend_reinit,most_recent_feerate_per_kw_funding,u32, msgdata,dualopend_reinit,funding_satoshi,amount_sat, msgdata,dualopend_reinit,our_funding,amount_msat, @@ -137,8 +136,7 @@ msgdata,dualopend_commit_rcvd,htlc_basepoint,pubkey, msgdata,dualopend_commit_rcvd,delayed_payment_basepoint,pubkey, msgdata,dualopend_commit_rcvd,their_per_commit_point,pubkey, msgdata,dualopend_commit_rcvd,remote_fundingkey,pubkey, -msgdata,dualopend_commit_rcvd,funding_txid,bitcoin_txid, -msgdata,dualopend_commit_rcvd,funding_txout,u16, +msgdata,dualopend_commit_rcvd,funding,bitcoin_outpoint, msgdata,dualopend_commit_rcvd,funding_satoshis,amount_sat, msgdata,dualopend_commit_rcvd,our_funding_sats,amount_sat, msgdata,dualopend_commit_rcvd,channel_flags,u8, diff --git a/openingd/openingd.c b/openingd/openingd.c index 14429cb31c1a..78280f6bcab6 100644 --- a/openingd/openingd.c +++ b/openingd/openingd.c @@ -75,11 +75,10 @@ struct state { struct channel_id channel_id; /* Funding and feerate: set by opening peer. */ - struct amount_sat funding; + struct amount_sat funding_sats; struct amount_msat push_msat; u32 feerate_per_kw; - struct bitcoin_txid funding_txid; - u16 funding_txout; + struct bitcoin_outpoint funding; /* If non-NULL, this is the scriptpubkey we/they *must* close with */ u8 *upfront_shutdown_script[NUM_SIDES]; @@ -155,7 +154,8 @@ static void negotiation_failed(struct state *state, bool am_opener, /* We always set channel_reserve_satoshis to 1%, rounded down. */ static void set_reserve(struct state *state, const struct amount_sat dust_limit) { - state->localconf.channel_reserve = amount_sat_div(state->funding, 100); + state->localconf.channel_reserve + = amount_sat_div(state->funding_sats, 100); /* BOLT #2: * @@ -290,13 +290,14 @@ static bool setup_channel_funder(struct state *state) */ if (!feature_negotiated(state->our_features, state->their_features, OPT_LARGE_CHANNELS) - && amount_sat_greater(state->funding, chainparams->max_funding)) { + && amount_sat_greater(state->funding_sats, + chainparams->max_funding)) { status_failed(STATUS_FAIL_MASTER_IO, "funding_satoshis must be < %s, not %s", type_to_string(tmpctx, struct amount_sat, &chainparams->max_funding), type_to_string(tmpctx, struct amount_sat, - &state->funding)); + &state->funding_sats)); return false; } @@ -372,7 +373,7 @@ static u8 *funder_channel_start(struct state *state, u8 channel_flags) msg = towire_open_channel(NULL, &chainparams->genesis_blockhash, &state->channel_id, - state->funding, + state->funding_sats, state->push_msat, state->localconf.dust_limit, state->localconf.max_htlc_value_in_flight, @@ -469,7 +470,7 @@ static u8 *funder_channel_start(struct state *state, u8 channel_flags) return NULL; } - if (!check_config_bounds(tmpctx, state->funding, + if (!check_config_bounds(tmpctx, state->funding_sats, state->feerate_per_kw, state->max_to_self_delay, state->min_effective_htlc_capacity, @@ -525,16 +526,14 @@ static bool funder_finalize_channel_setup(struct state *state, * part (common/initial_channel) which doesn't support HTLCs and is * enough for us here, and the complete channel support required by * `channeld` which lives in channeld/full_channel. */ - derive_channel_id(&cid, - &state->funding_txid, state->funding_txout); + derive_channel_id(&cid, &state->funding); state->channel = new_initial_channel(state, &cid, - &state->funding_txid, - state->funding_txout, + &state->funding, state->minimum_depth, NULL, 0, /* No channel lease */ - state->funding, + state->funding_sats, local_msat, take(new_fee_states(NULL, LOCAL, &state->feerate_per_kw)), @@ -611,8 +610,8 @@ static bool funder_finalize_channel_setup(struct state *state, /* Now we give our peer the signature for their first commitment * transaction. */ msg = towire_funding_created(state, &state->channel_id, - &state->funding_txid, - state->funding_txout, + &state->funding.txid, + state->funding.n, &sig->s); sync_crypto_write(state->pps, msg); @@ -725,17 +724,17 @@ static u8 *funder_channel_complete(struct state *state) /* Update the billboard about what we're doing*/ peer_billboard(false, "Funding channel con't: continuing with funding_txid %s", - type_to_string(tmpctx, struct bitcoin_txid, &state->funding_txid)); + type_to_string(tmpctx, struct bitcoin_txid, &state->funding.txid)); /* We recalculate the local_msat from cached values; should * succeed because we checked it earlier */ - if (!amount_sat_sub_msat(&local_msat, state->funding, state->push_msat)) + if (!amount_sat_sub_msat(&local_msat, state->funding_sats, state->push_msat)) status_failed(STATUS_FAIL_INTERNAL_ERROR, "push_msat %s > funding %s?", type_to_string(tmpctx, struct amount_msat, &state->push_msat), type_to_string(tmpctx, struct amount_sat, - &state->funding)); + &state->funding_sats)); if (!funder_finalize_channel_setup(state, local_msat, &sig, &tx, &pbase)) @@ -754,8 +753,7 @@ static u8 *funder_channel_complete(struct state *state) &state->first_per_commitment_point[REMOTE], state->minimum_depth, &state->their_funding_pubkey, - &state->funding_txid, - state->funding_txout, + &state->funding, state->feerate_per_kw, state->localconf.channel_reserve, state->upfront_shutdown_script[REMOTE], @@ -774,6 +772,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) u8 *msg; const u8 *wscript; u8 channel_flags; + u16 funding_txout; char* err_reason; struct wally_tx_output *direct_outputs[NUM_SIDES]; struct penalty_base *pbase; @@ -791,7 +790,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) */ if (!fromwire_open_channel(open_channel_msg, &chain_hash, &state->channel_id, - &state->funding, + &state->funding_sats, &state->push_msat, &state->remoteconf.dust_limit, &state->remoteconf.max_htlc_value_in_flight, @@ -862,11 +861,11 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) /* We choose to require *negotiation*, not just support! */ if (!feature_negotiated(state->our_features, state->their_features, OPT_LARGE_CHANNELS) - && amount_sat_greater(state->funding, chainparams->max_funding)) { + && amount_sat_greater(state->funding_sats, chainparams->max_funding)) { negotiation_failed(state, false, "funding_satoshis %s too large", type_to_string(tmpctx, struct amount_sat, - &state->funding)); + &state->funding_sats)); return NULL; } @@ -876,14 +875,14 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) * ... * - `push_msat` is greater than `funding_satoshis` * 1000. */ - if (amount_msat_greater_sat(state->push_msat, state->funding)) { + if (amount_msat_greater_sat(state->push_msat, state->funding_sats)) { peer_failed_err(state->pps, &state->channel_id, "Their push_msat %s" " would be too large for funding_satoshis %s", type_to_string(tmpctx, struct amount_msat, &state->push_msat), type_to_string(tmpctx, struct amount_sat, - &state->funding)); + &state->funding_sats)); return NULL; } @@ -944,7 +943,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) } /* These checks are the same whether we're opener or accepter... */ - if (!check_config_bounds(tmpctx, state->funding, + if (!check_config_bounds(tmpctx, state->funding_sats, state->feerate_per_kw, state->max_to_self_delay, state->min_effective_htlc_capacity, @@ -962,7 +961,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) /* Check with lightningd that we can accept this? In particular, * if we have an existing channel, we don't support it. */ msg = towire_openingd_got_offer(NULL, - state->funding, + state->funding_sats, state->push_msat, state->remoteconf.dust_limit, state->remoteconf.max_htlc_value_in_flight, @@ -1035,11 +1034,13 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) * tx they generated; the sighash type is implied, so we set it here. */ theirsig.sighash_type = SIGHASH_ALL; if (!fromwire_funding_created(msg, &id_in, - &state->funding_txid, - &state->funding_txout, + &state->funding.txid, + &funding_txout, &theirsig.s)) peer_failed_err(state->pps, &state->channel_id, "Parsing funding_created"); + /* We only allow 16 bits for this on the wire. */ + state->funding.n = funding_txout; /* BOLT #2: * @@ -1056,11 +1057,10 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) /* Now we can create the channel structure. */ state->channel = new_initial_channel(state, &state->channel_id, - &state->funding_txid, - state->funding_txout, + &state->funding, state->minimum_depth, NULL, 0, /* No channel lease */ - state->funding, + state->funding_sats, state->push_msat, take(new_fee_states(NULL, REMOTE, &state->feerate_per_kw)), @@ -1127,8 +1127,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) * `funding_txid` and the `funding_output_index`, using big-endian * exclusive-OR (i.e. `funding_output_index` alters the last 2 bytes). */ - derive_channel_id(&state->channel_id, - &state->funding_txid, state->funding_txout); + derive_channel_id(&state->channel_id, &state->funding); /*~ We generate the `funding_signed` message here, since we have all * the data and it's only applicable in the fundee case. @@ -1191,9 +1190,8 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) &theirs.delayed_payment, &state->first_per_commitment_point[REMOTE], &their_funding_pubkey, - &state->funding_txid, - state->funding_txout, - state->funding, + &state->funding, + state->funding_sats, state->push_msat, channel_flags, state->feerate_per_kw, @@ -1315,11 +1313,12 @@ static u8 *handle_master_in(struct state *state) switch (t) { case WIRE_OPENINGD_FUNDER_START: - if (!fromwire_openingd_funder_start(state, msg, &state->funding, - &state->push_msat, - &state->upfront_shutdown_script[LOCAL], - &state->feerate_per_kw, - &channel_flags)) + if (!fromwire_openingd_funder_start(state, msg, + &state->funding_sats, + &state->push_msat, + &state->upfront_shutdown_script[LOCAL], + &state->feerate_per_kw, + &channel_flags)) master_badmsg(WIRE_OPENINGD_FUNDER_START, msg); msg = funder_channel_start(state, channel_flags); @@ -1333,8 +1332,8 @@ static u8 *handle_master_in(struct state *state) &funding_txout, &state->channel_type)) master_badmsg(WIRE_OPENINGD_FUNDER_COMPLETE, msg); - state->funding_txid = funding_txid; - state->funding_txout = funding_txout; + state->funding.txid = funding_txid; + state->funding.n = funding_txout; return funder_channel_complete(state); case WIRE_OPENINGD_FUNDER_CANCEL: /* We're aborting this, simple */ diff --git a/openingd/openingd_wire.csv b/openingd/openingd_wire.csv index 26451bf675d7..39278ec58cb0 100644 --- a/openingd/openingd_wire.csv +++ b/openingd/openingd_wire.csv @@ -72,8 +72,7 @@ msgdata,openingd_funder_reply,delayed_payment_basepoint,pubkey, msgdata,openingd_funder_reply,their_per_commit_point,pubkey, msgdata,openingd_funder_reply,minimum_depth,u32, msgdata,openingd_funder_reply,remote_fundingkey,pubkey, -msgdata,openingd_funder_reply,funding_txid,bitcoin_txid, -msgdata,openingd_funder_reply,funding_txout,u16, +msgdata,openingd_funder_reply,funding,bitcoin_outpoint, msgdata,openingd_funder_reply,feerate_per_kw,u32, msgdata,openingd_funder_reply,our_channel_reserve_satoshis,amount_sat, msgdata,openingd_funder_reply,shutdown_len,u16, @@ -125,8 +124,7 @@ msgdata,openingd_fundee,htlc_basepoint,pubkey, msgdata,openingd_fundee,delayed_payment_basepoint,pubkey, msgdata,openingd_fundee,their_per_commit_point,pubkey, msgdata,openingd_fundee,remote_fundingkey,pubkey, -msgdata,openingd_fundee,funding_txid,bitcoin_txid, -msgdata,openingd_fundee,funding_txout,u16, +msgdata,openingd_fundee,funding,bitcoin_outpoint, msgdata,openingd_fundee,funding_satoshis,amount_sat, msgdata,openingd_fundee,push_msat,amount_msat, msgdata,openingd_fundee,channel_flags,u8, diff --git a/tests/fuzz/fuzz-channel_id.c b/tests/fuzz/fuzz-channel_id.c index b2d9307e54b1..79e8df3bb553 100644 --- a/tests/fuzz/fuzz-channel_id.c +++ b/tests/fuzz/fuzz-channel_id.c @@ -15,26 +15,23 @@ void run(const uint8_t *data, size_t size) { struct channel_id chan_id; struct pubkey basepoint_1, basepoint_2; - struct bitcoin_txid txid; - uint16_t vout; + struct bitcoin_outpoint outpoint; const uint8_t **v1_chunks, **v2_chunks, **marshal_chunks; const uint8_t *wire_ptr; size_t wire_max; uint8_t *wire_buf; - if (size < 34) + /* 32 (txid) + 4 (vout) */ + if (size < 36) return; - /* 32 (txid) + 2 (vout ala LN) */ - v1_chunks = get_chunks(NULL, data, size, 34); + v1_chunks = get_chunks(NULL, data, size, 36); for (size_t i = 0; i < tal_count(v1_chunks); i++) { wire_ptr = v1_chunks[i]; - wire_max = 32; - fromwire_bitcoin_txid(&wire_ptr, &wire_max, &txid); + wire_max = 36; + fromwire_bitcoin_outpoint(&wire_ptr, &wire_max, &outpoint); assert(wire_ptr); - wire_max = 2; - vout = fromwire_u16(&wire_ptr, &wire_max); - derive_channel_id(&chan_id, &txid, vout); + derive_channel_id(&chan_id, &outpoint); } tal_free(v1_chunks); diff --git a/tests/fuzz/fuzz-close_tx.c b/tests/fuzz/fuzz-close_tx.c index ebbef9a461c3..a0919d3bfd33 100644 --- a/tests/fuzz/fuzz-close_tx.c +++ b/tests/fuzz/fuzz-close_tx.c @@ -20,8 +20,7 @@ void run(const uint8_t *data, size_t size) { const uint8_t *wire_ptr; size_t wire_max, min_size, script_size; - struct bitcoin_txid txid; - uint32_t vout; + struct bitcoin_outpoint outpoint; struct amount_sat funding, to_us, to_them, dust_limit, max; const uint8_t *our_script, *their_script, *funding_script; struct pubkey *pk1, *pk2; @@ -62,10 +61,8 @@ void run(const uint8_t *data, size_t size) to_them = amount_sat_div(max, 2); } - wire_max = 4; - vout = fromwire_u32(&wire_ptr, &wire_max); - wire_max = 32; - fromwire_bitcoin_txid(&wire_ptr, &wire_max, &txid); + wire_max = 36; + fromwire_bitcoin_outpoint(&wire_ptr, &wire_max, &outpoint); our_script = tal_dup_arr(tmpctx, const uint8_t, wire_ptr, script_size, 0); their_script = tal_dup_arr(tmpctx, const uint8_t, wire_ptr + script_size, @@ -81,8 +78,8 @@ void run(const uint8_t *data, size_t size) funding_script = bitcoin_redeem_2of2(tmpctx, pk1, pk2); create_close_tx(tmpctx, chainparams, our_script, - their_script, funding_script, &txid, - vout, funding, to_us, to_them, dust_limit); + their_script, funding_script, &outpoint, + funding, to_us, to_them, dust_limit); clean_tmpctx(); } diff --git a/tests/fuzz/fuzz-initial_channel.c b/tests/fuzz/fuzz-initial_channel.c index df2b34177084..0eed31095a10 100644 --- a/tests/fuzz/fuzz-initial_channel.c +++ b/tests/fuzz/fuzz-initial_channel.c @@ -32,9 +32,9 @@ void init(int *argc, char ***argv) void run(const uint8_t *data, size_t size) { struct channel_id cid; - struct bitcoin_txid funding_txid; - u32 funding_txout, minimum_depth; - struct amount_sat funding, max; + struct bitcoin_outpoint funding; + u32 minimum_depth; + struct amount_sat funding_sats, max; struct amount_msat local_msatoshi; u32 feerate_per_kw, blockheight, lease_expiry; struct channel_config local, remote; @@ -45,14 +45,13 @@ void run(const uint8_t *data, size_t size) struct channel *channel; fromwire_channel_id(&data, &size, &cid); - fromwire_bitcoin_txid(&data, &size, &funding_txid); - funding_txout = fromwire_u32(&data, &size); + fromwire_bitcoin_outpoint(&data, &size, &funding); minimum_depth = fromwire_u32(&data, &size); - funding = fromwire_amount_sat(&data, &size); + funding_sats = fromwire_amount_sat(&data, &size); local_msatoshi = fromwire_amount_msat(&data, &size); max = AMOUNT_SAT((u32)WALLY_SATOSHI_PER_BTC * WALLY_BTC_MAX); - if (amount_sat_greater(funding, max)) - funding = max; + if (amount_sat_greater(funding_sats, max)) + funding_sats = max; feerate_per_kw = fromwire_u32(&data, &size); blockheight = fromwire_u32(&data, &size); lease_expiry = fromwire_u32(&data, &size); @@ -79,12 +78,12 @@ void run(const uint8_t *data, size_t size) return; for (enum side opener = 0; opener < NUM_SIDES; opener++) { - channel = new_initial_channel(tmpctx, &cid, &funding_txid, - funding_txout, minimum_depth, + channel = new_initial_channel(tmpctx, &cid, &funding, + minimum_depth, take(new_height_states(NULL, opener, &blockheight)), lease_expiry, - funding, local_msatoshi, + funding_sats, local_msatoshi, take(new_fee_states(NULL, opener, &feerate_per_kw)), &local, &remote, diff --git a/tests/test_closing.py b/tests/test_closing.py index 381153c9dfce..eab628020562 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -2320,7 +2320,7 @@ def test_onchain_all_dust(node_factory, bitcoind, executor): l1.wait_for_onchaind_broadcast('IGNORING_TINY_PAYMENT', 'THEIR_UNILATERAL/OUR_HTLC') - l1.daemon.wait_for_log('Ignoring output .* of .*: THEIR_UNILATERAL/OUR_HTLC') + l1.daemon.wait_for_log('Ignoring output .*: THEIR_UNILATERAL/OUR_HTLC') # 100 deep and l2 forgets. bitcoind.generate_block(93) diff --git a/wallet/db.c b/wallet/db.c index 082793d0d2e2..5c884cb16d4e 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -1470,14 +1470,13 @@ static void fillin_missing_channel_id(struct lightningd *ld, struct db *db, while (db_step(stmt)) { struct db_stmt *update_stmt; size_t id; - struct bitcoin_txid funding_txid; + struct bitcoin_outpoint funding; struct channel_id cid; - u32 outnum; id = db_column_u64(stmt, 0); - db_column_txid(stmt, 1, &funding_txid); - outnum = db_column_int(stmt, 2); - derive_channel_id(&cid, &funding_txid, outnum); + db_column_txid(stmt, 1, &funding.txid); + funding.n = db_column_int(stmt, 2); + derive_channel_id(&cid, &funding); update_stmt = db_prepare_v2(db, SQL("UPDATE channels" " SET full_channel_id = ?" diff --git a/wallet/reservation.c b/wallet/reservation.c index 646852451ac0..46ba907b83bb 100644 --- a/wallet/reservation.c +++ b/wallet/reservation.c @@ -36,8 +36,8 @@ static void json_add_reservestatus(struct json_stream *response, u32 current_height) { json_object_start(response, NULL); - json_add_txid(response, "txid", &utxo->txid); - json_add_u32(response, "vout", utxo->outnum); + json_add_txid(response, "txid", &utxo->outpoint.txid); + json_add_u32(response, "vout", utxo->outpoint.n); json_add_bool(response, "was_reserved", was_reserved(oldstatus, old_res, current_height)); json_add_bool(response, "reserved", @@ -67,11 +67,10 @@ static void reserve_and_report(struct json_stream *response, utxos[i], current_height, reserve)) { - fatal("Unable to reserve %s:%u!", + fatal("Unable to reserve %s!", type_to_string(tmpctx, - struct bitcoin_txid, - &utxos[i]->txid), - utxos[i]->outnum); + struct bitcoin_outpoint, + &utxos[i]->outpoint)); } json_add_reservestatus(response, utxos[i], oldstatus, old_res, current_height); @@ -100,29 +99,26 @@ static struct command_result *json_reserveinputs(struct command *cmd, current_height = get_block_height(cmd->ld->topology); for (size_t i = 0; i < psbt->tx->num_inputs; i++) { - struct bitcoin_txid txid; + struct bitcoin_outpoint outpoint; struct utxo *utxo; - wally_tx_input_get_txid(&psbt->tx->inputs[i], &txid); - utxo = wallet_utxo_get(cmd, cmd->ld->wallet, - &txid, psbt->tx->inputs[i].index); + wally_tx_input_get_outpoint(&psbt->tx->inputs[i], &outpoint); + utxo = wallet_utxo_get(cmd, cmd->ld->wallet, &outpoint); if (!utxo) continue; if (*exclusive && utxo_is_reserved(utxo, current_height)) { return command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "%s:%u already reserved", + "%s already reserved", type_to_string(tmpctx, - struct bitcoin_txid, - &utxo->txid), - utxo->outnum); + struct bitcoin_outpoint, + &utxo->outpoint)); } if (utxo->status == OUTPUT_STATE_SPENT) return command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "%s:%u already spent", + "%s already spent", type_to_string(tmpctx, - struct bitcoin_txid, - &utxo->txid), - utxo->outnum); + struct bitcoin_outpoint, + &utxo->outpoint)); tal_arr_expand(&utxos, utxo); } @@ -181,14 +177,13 @@ static struct command_result *json_unreserveinputs(struct command *cmd, response = json_stream_success(cmd); json_array_start(response, "reservations"); for (size_t i = 0; i < psbt->tx->num_inputs; i++) { - struct bitcoin_txid txid; + struct bitcoin_outpoint outpoint; struct utxo *utxo; enum output_status oldstatus; u32 old_res; - wally_tx_input_get_txid(&psbt->tx->inputs[i], &txid); - utxo = wallet_utxo_get(cmd, cmd->ld->wallet, - &txid, psbt->tx->inputs[i].index); + wally_tx_input_get_outpoint(&psbt->tx->inputs[i], &outpoint); + utxo = wallet_utxo_get(cmd, cmd->ld->wallet, &outpoint); if (!utxo || utxo->status != OUTPUT_STATE_RESERVED) continue; @@ -295,7 +290,7 @@ static struct wally_psbt *psbt_using_utxos(const tal_t *ctx, else this_nsequence = nsequence; - psbt_append_input(psbt, &utxos[i]->txid, utxos[i]->outnum, + psbt_append_input(psbt, &utxos[i]->outpoint, this_nsequence, scriptSig, NULL, redeemscript); @@ -320,7 +315,8 @@ static struct wally_psbt *psbt_using_utxos(const tal_t *ctx, * add it to the PSBT as the non-witness-utxo field. * Dual-funded channels and some hardware wallets * require this */ - tx = wallet_transaction_get(ctx, wallet, &utxos[i]->txid); + tx = wallet_transaction_get(ctx, wallet, + &utxos[i]->outpoint.txid); if (tx) psbt_input_set_utxo(psbt, i, tx->wtx); } @@ -594,8 +590,7 @@ static struct command_result *param_txout(struct command *cmd, json_for_each_arr(i, curr, tok) { struct utxo *utxo; jsmntok_t txid_tok, outnum_tok; - struct bitcoin_txid txid; - u32 outnum; + struct bitcoin_outpoint outpoint; if (!split_tok(buffer, curr, ':', &txid_tok, &outnum_tok)) return command_fail(cmd, JSONRPC2_INVALID_PARAMS, @@ -604,33 +599,31 @@ static struct command_result *param_txout(struct command *cmd, " 'txid:output_index'.", json_strdup(tmpctx, buffer, curr)); - if (!json_to_txid(buffer, &txid_tok, &txid)) { + if (!json_to_txid(buffer, &txid_tok, &outpoint.txid)) { return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Could not get a txid out of \"%s\"", json_strdup(tmpctx, buffer, &txid_tok)); } - if (!json_to_number(buffer, &outnum_tok, &outnum)) { + if (!json_to_number(buffer, &outnum_tok, &outpoint.n)) { return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Could not get a vout out of \"%s\"", json_strdup(tmpctx, buffer, &outnum_tok)); } - utxo = wallet_utxo_get(*utxos, cmd->ld->wallet, &txid, outnum); + utxo = wallet_utxo_get(*utxos, cmd->ld->wallet, &outpoint); if (!utxo) { return command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "Unknown UTXO %s:%u", + "Unknown UTXO %s", type_to_string(tmpctx, - struct bitcoin_txid, - &txid), - outnum); + struct bitcoin_outpoint, + &outpoint)); } if (utxo->status == OUTPUT_STATE_SPENT) { return command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "Already spent UTXO %s:%u", + "Already spent UTXO %s", type_to_string(tmpctx, - struct bitcoin_txid, - &txid), - outnum); + struct bitcoin_outpoint, + &outpoint)); } (*utxos)[i] = utxo; @@ -681,18 +674,16 @@ static struct command_result *json_utxopsbt(struct command *cmd, if (!*reserved_ok && utxo_is_reserved(utxo, current_height)) return command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "UTXO %s:%u already reserved", + "UTXO %s already reserved", type_to_string(tmpctx, - struct bitcoin_txid, - &utxo->txid), - utxo->outnum); + struct bitcoin_outpoint, + &utxo->outpoint)); if (utxo_is_csv_locked(utxo, current_height)) return command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "UTXO %s:%u is csv locked (%u)", + "UTXO %s is csv locked (%u)", type_to_string(tmpctx, - struct bitcoin_txid, - &utxo->txid), - utxo->outnum, + struct bitcoin_outpoint, + &utxo->outpoint), utxo->close_info->csv); diff --git a/wallet/test/run-db.c b/wallet/test/run-db.c index 9bd50c395277..92ae8a87a241 100644 --- a/wallet/test/run-db.c +++ b/wallet/test/run-db.c @@ -19,7 +19,7 @@ static void db_log_(struct log *log UNUSED, enum log_level level UNUSED, const s /* AUTOGENERATED MOCKS START */ /* Generated stub for derive_channel_id */ void derive_channel_id(struct channel_id *channel_id UNNEEDED, - const struct bitcoin_txid *txid UNNEEDED, u16 txout UNNEEDED) + const struct bitcoin_outpoint *outpoint UNNEEDED) { fprintf(stderr, "derive_channel_id called!\n"); abort(); } /* Generated stub for fatal */ void fatal(const char *fmt UNNEEDED, ...) diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index c4e603fadd14..8b927e8555a5 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -28,7 +28,7 @@ size_t bigsize_put(u8 buf[BIGSIZE_MAX_LEN] UNNEEDED, bigsize_t v UNNEEDED) { fprintf(stderr, "bigsize_put called!\n"); abort(); } /* Generated stub for bitcoind_getutxout_ */ void bitcoind_getutxout_(struct bitcoind *bitcoind UNNEEDED, - const struct bitcoin_txid *txid UNNEEDED, const u32 outnum UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, void (*cb)(struct bitcoind *bitcoind UNNEEDED, const struct bitcoin_tx_output *txout UNNEEDED, void *arg) UNNEEDED, @@ -99,7 +99,7 @@ void delay_then_reconnect(struct channel *channel UNNEEDED, u32 seconds_delay UN { fprintf(stderr, "delay_then_reconnect called!\n"); abort(); } /* Generated stub for derive_channel_id */ void derive_channel_id(struct channel_id *channel_id UNNEEDED, - const struct bitcoin_txid *txid UNNEEDED, u16 txout UNNEEDED) + const struct bitcoin_outpoint *outpoint UNNEEDED) { fprintf(stderr, "derive_channel_id called!\n"); abort(); } /* Generated stub for ecdh */ void ecdh(const struct pubkey *point UNNEEDED, struct secret *ss UNNEEDED) @@ -442,8 +442,7 @@ struct channel_coin_mvt *new_channel_mvt_routed_hout(const tal_t *ctx UNNEEDED, /* Generated stub for new_coin_deposit_sat */ struct chain_coin_mvt *new_coin_deposit_sat(const tal_t *ctx UNNEEDED, const char *account_name UNNEEDED, - const struct bitcoin_txid *txid UNNEEDED, - u32 vout UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, u32 blockheight UNNEEDED, struct amount_sat amount UNNEEDED) { fprintf(stderr, "new_coin_deposit_sat called!\n"); abort(); } @@ -508,18 +507,18 @@ const char *onion_wire_name(int e UNNEEDED) { fprintf(stderr, "onion_wire_name called!\n"); abort(); } /* Generated stub for outpointfilter_add */ void outpointfilter_add(struct outpointfilter *of UNNEEDED, - const struct bitcoin_txid *txid UNNEEDED, const u32 outnum UNNEEDED) + const struct bitcoin_outpoint *outpoint UNNEEDED) { fprintf(stderr, "outpointfilter_add called!\n"); abort(); } /* Generated stub for outpointfilter_matches */ bool outpointfilter_matches(struct outpointfilter *of UNNEEDED, - const struct bitcoin_txid *txid UNNEEDED, const u32 outnum UNNEEDED) + const struct bitcoin_outpoint *outpoint UNNEEDED) { fprintf(stderr, "outpointfilter_matches called!\n"); abort(); } /* Generated stub for outpointfilter_new */ struct outpointfilter *outpointfilter_new(tal_t *ctx UNNEEDED) { fprintf(stderr, "outpointfilter_new called!\n"); abort(); } /* Generated stub for outpointfilter_remove */ void outpointfilter_remove(struct outpointfilter *of UNNEEDED, - const struct bitcoin_txid *txid UNNEEDED, const u32 outnum UNNEEDED) + const struct bitcoin_outpoint *outpoint UNNEEDED) { fprintf(stderr, "outpointfilter_remove called!\n"); abort(); } /* Generated stub for param */ bool param(struct command *cmd UNNEEDED, const char *buffer UNNEEDED, @@ -812,8 +811,7 @@ struct txwatch *watch_txid(const tal_t *ctx UNNEEDED, struct txowatch *watch_txo(const tal_t *ctx UNNEEDED, struct chain_topology *topo UNNEEDED, struct channel *channel UNNEEDED, - const struct bitcoin_txid *txid UNNEEDED, - unsigned int output UNNEEDED, + const struct bitcoin_outpoint *outpoint UNNEEDED, enum watch_result (*cb)(struct channel *channel UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, size_t input_num UNNEEDED, @@ -987,7 +985,7 @@ static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx) CHECK_MSG(!wallet_err, wallet_err); /* Attempt to save an UTXO with close_info set */ - memset(&u.txid, 1, sizeof(u.txid)); + memset(&u.outpoint, 1, sizeof(u.outpoint)); u.close_info = tal(w, struct unilateral_close_info); u.close_info->channel_id = 42; u.close_info->peer_id = id; @@ -1019,31 +1017,31 @@ static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx) u.close_info->option_anchor_outputs == false); /* Attempt to reserve the utxo */ - CHECK_MSG(wallet_update_output_status(w, &u.txid, u.outnum, + CHECK_MSG(wallet_update_output_status(w, &u.outpoint, OUTPUT_STATE_AVAILABLE, OUTPUT_STATE_RESERVED), "could not reserve available output"); /* Reserving twice should fail */ - CHECK_MSG(!wallet_update_output_status(w, &u.txid, u.outnum, + CHECK_MSG(!wallet_update_output_status(w, &u.outpoint, OUTPUT_STATE_AVAILABLE, OUTPUT_STATE_RESERVED), "could reserve already reserved output"); /* Un-reserving should work */ - CHECK_MSG(wallet_update_output_status(w, &u.txid, u.outnum, + CHECK_MSG(wallet_update_output_status(w, &u.outpoint, OUTPUT_STATE_RESERVED, OUTPUT_STATE_AVAILABLE), "could not unreserve reserved output"); /* Switching from any to something else */ - CHECK_MSG(wallet_update_output_status(w, &u.txid, u.outnum, + CHECK_MSG(wallet_update_output_status(w, &u.outpoint, OUTPUT_STATE_ANY, OUTPUT_STATE_SPENT), "could not change output state ignoring oldstate"); /* Attempt to save an UTXO with close_info set, no commitment_point */ - memset(&u.txid, 2, sizeof(u.txid)); + memset(&u.outpoint, 2, sizeof(u.outpoint)); u.amount = AMOUNT_SAT(5); u.close_info = tal(w, struct unilateral_close_info); u.close_info->channel_id = 42; @@ -1074,9 +1072,8 @@ static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx) channel.peer = new_peer(ld, 0, &id, &addr, false); channel.dbid = 1; channel.type = channel_type_anchor_outputs(tmpctx); - memset(&u.txid, 3, sizeof(u.txid)); - CHECK_MSG(wallet_add_onchaind_utxo(w, &u.txid, - u.outnum, + memset(&u.outpoint, 3, sizeof(u.outpoint)); + CHECK_MSG(wallet_add_onchaind_utxo(w, &u.outpoint, u.scriptPubkey, *u.blockheight, AMOUNT_SAT(3), @@ -1184,11 +1181,11 @@ static bool bitcoin_tx_eq(const struct bitcoin_tx *tx1, static bool channel_inflightseq(struct channel_inflight *i1, struct channel_inflight *i2) { - CHECK(memeq(&i1->funding->txid, + CHECK(memeq(&i1->funding->outpoint.txid, sizeof(struct sha256_double), - &i2->funding->txid, + &i2->funding->outpoint.txid, sizeof(struct sha256_double))); - CHECK(i1->funding->outnum == i2->funding->outnum); + CHECK(i1->funding->outpoint.n == i2->funding->outpoint.n); CHECK(i1->funding->feerate == i2->funding->feerate); CHECK(amount_sat_eq(i1->funding->total_funds, i2->funding->total_funds)); @@ -1229,11 +1226,7 @@ static bool channelseq(struct channel *c1, struct channel *c2) tal_count(c1->shutdown_scriptpubkey[REMOTE]), c2->shutdown_scriptpubkey[REMOTE], tal_count(c2->shutdown_scriptpubkey[REMOTE]))); - CHECK(memeq( - &c1->funding_txid, - sizeof(struct sha256_double), - &c2->funding_txid, - sizeof(struct sha256_double))); + CHECK(bitcoin_outpoint_eq(&c1->funding, &c2->funding)); CHECK(pubkey_eq(&ci1->remote_fundingkey, &ci2->remote_fundingkey)); CHECK(pubkey_eq(&ci1->theirbase.revocation, &ci2->theirbase.revocation)); CHECK(pubkey_eq(&ci1->theirbase.payment, &ci2->theirbase.payment)); @@ -1513,7 +1506,7 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx) struct wallet *w = create_test_wallet(ld, ctx); struct channel *chan, *c2; struct channel_inflight *inflight; - struct bitcoin_txid txid; + struct bitcoin_outpoint outpoint; struct bitcoin_signature sig; struct amount_sat funding_sats, our_sats; struct node_id id; @@ -1555,7 +1548,7 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx) lease_blockheight_start = 101010; memset(&our_config, 1, sizeof(struct channel_config)); our_config.id = 0; - memset(&txid, 1, sizeof(txid)); + memset(&outpoint, 1, sizeof(outpoint)); basepoints.revocation = pk; basepoints.payment = pk; basepoints.htlc = pk; @@ -1572,7 +1565,7 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx) LOCAL, NULL, "billboard", 8, &our_config, 101, 1, 1, 1, - &txid, 1, + &outpoint, funding_sats, AMOUNT_MSAT(0), our_sats, 0, false, @@ -1609,10 +1602,10 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx) /* info for the inflight */ funding_sats = AMOUNT_SAT(222222); our_sats = AMOUNT_SAT(111111); - memset(&txid, 1, sizeof(txid)); + memset(&outpoint, 1, sizeof(outpoint)); mempat(&sig.s, sizeof(sig.s)); - inflight = new_inflight(chan, txid, 11, 253, + inflight = new_inflight(chan, &outpoint, 253, funding_sats, our_sats, funding_psbt, @@ -1632,9 +1625,9 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx) /* add another inflight, confirm existence */ funding_sats = AMOUNT_SAT(666666); our_sats = AMOUNT_SAT(555555); - memset(&txid, 2, sizeof(txid)); + memset(&outpoint, 2, sizeof(outpoint)); mempat(&sig.s, sizeof(sig.s)); - inflight = new_inflight(chan, txid, 111, 300, + inflight = new_inflight(chan, &outpoint, 300, funding_sats, our_sats, funding_psbt, diff --git a/wallet/txfilter.c b/wallet/txfilter.c index 2682ebba4996..1e4c47ab9aa2 100644 --- a/wallet/txfilter.c +++ b/wallet/txfilter.c @@ -31,32 +31,21 @@ struct txfilter { struct scriptpubkeyset scriptpubkeyset; }; -struct outpointfilter_entry { - struct bitcoin_txid txid; - u32 outnum; -}; - -static size_t outpoint_hash(const struct outpointfilter_entry *out) +static size_t outpoint_hash(const struct bitcoin_outpoint *out) { struct siphash24_ctx ctx; siphash24_init(&ctx, siphash_seed()); siphash24_update(&ctx, &out->txid, sizeof(out->txid)); - siphash24_u32(&ctx, out->outnum); + siphash24_u32(&ctx, out->n); return siphash24_done(&ctx); } -static bool outpoint_eq(const struct outpointfilter_entry *o1, - const struct outpointfilter_entry *o2) -{ - return bitcoin_txid_eq(&o1->txid, &o2->txid) && o1->outnum == o2->outnum; -} - -static const struct outpointfilter_entry *outpoint_keyof(const struct outpointfilter_entry *out) +static const struct bitcoin_outpoint *outpoint_keyof(const struct bitcoin_outpoint *out) { return out; } -HTABLE_DEFINE_TYPE(struct outpointfilter_entry, outpoint_keyof, outpoint_hash, outpoint_eq, +HTABLE_DEFINE_TYPE(struct bitcoin_outpoint, outpoint_keyof, outpoint_hash, bitcoin_outpoint_eq, outpointset); struct outpointfilter { @@ -110,33 +99,28 @@ bool txfilter_match(const struct txfilter *filter, const struct bitcoin_tx *tx) return false; } -void outpointfilter_add(struct outpointfilter *of, const struct bitcoin_txid *txid, const u32 outnum) +void outpointfilter_add(struct outpointfilter *of, + const struct bitcoin_outpoint *outpoint) { - struct outpointfilter_entry *op; - if (outpointfilter_matches(of, txid, outnum)) + if (outpointfilter_matches(of, outpoint)) return; /* Have to mark the entries as notleak since they'll not be * pointed to by anything other than the htable */ - op = notleak(tal(of->set, struct outpointfilter_entry)); - op->txid = *txid; - op->outnum = outnum; - outpointset_add(of->set, op); + outpointset_add(of->set, notleak(tal_dup(of->set, + struct bitcoin_outpoint, + outpoint))); } -bool outpointfilter_matches(struct outpointfilter *of, const struct bitcoin_txid *txid, const u32 outnum) +bool outpointfilter_matches(struct outpointfilter *of, + const struct bitcoin_outpoint *outpoint) { - struct outpointfilter_entry op; - op.txid = *txid; - op.outnum = outnum; - return outpointset_get(of->set, &op) != NULL; + return outpointset_get(of->set, outpoint) != NULL; } -void outpointfilter_remove(struct outpointfilter *of, const struct bitcoin_txid *txid, const u32 outnum) +void outpointfilter_remove(struct outpointfilter *of, + const struct bitcoin_outpoint *outpoint) { - struct outpointfilter_entry op; - op.txid = *txid; - op.outnum = outnum; - outpointset_del(of->set, &op); + outpointset_del(of->set, outpoint); } static void destroy_outpointfilter(struct outpointfilter *opf) diff --git a/wallet/txfilter.h b/wallet/txfilter.h index 6e862100629b..bed798394076 100644 --- a/wallet/txfilter.h +++ b/wallet/txfilter.h @@ -46,17 +46,17 @@ struct outpointfilter *outpointfilter_new(tal_t *ctx); * outpointfilter_add -- Add an outpoint to the filter */ void outpointfilter_add(struct outpointfilter *of, - const struct bitcoin_txid *txid, const u32 outnum); + const struct bitcoin_outpoint *outpoint); /** * outpointfilter_matches -- Are we tracking this outpoint? */ bool outpointfilter_matches(struct outpointfilter *of, - const struct bitcoin_txid *txid, const u32 outnum); + const struct bitcoin_outpoint *outpoint); /** * outpointfilter_remove -- Do not match this outpoint in the future */ void outpointfilter_remove(struct outpointfilter *of, - const struct bitcoin_txid *txid, const u32 outnum); + const struct bitcoin_outpoint *outpoint); #endif /* LIGHTNING_WALLET_TXFILTER_H */ diff --git a/wallet/wallet.c b/wallet/wallet.c index 71794fc0487b..a28d99ec98bb 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -49,12 +49,11 @@ static void outpointfilters_init(struct wallet *w) { struct db_stmt *stmt; struct utxo **utxos = wallet_get_utxos(NULL, w, OUTPUT_STATE_ANY); - struct bitcoin_txid txid; - u32 outnum; + struct bitcoin_outpoint outpoint; w->owned_outpoints = outpointfilter_new(w); for (size_t i = 0; i < tal_count(utxos); i++) - outpointfilter_add(w->owned_outpoints, &utxos[i]->txid, utxos[i]->outnum); + outpointfilter_add(w->owned_outpoints, &utxos[i]->outpoint); tal_free(utxos); @@ -65,9 +64,9 @@ static void outpointfilters_init(struct wallet *w) db_query_prepared(stmt); while (db_step(stmt)) { - db_column_sha256d(stmt, 0, &txid.shad); - outnum = db_column_int(stmt, 1); - outpointfilter_add(w->utxoset_outpoints, &txid, outnum); + db_column_txid(stmt, 0, &outpoint.txid); + outpoint.n = db_column_int(stmt, 1); + outpointfilter_add(w->utxoset_outpoints, &outpoint); } tal_free(stmt); } @@ -104,8 +103,8 @@ static bool wallet_add_utxo(struct wallet *w, struct utxo *utxo, stmt = db_prepare_v2(w->db, SQL("SELECT * from outputs WHERE " "prev_out_tx=? AND prev_out_index=?")); - db_bind_txid(stmt, 0, &utxo->txid); - db_bind_int(stmt, 1, utxo->outnum); + db_bind_txid(stmt, 0, &utxo->outpoint.txid); + db_bind_int(stmt, 1, utxo->outpoint.n); db_query_prepared(stmt); /* If we get a result, that means a clash. */ @@ -131,8 +130,8 @@ static bool wallet_add_utxo(struct wallet *w, struct utxo *utxo, ", spend_height" ", scriptpubkey" ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")); - db_bind_txid(stmt, 0, &utxo->txid); - db_bind_int(stmt, 1, utxo->outnum); + db_bind_txid(stmt, 0, &utxo->outpoint.txid); + db_bind_int(stmt, 1, utxo->outpoint.n); db_bind_amount_sat(stmt, 2, &utxo->amount); db_bind_int(stmt, 3, wallet_output_type_in_db(type)); db_bind_int(stmt, 4, OUTPUT_STATE_AVAILABLE); @@ -176,8 +175,8 @@ static struct utxo *wallet_stmt2output(const tal_t *ctx, struct db_stmt *stmt) { struct utxo *utxo = tal(ctx, struct utxo); u32 *blockheight, *spendheight; - db_column_txid(stmt, 0, &utxo->txid); - utxo->outnum = db_column_int(stmt, 1); + db_column_txid(stmt, 0, &utxo->outpoint.txid); + utxo->outpoint.n = db_column_int(stmt, 1); db_column_amount_sat(stmt, 2, &utxo->amount); utxo->is_p2sh = db_column_int(stmt, 3) == p2sh_wpkh; utxo->status = db_column_int(stmt, 4); @@ -226,8 +225,8 @@ static struct utxo *wallet_stmt2output(const tal_t *ctx, struct db_stmt *stmt) } bool wallet_update_output_status(struct wallet *w, - const struct bitcoin_txid *txid, - const u32 outnum, enum output_status oldstatus, + const struct bitcoin_outpoint *outpoint, + enum output_status oldstatus, enum output_status newstatus) { struct db_stmt *stmt; @@ -238,15 +237,15 @@ bool wallet_update_output_status(struct wallet *w, "prev_out_tx=? AND prev_out_index=?")); db_bind_int(stmt, 0, output_status_in_db(newstatus)); db_bind_int(stmt, 1, output_status_in_db(oldstatus)); - db_bind_txid(stmt, 2, txid); - db_bind_int(stmt, 3, outnum); + db_bind_txid(stmt, 2, &outpoint->txid); + db_bind_int(stmt, 3, outpoint->n); } else { stmt = db_prepare_v2(w->db, SQL("UPDATE outputs SET status=? WHERE " "prev_out_tx=? AND prev_out_index=?")); db_bind_int(stmt, 0, output_status_in_db(newstatus)); - db_bind_txid(stmt, 1, txid); - db_bind_int(stmt, 2, outnum); + db_bind_txid(stmt, 1, &outpoint->txid); + db_bind_int(stmt, 2, outpoint->n); } db_exec_prepared_v2(stmt); changes = db_count_changes(stmt); @@ -350,8 +349,7 @@ struct utxo **wallet_get_unconfirmed_closeinfo_utxos(const tal_t *ctx, } struct utxo *wallet_utxo_get(const tal_t *ctx, struct wallet *w, - const struct bitcoin_txid *txid, - u32 outnum) + const struct bitcoin_outpoint *outpoint) { struct db_stmt *stmt; struct utxo *utxo; @@ -376,8 +374,8 @@ struct utxo *wallet_utxo_get(const tal_t *ctx, struct wallet *w, " WHERE prev_out_tx = ?" " AND prev_out_index = ?")); - db_bind_sha256d(stmt, 0, &txid->shad); - db_bind_int(stmt, 1, outnum); + db_bind_txid(stmt, 0, &outpoint->txid); + db_bind_int(stmt, 1, outpoint->n); db_query_prepared(stmt); @@ -393,10 +391,9 @@ struct utxo *wallet_utxo_get(const tal_t *ctx, struct wallet *w, } bool wallet_unreserve_output(struct wallet *w, - const struct bitcoin_txid *txid, - const u32 outnum) + const struct bitcoin_outpoint *outpoint) { - return wallet_update_output_status(w, txid, outnum, + return wallet_update_output_status(w, outpoint, OUTPUT_STATE_RESERVED, OUTPUT_STATE_AVAILABLE); } @@ -406,7 +403,7 @@ bool wallet_unreserve_output(struct wallet *w, */ static void unreserve_utxo(struct wallet *w, const struct utxo *unres) { - if (!wallet_update_output_status(w, &unres->txid, unres->outnum, + if (!wallet_update_output_status(w, &unres->outpoint, OUTPUT_STATE_RESERVED, OUTPUT_STATE_AVAILABLE)) { fatal("Unable to unreserve output"); @@ -432,7 +429,7 @@ void wallet_confirm_utxos(struct wallet *w, const struct utxo **utxos) tal_del_destructor2(utxos, destroy_utxos, w); for (size_t i = 0; i < tal_count(utxos); i++) { if (!wallet_update_output_status( - w, &utxos[i]->txid, utxos[i]->outnum, + w, &utxos[i]->outpoint, OUTPUT_STATE_RESERVED, OUTPUT_STATE_SPENT)) { fatal("Unable to mark output as spent"); } @@ -453,8 +450,8 @@ static void db_set_utxo(struct db *db, const struct utxo *utxo) "WHERE prev_out_tx=? AND prev_out_index=?")); db_bind_int(stmt, 0, output_status_in_db(utxo->status)); db_bind_int(stmt, 1, utxo->reserved_til); - db_bind_txid(stmt, 2, &utxo->txid); - db_bind_int(stmt, 3, utxo->outnum); + db_bind_txid(stmt, 2, &utxo->outpoint.txid); + db_bind_int(stmt, 3, utxo->outpoint.n); db_exec_prepared_v2(take(stmt)); } @@ -490,9 +487,9 @@ void wallet_unreserve_utxo(struct wallet *w, struct utxo *utxo, u32 unreserve) { if (utxo->status != OUTPUT_STATE_RESERVED) - fatal("UTXO %s:%u is not reserved", - type_to_string(tmpctx, struct bitcoin_txid, &utxo->txid), - utxo->outnum); + fatal("UTXO %s is not reserved", + type_to_string(tmpctx, struct bitcoin_outpoint, + &utxo->outpoint)); if (utxo->reserved_til <= current_height + unreserve) { utxo->status = OUTPUT_STATE_AVAILABLE; @@ -507,8 +504,7 @@ static bool excluded(const struct utxo **excludes, const struct utxo *utxo) { for (size_t i = 0; i < tal_count(excludes); i++) { - if (bitcoin_txid_eq(&excludes[i]->txid, &utxo->txid) - && excludes[i]->outnum == utxo->outnum) + if (bitcoin_outpoint_eq(&excludes[i]->outpoint, &utxo->outpoint)) return true; } return false; @@ -594,8 +590,7 @@ struct utxo *wallet_find_utxo(const tal_t *ctx, struct wallet *w, } bool wallet_add_onchaind_utxo(struct wallet *w, - const struct bitcoin_txid *txid, - u32 outnum, + const struct bitcoin_outpoint *outpoint, const u8 *scriptpubkey, u32 blockheight, struct amount_sat amount, @@ -608,8 +603,8 @@ bool wallet_add_onchaind_utxo(struct wallet *w, stmt = db_prepare_v2(w->db, SQL("SELECT * from outputs WHERE " "prev_out_tx=? AND prev_out_index=?")); - db_bind_txid(stmt, 0, txid); - db_bind_int(stmt, 1, outnum); + db_bind_txid(stmt, 0, &outpoint->txid); + db_bind_int(stmt, 1, outpoint->n); db_query_prepared(stmt); /* If we get a result, that means a clash. */ @@ -636,8 +631,8 @@ bool wallet_add_onchaind_utxo(struct wallet *w, ", scriptpubkey" ", csv_lock" ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")); - db_bind_txid(stmt, 0, txid); - db_bind_int(stmt, 1, outnum); + db_bind_txid(stmt, 0, &outpoint->txid); + db_bind_int(stmt, 1, outpoint->n); db_bind_amount_sat(stmt, 2, &amount); db_bind_int(stmt, 3, wallet_output_type_in_db(p2wpkh)); db_bind_int(stmt, 4, OUTPUT_STATE_AVAILABLE); @@ -1049,8 +1044,8 @@ void wallet_inflight_add(struct wallet *w, struct channel_inflight *inflight) "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")); db_bind_u64(stmt, 0, inflight->channel->dbid); - db_bind_txid(stmt, 1, &inflight->funding->txid); - db_bind_int(stmt, 2, inflight->funding->outnum); + db_bind_txid(stmt, 1, &inflight->funding->outpoint.txid); + db_bind_int(stmt, 2, inflight->funding->outpoint.n); db_bind_int(stmt, 3, inflight->funding->feerate); db_bind_amount_sat(stmt, 4, &inflight->funding->total_funds); db_bind_amount_sat(stmt, 5, &inflight->funding->our_funds); @@ -1096,8 +1091,8 @@ void wallet_inflight_save(struct wallet *w, db_bind_psbt(stmt, 0, inflight->funding_psbt); db_bind_int(stmt, 1, inflight->remote_tx_sigs); db_bind_u64(stmt, 2, inflight->channel->dbid); - db_bind_txid(stmt, 3, &inflight->funding->txid); - db_bind_int(stmt, 4, inflight->funding->outnum); + db_bind_txid(stmt, 3, &inflight->funding->outpoint.txid); + db_bind_int(stmt, 4, inflight->funding->outpoint.n); db_exec_prepared_v2(take(stmt)); } @@ -1125,7 +1120,7 @@ wallet_stmt2inflight(struct wallet *w, struct db_stmt *stmt, struct channel *chan) { struct amount_sat funding_sat, our_funding_sat; - struct bitcoin_txid funding_txid; + struct bitcoin_outpoint funding; struct bitcoin_signature last_sig; struct channel_inflight *inflight; @@ -1133,7 +1128,8 @@ wallet_stmt2inflight(struct wallet *w, struct db_stmt *stmt, u32 lease_chan_max_msat, lease_blockheight_start; u16 lease_chan_max_ppt; - db_column_txid(stmt, 0, &funding_txid); + db_column_txid(stmt, 0, &funding.txid); + funding.n = db_column_int(stmt, 1), db_column_amount_sat(stmt, 3, &funding_sat); db_column_amount_sat(stmt, 4, &our_funding_sat); if (!db_column_signature(stmt, 7, &last_sig.s)) @@ -1154,8 +1150,7 @@ wallet_stmt2inflight(struct wallet *w, struct db_stmt *stmt, lease_blockheight_start = 0; } - inflight = new_inflight(chan, funding_txid, - db_column_int(stmt, 1), + inflight = new_inflight(chan, &funding, db_column_int(stmt, 2), funding_sat, our_funding_sat, @@ -1230,7 +1225,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm struct peer *peer; struct wallet_shachain wshachain; struct channel_config our_config; - struct bitcoin_txid funding_txid; + struct bitcoin_outpoint funding; struct bitcoin_outpoint *shutdown_wrong_funding; struct bitcoin_signature last_sig; u8 *remote_shutdown_scriptpubkey; @@ -1300,7 +1295,8 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm db_column_channel_id(stmt, 3, &cid); channel_config_id = db_column_u64(stmt, 4); ok &= wallet_channel_config_load(w, channel_config_id, &our_config); - db_column_sha256d(stmt, 13, &funding_txid.shad); + db_column_sha256d(stmt, 13, &funding.txid.shad); + funding.n = db_column_int(stmt, 14), ok &= db_column_signature(stmt, 35, &last_sig.s); last_sig.sighash_type = SIGHASH_ALL; @@ -1398,8 +1394,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm db_column_u64(stmt, 10), db_column_u64(stmt, 11), db_column_u64(stmt, 12), - &funding_txid, - db_column_int(stmt, 14), + &funding, funding_sat, push_msat, our_funding_sat, @@ -1846,10 +1841,10 @@ void wallet_channel_save(struct wallet *w, struct channel *chan) db_bind_u64(stmt, 8, chan->next_index[REMOTE]); db_bind_u64(stmt, 9, chan->next_htlc_id); - db_bind_sha256d(stmt, 10, &chan->funding_txid.shad); + db_bind_sha256d(stmt, 10, &chan->funding.txid.shad); - db_bind_int(stmt, 11, chan->funding_outnum); - db_bind_amount_sat(stmt, 12, &chan->funding); + db_bind_int(stmt, 11, chan->funding.n); + db_bind_amount_sat(stmt, 12, &chan->funding_sats); db_bind_amount_sat(stmt, 13, &chan->our_funds); db_bind_int(stmt, 14, chan->remote_funding_locked); db_bind_amount_msat(stmt, 15, &chan->push); @@ -2241,8 +2236,8 @@ int wallet_extract_owned_outputs(struct wallet *w, const struct wally_tx *wtx, utxo->is_p2sh = is_p2sh; utxo->amount = amount_asset_to_sat(&asset); utxo->status = OUTPUT_STATE_AVAILABLE; - wally_txid(wtx, &utxo->txid); - utxo->outnum = output; + wally_txid(wtx, &utxo->outpoint.txid); + utxo->outpoint.n = output; utxo->close_info = NULL; utxo->blockheight = blockheight ? blockheight : NULL; @@ -2255,11 +2250,13 @@ int wallet_extract_owned_outputs(struct wallet *w, const struct wally_tx *wtx, &utxo->amount), is_p2sh ? "P2SH" : "SEGWIT", type_to_string(tmpctx, struct bitcoin_txid, - &utxo->txid), blockheight ? " CONFIRMED" : ""); + &utxo->outpoint.txid), + blockheight ? " CONFIRMED" : ""); /* We only record final ledger movements */ if (blockheight) { - mvt = new_coin_deposit_sat(utxo, "wallet", &utxo->txid, utxo->outnum, + mvt = new_coin_deposit_sat(utxo, "wallet", + &utxo->outpoint, blockheight ? *blockheight : 0, utxo->amount); notify_chain_mvt(w->ld, mvt); @@ -2272,7 +2269,8 @@ int wallet_extract_owned_outputs(struct wallet *w, const struct wally_tx *wtx, * the output from a transaction we created * ourselves. */ if (blockheight) - wallet_confirm_tx(w, &utxo->txid, *blockheight); + wallet_confirm_tx(w, &utxo->outpoint.txid, + *blockheight); tal_free(utxo); continue; } @@ -2281,7 +2279,7 @@ int wallet_extract_owned_outputs(struct wallet *w, const struct wally_tx *wtx, if (!is_p2sh && !blockheight) txfilter_add_scriptpubkey(w->ld->owned_txfilter, script); - outpointfilter_add(w->owned_outpoints, &utxo->txid, utxo->outnum); + outpointfilter_add(w->owned_outpoints, &utxo->outpoint); if (!amount_sat_add(total, *total, utxo->amount)) fatal("Cannot add utxo output %zu/%zu %s + %s", @@ -2290,7 +2288,7 @@ int wallet_extract_owned_outputs(struct wallet *w, const struct wally_tx *wtx, type_to_string(tmpctx, struct amount_sat, &utxo->amount)); - wallet_annotate_txout(w, &utxo->txid, output, TX_WALLET_DEPOSIT, 0); + wallet_annotate_txout(w, &utxo->outpoint, TX_WALLET_DEPOSIT, 0); tal_free(utxo); num_utxos++; } @@ -3584,7 +3582,6 @@ bool wallet_network_check(struct wallet *w) static void wallet_utxoset_prune(struct wallet *w, const u32 blockheight) { struct db_stmt *stmt; - struct bitcoin_txid txid; stmt = db_prepare_v2( w->db, @@ -3593,9 +3590,10 @@ static void wallet_utxoset_prune(struct wallet *w, const u32 blockheight) db_query_prepared(stmt); while (db_step(stmt)) { - db_column_sha256d(stmt, 0, &txid.shad); - outpointfilter_remove(w->utxoset_outpoints, &txid, - db_column_int(stmt, 1)); + struct bitcoin_outpoint outpoint; + db_column_txid(stmt, 0, &outpoint.txid); + outpoint.n = db_column_int(stmt, 1); + outpointfilter_remove(w->utxoset_outpoints, &outpoint); } tal_free(stmt); @@ -3649,11 +3647,11 @@ void wallet_blocks_rollback(struct wallet *w, u32 height) } bool wallet_outpoint_spend(struct wallet *w, const tal_t *ctx, const u32 blockheight, - const struct bitcoin_txid *txid, const u32 outnum) + const struct bitcoin_outpoint *outpoint) { struct db_stmt *stmt; bool our_spend; - if (outpointfilter_matches(w->owned_outpoints, txid, outnum)) { + if (outpointfilter_matches(w->owned_outpoints, outpoint)) { stmt = db_prepare_v2(w->db, SQL("UPDATE outputs " "SET spend_height = ?, " " status = ? " @@ -3662,8 +3660,8 @@ bool wallet_outpoint_spend(struct wallet *w, const tal_t *ctx, const u32 blockhe db_bind_int(stmt, 0, blockheight); db_bind_int(stmt, 1, output_status_in_db(OUTPUT_STATE_SPENT)); - db_bind_sha256d(stmt, 2, &txid->shad); - db_bind_int(stmt, 3, outnum); + db_bind_txid(stmt, 2, &outpoint->txid); + db_bind_int(stmt, 3, outpoint->n); db_exec_prepared_v2(take(stmt)); @@ -3671,29 +3669,28 @@ bool wallet_outpoint_spend(struct wallet *w, const tal_t *ctx, const u32 blockhe } else our_spend = false; - if (outpointfilter_matches(w->utxoset_outpoints, txid, outnum)) { + if (outpointfilter_matches(w->utxoset_outpoints, outpoint)) { stmt = db_prepare_v2(w->db, SQL("UPDATE utxoset " "SET spendheight = ? " "WHERE txid = ?" " AND outnum = ?")); db_bind_int(stmt, 0, blockheight); - db_bind_sha256d(stmt, 1, &txid->shad); - db_bind_int(stmt, 2, outnum); + db_bind_txid(stmt, 1, &outpoint->txid); + db_bind_int(stmt, 2, outpoint->n); db_exec_prepared_v2(stmt); tal_free(stmt); } return our_spend; } -void wallet_utxoset_add(struct wallet *w, const struct bitcoin_tx *tx, - const u32 outnum, const u32 blockheight, +void wallet_utxoset_add(struct wallet *w, + const struct bitcoin_outpoint *outpoint, + const u32 blockheight, const u32 txindex, const u8 *scriptpubkey, struct amount_sat sat) { struct db_stmt *stmt; - struct bitcoin_txid txid; - bitcoin_txid(tx, &txid); stmt = db_prepare_v2(w->db, SQL("INSERT INTO utxoset (" " txid," @@ -3704,8 +3701,8 @@ void wallet_utxoset_add(struct wallet *w, const struct bitcoin_tx *tx, " scriptpubkey," " satoshis" ") VALUES(?, ?, ?, ?, ?, ?, ?);")); - db_bind_sha256d(stmt, 0, &txid.shad); - db_bind_int(stmt, 1, outnum); + db_bind_txid(stmt, 0, &outpoint->txid); + db_bind_int(stmt, 1, outpoint->n); db_bind_int(stmt, 2, blockheight); db_bind_null(stmt, 3); db_bind_int(stmt, 4, txindex); @@ -3713,7 +3710,7 @@ void wallet_utxoset_add(struct wallet *w, const struct bitcoin_tx *tx, db_bind_amount_sat(stmt, 6, &sat); db_exec_prepared_v2(take(stmt)); - outpointfilter_add(w->utxoset_outpoints, &txid, outnum); + outpointfilter_add(w->utxoset_outpoints, outpoint); } void wallet_filteredblock_add(struct wallet *w, const struct filteredblock *fb) @@ -3742,8 +3739,8 @@ void wallet_filteredblock_add(struct wallet *w, const struct filteredblock *fb) " scriptpubkey," " satoshis" ") VALUES(?, ?, ?, ?, ?, ?, ?);")); - db_bind_sha256d(stmt, 0, &o->txid.shad); - db_bind_int(stmt, 1, o->outnum); + db_bind_txid(stmt, 0, &o->outpoint.txid); + db_bind_int(stmt, 1, o->outpoint.n); db_bind_int(stmt, 2, fb->height); db_bind_null(stmt, 3); db_bind_int(stmt, 4, o->txindex); @@ -3751,7 +3748,7 @@ void wallet_filteredblock_add(struct wallet *w, const struct filteredblock *fb) db_bind_amount_sat(stmt, 6, &o->amount); db_exec_prepared_v2(take(stmt)); - outpointfilter_add(w->utxoset_outpoints, &o->txid, o->outnum); + outpointfilter_add(w->utxoset_outpoints, &o->outpoint); } } @@ -3795,8 +3792,8 @@ struct outpoint *wallet_outpoint_for_scid(struct wallet *w, tal_t *ctx, op = tal(ctx, struct outpoint); op->blockheight = short_channel_id_blocknum(scid); op->txindex = short_channel_id_txnum(scid); - op->outnum = short_channel_id_outnum(scid); - db_column_sha256d(stmt, 0, &op->txid.shad); + op->outpoint.n = short_channel_id_outnum(scid); + db_column_txid(stmt, 0, &op->outpoint.txid); if (db_column_is_null(stmt, 1)) op->spendheight = 0; else @@ -3933,10 +3930,12 @@ static void wallet_annotation_add(struct wallet *w, const struct bitcoin_txid *t db_exec_prepared_v2(take(stmt)); } -void wallet_annotate_txout(struct wallet *w, const struct bitcoin_txid *txid, - int outnum, enum wallet_tx_type type, u64 channel) +void wallet_annotate_txout(struct wallet *w, + const struct bitcoin_outpoint *outpoint, + enum wallet_tx_type type, u64 channel) { - wallet_annotation_add(w, txid, outnum, OUTPUT_ANNOTATION, type, channel); + wallet_annotation_add(w, &outpoint->txid, outpoint->n, + OUTPUT_ANNOTATION, type, channel); } void wallet_annotate_txin(struct wallet *w, const struct bitcoin_txid *txid, diff --git a/wallet/wallet.h b/wallet/wallet.h index 9215e2824c58..85de90b1f5e2 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -325,10 +325,9 @@ struct wallet_payment { }; struct outpoint { - struct bitcoin_txid txid; + struct bitcoin_outpoint outpoint; u32 blockheight; u32 txindex; - u32 outnum; struct amount_sat sat; u8 *scriptpubkey; u32 spendheight; @@ -397,8 +396,8 @@ void wallet_confirm_tx(struct wallet *w, * `output_state_any` as @oldstatus. */ bool wallet_update_output_status(struct wallet *w, - const struct bitcoin_txid *txid, - const u32 outnum, enum output_status oldstatus, + const struct bitcoin_outpoint *outpoint, + enum output_status oldstatus, enum output_status newstatus); /** @@ -452,8 +451,7 @@ struct utxo *wallet_find_utxo(const tal_t *ctx, struct wallet *w, * Returns false if we already have it in db (that's fine). */ bool wallet_add_onchaind_utxo(struct wallet *w, - const struct bitcoin_txid *txid, - u32 outnum, + const struct bitcoin_outpoint *outpoint, const u8 *scriptpubkey, u32 blockheight, struct amount_sat amount, @@ -490,8 +488,7 @@ void wallet_unreserve_utxo(struct wallet *w, struct utxo *utxo, * Returns a utxo, or NULL if not found. */ struct utxo *wallet_utxo_get(const tal_t *ctx, struct wallet *w, - const struct bitcoin_txid *txid, - u32 outnum); + const struct bitcoin_outpoint *outpoint); /** * wallet_select_specific - Select utxos given an array of txids and an array of outputs index @@ -1245,13 +1242,14 @@ bool wallet_have_block(struct wallet *w, u32 blockheight); */ bool wallet_outpoint_spend(struct wallet *w, const tal_t *ctx, const u32 blockheight, - const struct bitcoin_txid *txid, const u32 outnum); + const struct bitcoin_outpoint *outpoint); struct outpoint *wallet_outpoint_for_scid(struct wallet *w, tal_t *ctx, const struct short_channel_id *scid); -void wallet_utxoset_add(struct wallet *w, const struct bitcoin_tx *tx, - const u32 outnum, const u32 blockheight, +void wallet_utxoset_add(struct wallet *w, + const struct bitcoin_outpoint *outpoint, + const u32 blockheight, const u32 txindex, const u8 *scriptpubkey, struct amount_sat sat); @@ -1279,8 +1277,9 @@ wallet_utxoset_get_created(const tal_t *ctx, struct wallet *w, u32 blockheight); void wallet_transaction_add(struct wallet *w, const struct wally_tx *tx, const u32 blockheight, const u32 txindex); -void wallet_annotate_txout(struct wallet *w, const struct bitcoin_txid *txid, - int outnum, enum wallet_tx_type type, u64 channel); +void wallet_annotate_txout(struct wallet *w, + const struct bitcoin_outpoint *outpoint, + enum wallet_tx_type type, u64 channel); void wallet_annotate_txin(struct wallet *w, const struct bitcoin_txid *txid, int innum, enum wallet_tx_type type, u64 channel); @@ -1423,8 +1422,7 @@ void wallet_persist_utxo_reservation(struct wallet *w, const struct utxo **utxos * We unreserve utxos so that they can be spent elsewhere. * */ bool wallet_unreserve_output(struct wallet *w, - const struct bitcoin_txid *txid, - const u32 outnum); + const struct bitcoin_outpoint *outpoint); /** * Get a list of transactions that we track in the wallet. * diff --git a/wallet/walletrpc.c b/wallet/walletrpc.c index 33b60fbd9e33..6fe87d0bb334 100644 --- a/wallet/walletrpc.c +++ b/wallet/walletrpc.c @@ -239,8 +239,8 @@ static void json_add_utxo(struct json_stream *response, bool reserved; json_object_start(response, fieldname); - json_add_txid(response, "txid", &utxo->txid); - json_add_num(response, "output", utxo->outnum); + json_add_txid(response, "txid", &utxo->outpoint.txid); + json_add_num(response, "output", utxo->outpoint.n); json_add_amount_sat_compat(response, utxo->amount, "value", "amount_msat"); @@ -257,11 +257,10 @@ static void json_add_utxo(struct json_stream *response, utxo->scriptPubkey); if (!out) log_broken(wallet->log, - "Could not encode utxo %s:%u%s!", + "Could not encode utxo %s%s!", type_to_string(tmpctx, - struct bitcoin_txid, - &utxo->txid), - utxo->outnum, + struct bitcoin_outpoint, + &utxo->outpoint), utxo->close_info ? " (has close_info)" : ""); else json_add_string(response, "address", out); @@ -354,13 +353,13 @@ static struct command_result *json_listfunds(struct command *cmd, amount_msat_to_sat_round_down(c->our_msat), "channel_sat", "our_amount_msat"); - json_add_amount_sat_compat(response, c->funding, + json_add_amount_sat_compat(response, c->funding_sats, "channel_total_sat", "amount_msat"); json_add_txid(response, "funding_txid", - &c->funding_txid); + &c->funding.txid); json_add_num(response, "funding_output", - c->funding_outnum); + c->funding.n); json_object_end(response); } } @@ -399,12 +398,12 @@ static void process_utxo_result(struct bitcoind *bitcoind, txout == NULL ? OUTPUT_STATE_SPENT : OUTPUT_STATE_AVAILABLE; json_object_start(rescan->response, NULL); - json_add_txid(response, "txid", &u->txid); - json_add_num(response, "output", u->outnum); + json_add_txid(response, "txid", &u->outpoint.txid); + json_add_num(response, "output", u->outpoint.n); json_add_num(response, "oldstate", u->status); json_add_num(response, "newstate", newstate); json_object_end(rescan->response); - wallet_update_output_status(bitcoind->ld->wallet, &u->txid, u->outnum, + wallet_update_output_status(bitcoind->ld->wallet, &u->outpoint, u->status, newstate); /* Remove the utxo we just resolved */ @@ -416,9 +415,9 @@ static void process_utxo_result(struct bitcoind *bitcoind, json_array_end(rescan->response); was_pending(command_success(rescan->cmd, rescan->response)); } else { - bitcoind_getutxout( - bitcoind->ld->topology->bitcoind, &rescan->utxos[0]->txid, - rescan->utxos[0]->outnum, process_utxo_result, rescan); + bitcoind_getutxout(bitcoind->ld->topology->bitcoind, + &rescan->utxos[0]->outpoint, + process_utxo_result, rescan); } } @@ -442,9 +441,10 @@ static struct command_result *json_dev_rescan_outputs(struct command *cmd, json_array_end(rescan->response); return command_success(cmd, rescan->response); } - bitcoind_getutxout(cmd->ld->topology->bitcoind, &rescan->utxos[0]->txid, - rescan->utxos[0]->outnum, process_utxo_result, - rescan); + bitcoind_getutxout(cmd->ld->topology->bitcoind, + &rescan->utxos[0]->outpoint, + process_utxo_result, + rescan); return command_still_pending(cmd); } @@ -626,31 +626,28 @@ static struct command_result *match_psbt_inputs_to_utxos(struct command *cmd, *utxos = tal_arr(cmd, struct utxo *, 0); for (size_t i = 0; i < psbt->tx->num_inputs; i++) { struct utxo *utxo; - struct bitcoin_txid txid; + struct bitcoin_outpoint outpoint; if (only_inputs && !in_only_inputs(only_inputs, i)) continue; - wally_tx_input_get_txid(&psbt->tx->inputs[i], &txid); - utxo = wallet_utxo_get(*utxos, cmd->ld->wallet, - &txid, psbt->tx->inputs[i].index); + wally_tx_input_get_outpoint(&psbt->tx->inputs[i], &outpoint); + utxo = wallet_utxo_get(*utxos, cmd->ld->wallet, &outpoint); if (!utxo) { if (only_inputs) return command_fail(cmd, LIGHTNINGD, - "Aborting PSBT signing. UTXO %s:%u is unknown (and specified by signonly)", - type_to_string(tmpctx, struct bitcoin_txid, - &txid), - psbt->tx->inputs[i].index); + "Aborting PSBT signing. UTXO %s is unknown (and specified by signonly)", + type_to_string(tmpctx, struct bitcoin_outpoint, + &outpoint)); continue; } /* Oops we haven't reserved this utxo yet! */ if (!utxo_is_reserved(utxo, get_block_height(cmd->ld->topology))) return command_fail(cmd, LIGHTNINGD, - "Aborting PSBT signing. UTXO %s:%u is not reserved", - type_to_string(tmpctx, struct bitcoin_txid, - &utxo->txid), - utxo->outnum); + "Aborting PSBT signing. UTXO %s is not reserved", + type_to_string(tmpctx, struct bitcoin_outpoint, + &utxo->outpoint)); tal_arr_expand(utxos, utxo); } From 195a18da1999a78c4363755c82b04004eb4d0d24 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Oct 2021 14:15:36 +1030 Subject: [PATCH 13/16] onchaind: tell lightningd our commitment number, then get htlcs. This makes init a two-stage, and causes some code hoisting. And we can now send all the HTLCs in a single message, since we have an 128MB limit and each HTLC is 37 bytes. This breaks the onchaind stresstest, which uses canned internal messages. It's time to finally delete that. Signed-off-by: Rusty Russell --- lightningd/onchain_control.c | 128 ++++++++------- onchaind/onchaind.c | 187 +++++++++++---------- onchaind/onchaind_wire.csv | 18 +-- onchaind/test/run-grind_feerate-bug.c | 10 +- onchaind/test/run-grind_feerate.c | 10 +- onchaind/test/run-onchainstress.c | 223 -------------------------- 6 files changed, 178 insertions(+), 398 deletions(-) delete mode 100644 onchaind/test/run-onchainstress.c diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index 242ab495e8f7..d2ee1ab7d904 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -70,14 +70,79 @@ static void onchaind_tell_fulfill(struct channel *channel) } } -static void handle_onchain_init_reply(struct channel *channel, const u8 *msg UNUSED) +/* If we want to know if this HTLC is missing, return depth. */ +static bool tell_if_missing(const struct channel *channel, + struct htlc_stub *stub, + bool *tell_immediate) { + struct htlc_out *hout; + + /* Keep valgrind happy. */ + *tell_immediate = false; + + /* Don't care about incoming HTLCs, just ones we offered. */ + if (stub->owner == REMOTE) + return false; + + /* Might not be a current HTLC. */ + hout = find_htlc_out(&channel->peer->ld->htlcs_out, channel, stub->id); + if (!hout) + return false; + + /* BOLT #5: + * + * - for any committed HTLC that does NOT have an output in this + * commitment transaction: + * - once the commitment transaction has reached reasonable depth: + * - MUST fail the corresponding incoming HTLC (if any). + * - if no *valid* commitment transaction contains an output + * corresponding to the HTLC. + * - MAY fail the corresponding incoming HTLC sooner. + */ + if (hout->hstate >= RCVD_ADD_REVOCATION + && hout->hstate < SENT_REMOVE_REVOCATION) + *tell_immediate = true; + + log_debug(channel->log, + "We want to know if htlc %"PRIu64" is missing (%s)", + hout->key.id, *tell_immediate ? "immediate" : "later"); + return true; +} + +static void handle_onchain_init_reply(struct channel *channel, const u8 *msg) +{ + struct htlc_stub *stubs; + u64 commit_num; + bool *tell, *tell_immediate; + + if (!fromwire_onchaind_init_reply(msg, &commit_num)) { + channel_internal_error(channel, "Invalid onchaind_init_reply %s", + tal_hex(tmpctx, msg)); + return; + } + /* FIXME: We may already be ONCHAIN state when we implement restart! */ channel_set_state(channel, FUNDING_SPEND_SEEN, ONCHAIN, REASON_UNKNOWN, "Onchain init reply"); + + /* Tell it about any relevant HTLCs */ + /* FIXME: Filter by commitnum! */ + stubs = wallet_htlc_stubs(tmpctx, channel->peer->ld->wallet, channel); + tell = tal_arr(stubs, bool, tal_count(stubs)); + tell_immediate = tal_arr(stubs, bool, tal_count(stubs)); + + for (size_t i = 0; i < tal_count(stubs); i++) { + tell[i] = tell_if_missing(channel, &stubs[i], + &tell_immediate[i]); + } + msg = towire_onchaind_htlcs(channel, stubs, tell, tell_immediate); + subd_send_msg(channel->owner, take(msg)); + + /* Tell it about any preimages we know. */ + onchaind_tell_fulfill(channel); } /** @@ -492,7 +557,7 @@ static unsigned int onchain_msg(struct subd *sd, const u8 *msg, const int *fds U case WIRE_ONCHAIND_INIT: case WIRE_ONCHAIND_SPENT: case WIRE_ONCHAIND_DEPTH: - case WIRE_ONCHAIND_HTLC: + case WIRE_ONCHAIND_HTLCS: case WIRE_ONCHAIND_KNOWN_PREIMAGE: case WIRE_ONCHAIND_DEV_MEMLEAK: case WIRE_ONCHAIND_DEV_MEMLEAK_REPLY: @@ -502,45 +567,6 @@ static unsigned int onchain_msg(struct subd *sd, const u8 *msg, const int *fds U return 0; } -/* If we want to know if this HTLC is missing, return depth. */ -static bool tell_if_missing(const struct channel *channel, - struct htlc_stub *stub, - bool *tell_immediate) -{ - struct htlc_out *hout; - - /* Keep valgrind happy. */ - *tell_immediate = false; - - /* Don't care about incoming HTLCs, just ones we offered. */ - if (stub->owner == REMOTE) - return false; - - /* Might not be a current HTLC. */ - hout = find_htlc_out(&channel->peer->ld->htlcs_out, channel, stub->id); - if (!hout) - return false; - - /* BOLT #5: - * - * - for any committed HTLC that does NOT have an output in this - * commitment transaction: - * - once the commitment transaction has reached reasonable depth: - * - MUST fail the corresponding incoming HTLC (if any). - * - if no *valid* commitment transaction contains an output - * corresponding to the HTLC. - * - MAY fail the corresponding incoming HTLC sooner. - */ - if (hout->hstate >= RCVD_ADD_REVOCATION - && hout->hstate < SENT_REMOVE_REVOCATION) - *tell_immediate = true; - - log_debug(channel->log, - "We want to know if htlc %"PRIu64" is missing (%s)", - hout->key.id, *tell_immediate ? "immediate" : "later"); - return true; -} - /* Only error onchaind can get is if it dies. */ static void onchain_error(struct channel *channel, struct per_peer_state *pps UNUSED, @@ -564,7 +590,6 @@ enum watch_result onchaind_funding_spent(struct channel *channel, { u8 *msg; struct bitcoin_txid our_last_txid; - struct htlc_stub *stubs; struct lightningd *ld = channel->peer->ld; struct pubkey final_key; int hsmfd; @@ -609,12 +634,6 @@ enum watch_result onchaind_funding_spent(struct channel *channel, return KEEP_WATCHING; } - stubs = wallet_htlc_stubs(tmpctx, ld->wallet, channel); - if (!stubs) { - log_broken(channel->log, "Could not load htlc_stubs"); - return KEEP_WATCHING; - } - if (!bip32_pubkey(ld->wallet->bip32_base, &final_key, channel->final_key_idx)) { log_broken(channel->log, "Could not derive onchain key %"PRIu64, @@ -695,7 +714,6 @@ enum watch_result onchaind_funding_spent(struct channel *channel, /* FIXME: config for 'reasonable depth' */ 3, channel->last_htlc_sigs, - tal_count(stubs), channel->min_possible_feerate, channel->max_possible_feerate, channel->future_per_commitment_point, @@ -708,18 +726,6 @@ enum watch_result onchaind_funding_spent(struct channel *channel, feerate_min(ld, NULL)); subd_send_msg(channel->owner, take(msg)); - /* FIXME: Don't queue all at once, use an empty cb... */ - for (size_t i = 0; i < tal_count(stubs); i++) { - bool tell_immediate; - bool tell = tell_if_missing(channel, &stubs[i], &tell_immediate); - msg = towire_onchaind_htlc(channel, &stubs[i], - tell, tell_immediate); - subd_send_msg(channel->owner, take(msg)); - } - - /* Tell it about any preimages we know. */ - onchaind_tell_fulfill(channel); - watch_tx_and_outputs(channel, tx); /* We keep watching until peer finally deleted, for reorgs. */ diff --git a/onchaind/onchaind.c b/onchaind/onchaind.c index b2973a4fecd9..eafe7b5d09f7 100644 --- a/onchaind/onchaind.c +++ b/onchaind/onchaind.c @@ -2222,11 +2222,55 @@ static void wait_for_resolved(struct tracked_output **outs) take(towire_onchaind_all_irrevocably_resolved(outs))); } -static void init_reply(const char *what) +static int cmp_htlc_cltv(const struct htlc_stub *a, + const struct htlc_stub *b, void *unused) +{ + if (a->cltv_expiry < b->cltv_expiry) + return -1; + else if (a->cltv_expiry > b->cltv_expiry) + return 1; + return 0; +} + +struct htlcs_info { + struct htlc_stub *htlcs; + bool *tell_if_missing; + bool *tell_immediately; +}; + +static struct htlcs_info *init_reply(const tal_t *ctx, const char *what) { + struct htlcs_info *htlcs_info = tal(ctx, struct htlcs_info); + u8 *msg; + + /* commit_num is 0 for mutual close, but we don't care about HTLCs + * then anyway. */ + /* Send init_reply first, so billboard gets credited to ONCHAIND */ - wire_sync_write(REQ_FD, take(towire_onchaind_init_reply(NULL))); + wire_sync_write(REQ_FD, + take(towire_onchaind_init_reply(NULL, commit_num))); + peer_billboard(true, what); + + /* Read in htlcs */ + /* FIXME: queue other messages! */ + msg = wire_sync_read(tmpctx, REQ_FD); + if (!fromwire_onchaind_htlcs(htlcs_info, msg, + &htlcs_info->htlcs, + &htlcs_info->tell_if_missing, + &htlcs_info->tell_immediately)) + master_badmsg(WIRE_ONCHAIND_HTLCS, msg); + + /* We want htlcs to be a valid tal parent, so make it a zero-length + * array if NULL (fromwire makes it NULL if there are no entries) */ + if (!htlcs_info->htlcs) + htlcs_info->htlcs = tal_arr(htlcs_info, struct htlc_stub, 0); + + /* Sort by CLTV, so matches are in CLTV order (and easy to skip dups) */ + asort(htlcs_info->htlcs, tal_count(htlcs_info->htlcs), + cmp_htlc_cltv, NULL); + + return htlcs_info; } static void handle_mutual_close(struct tracked_output **outs, @@ -2236,7 +2280,9 @@ static void handle_mutual_close(struct tracked_output **outs, bool is_replay) { struct amount_sat our_out; - init_reply("Tracking mutual close transaction"); + + /* In this case, we don't care about htlcs: there are none. */ + init_reply(tmpctx, "Tracking mutual close transaction"); /* Annotate the first input as close. We can currently only have a * single input for these. */ @@ -2526,11 +2572,9 @@ static enum side matches_direction(const size_t *matches, /* Tell master about any we didn't use, if it wants to know. */ static void note_missing_htlcs(u8 **htlc_scripts, - const struct htlc_stub *htlcs, - const bool *tell_if_missing, - const bool *tell_immediately) + const struct htlcs_info *htlcs_info) { - for (size_t i = 0; i < tal_count(htlcs); i++) { + for (size_t i = 0; i < tal_count(htlcs_info->htlcs); i++) { u8 *msg; /* Used. */ @@ -2538,12 +2582,12 @@ static void note_missing_htlcs(u8 **htlc_scripts, continue; /* Doesn't care. */ - if (!tell_if_missing[i]) + if (!htlcs_info->tell_if_missing[i]) continue; msg = towire_onchaind_missing_htlc_output(missing_htlc_msgs, - &htlcs[i]); - if (tell_immediately[i]) + &htlcs_info->htlcs[i]); + if (htlcs_info->tell_immediately[i]) wire_sync_write(REQ_FD, take(msg)); else tal_arr_expand(&missing_htlc_msgs, msg); @@ -2645,9 +2689,6 @@ static void our_unilateral_to_us(struct tracked_output ***outs, static void handle_our_unilateral(const struct tx_parts *tx, u32 tx_blockheight, const struct basepoints basepoints[NUM_SIDES], - const struct htlc_stub *htlcs, - const bool *tell_if_missing, - const bool *tell_immediately, const enum side opener, const struct bitcoin_signature *remote_htlc_sigs, struct tracked_output **outs, @@ -2659,8 +2700,9 @@ static void handle_our_unilateral(const struct tx_parts *tx, struct keyset *ks; size_t i; struct amount_sat their_outs = AMOUNT_SAT(0), our_outs = AMOUNT_SAT(0); + struct htlcs_info *htlcs_info; - init_reply("Tracking our own unilateral close"); + htlcs_info = init_reply(tx, "Tracking our own unilateral close"); onchain_annotate_txin(&tx->txid, 0, TX_CHANNEL_UNILATERAL); /* BOLT #5: @@ -2716,7 +2758,7 @@ static void handle_our_unilateral(const struct tx_parts *tx, &keyset->other_payment_key, 1); /* Calculate all the HTLC scripts so we can match them */ - htlc_scripts = derive_htlc_scripts(htlcs, LOCAL); + htlc_scripts = derive_htlc_scripts(htlcs_info->htlcs, LOCAL); status_debug("Script to-me: %u: %s (%s)", to_self_delay[LOCAL], @@ -2909,7 +2951,7 @@ static void handle_our_unilateral(const struct tx_parts *tx, i); } - if (matches_direction(matches, htlcs) == LOCAL) { + if (matches_direction(matches, htlcs_info->htlcs) == LOCAL) { /* BOLT #5: * * - MUST handle HTLCs offered by itself as specified @@ -2925,7 +2967,7 @@ static void handle_our_unilateral(const struct tx_parts *tx, remote_htlc_sigs); /* Tells us which htlc to use */ which_htlc = resolve_our_htlc_ourcommit(out, matches, - htlcs, + htlcs_info->htlcs, htlc_scripts, is_replay); add_amt(&our_outs, amt); @@ -2944,12 +2986,13 @@ static void handle_our_unilateral(const struct tx_parts *tx, * Commitment, Remote Offers] */ /* Tells us which htlc to use */ - which_htlc = resolve_their_htlc(out, matches, htlcs, + which_htlc = resolve_their_htlc(out, matches, + htlcs_info->htlcs, htlc_scripts, is_replay); add_amt(&their_outs, amt); } - out->htlc = htlcs[which_htlc]; + out->htlc = htlcs_info->htlcs[which_htlc]; out->wscript = tal_steal(out, htlc_scripts[which_htlc]); /* Each of these consumes one HTLC signature */ @@ -2959,13 +3002,13 @@ static void handle_our_unilateral(const struct tx_parts *tx, } - note_missing_htlcs(htlc_scripts, htlcs, - tell_if_missing, tell_immediately); + note_missing_htlcs(htlc_scripts, htlcs_info); + tal_free(htlcs_info); + if (!is_replay) record_chain_fees_unilateral(&tx->txid, tx_blockheight, outs[0]->sat, their_outs, our_outs); - wait_for_resolved(outs); } @@ -3130,9 +3173,6 @@ static void handle_their_cheat(const struct tx_parts *tx, u32 tx_blockheight, const struct secret *revocation_preimage, const struct basepoints basepoints[NUM_SIDES], - const struct htlc_stub *htlcs, - const bool *tell_if_missing, - const bool *tell_immediately, const enum side opener, struct tracked_output **outs, bool is_replay) @@ -3146,8 +3186,10 @@ static void handle_their_cheat(const struct tx_parts *tx, * for this unilateral tx are */ struct amount_sat total_outs = AMOUNT_SAT(0), fee_cost; bool amt_ok; + struct htlcs_info *htlcs_info; - init_reply("Tracking their illegal close: taking all funds"); + htlcs_info = init_reply(tx, + "Tracking their illegal close: taking all funds"); onchain_annotate_txin( &tx->txid, 0, TX_CHANNEL_UNILATERAL | TX_CHANNEL_CHEAT | TX_THEIRS); @@ -3245,7 +3287,7 @@ static void handle_their_cheat(const struct tx_parts *tx, &keyset->other_payment_key, 1); /* Calculate all the HTLC scripts so we can match them */ - htlc_scripts = derive_htlc_scripts(htlcs, REMOTE); + htlc_scripts = derive_htlc_scripts(htlcs_info->htlcs, REMOTE); status_debug("Script to-them: %u: %s (%s)", to_self_delay[REMOTE], @@ -3427,7 +3469,7 @@ static void handle_their_cheat(const struct tx_parts *tx, /* In this case, we don't care which HTLC we choose; so pick first one */ which_htlc = matches[0]; - if (matches_direction(matches, htlcs) == LOCAL) { + if (matches_direction(matches, htlcs_info->htlcs) == LOCAL) { /* BOLT #5: * * - MUST *resolve* the _local node's offered HTLCs_ in one of three ways: @@ -3440,7 +3482,7 @@ static void handle_their_cheat(const struct tx_parts *tx, THEIR_REVOKED_UNILATERAL, amt, OUR_HTLC, - &htlcs[which_htlc], + &htlcs_info->htlcs[which_htlc], htlc_scripts[which_htlc], NULL); steal_htlc(out, is_replay); @@ -3451,7 +3493,7 @@ static void handle_their_cheat(const struct tx_parts *tx, THEIR_REVOKED_UNILATERAL, amt, THEIR_HTLC, - &htlcs[which_htlc], + &htlcs_info->htlcs[which_htlc], htlc_scripts[which_htlc], NULL); /* BOLT #5: @@ -3467,8 +3509,8 @@ static void handle_their_cheat(const struct tx_parts *tx, htlc_scripts[which_htlc] = NULL; } - note_missing_htlcs(htlc_scripts, htlcs, - tell_if_missing, tell_immediately); + note_missing_htlcs(htlc_scripts, htlcs_info); + tal_free(htlcs_info); /* Record the fee cost for this tx, deducting it from channel balance */ amt_ok = amount_sat_sub(&fee_cost, outs[0]->sat, total_outs); @@ -3486,9 +3528,6 @@ static void handle_their_unilateral(const struct tx_parts *tx, u32 tx_blockheight, const struct pubkey *this_remote_per_commitment_point, const struct basepoints basepoints[NUM_SIDES], - const struct htlc_stub *htlcs, - const bool *tell_if_missing, - const bool *tell_immediately, const enum side opener, struct tracked_output **outs, bool is_replay) @@ -3498,8 +3537,9 @@ static void handle_their_unilateral(const struct tx_parts *tx, struct keyset *ks; size_t i; struct amount_sat their_outs = AMOUNT_SAT(0), our_outs = AMOUNT_SAT(0); + struct htlcs_info *htlcs_info; - init_reply("Tracking their unilateral close"); + htlcs_info = init_reply(tx, "Tracking their unilateral close"); onchain_annotate_txin(&tx->txid, 0, TX_CHANNEL_UNILATERAL | TX_THEIRS); /* HSM can't derive this. */ @@ -3576,7 +3616,7 @@ static void handle_their_unilateral(const struct tx_parts *tx, &keyset->other_htlc_key)); /* Calculate all the HTLC scripts so we can match them */ - htlc_scripts = derive_htlc_scripts(htlcs, REMOTE); + htlc_scripts = derive_htlc_scripts(htlcs_info->htlcs, REMOTE); get_anchor_scriptpubkeys(tmpctx, anchor); @@ -3765,7 +3805,7 @@ static void handle_their_unilateral(const struct tx_parts *tx, i); } - if (matches_direction(matches, htlcs) == LOCAL) { + if (matches_direction(matches, htlcs_info->htlcs) == LOCAL) { /* BOLT #5: * * - MUST handle HTLCs offered by itself as specified in @@ -3781,7 +3821,7 @@ static void handle_their_unilateral(const struct tx_parts *tx, NULL); which_htlc = resolve_our_htlc_theircommit(out, matches, - htlcs, + htlcs_info->htlcs, htlc_scripts, is_replay); add_amt(&our_outs, amt); @@ -3799,17 +3839,18 @@ static void handle_their_unilateral(const struct tx_parts *tx, * specified in [HTLC Output Handling: Remote * Commitment, Remote Offers] */ - which_htlc = resolve_their_htlc(out, matches, htlcs, + which_htlc = resolve_their_htlc(out, matches, + htlcs_info->htlcs, htlc_scripts, is_replay); add_amt(&their_outs, amt); } - out->htlc = htlcs[which_htlc]; + out->htlc = htlcs_info->htlcs[which_htlc]; out->wscript = tal_steal(out, htlc_scripts[which_htlc]); htlc_scripts[which_htlc] = NULL; } - note_missing_htlcs(htlc_scripts, htlcs, - tell_if_missing, tell_immediately); + note_missing_htlcs(htlc_scripts, htlcs_info); + tal_free(htlcs_info); if (!is_replay) record_chain_fees_unilateral(&tx->txid, tx_blockheight, @@ -3859,8 +3900,6 @@ static void handle_unknown_commitment(const struct tx_parts *tx, u32 tx_blockheight, const struct pubkey *possible_remote_per_commitment_point, const struct basepoints basepoints[NUM_SIDES], - const struct htlc_stub *htlcs, - const bool *tell_if_missing, struct tracked_output **outs, bool is_replay) { @@ -3868,6 +3907,7 @@ static void handle_unknown_commitment(const struct tx_parts *tx, /* We have two possible local scripts, depending on options */ u8 *local_scripts[2]; struct amount_sat amt_salvaged = AMOUNT_SAT(0); + struct htlcs_info *htlcs_info; onchain_annotate_txin(&tx->txid, 0, TX_CHANNEL_UNILATERAL | TX_THEIRS); @@ -3961,12 +4001,12 @@ static void handle_unknown_commitment(const struct tx_parts *tx, if (to_us_output == -1) { status_broken("FUNDS LOST. Unknown commitment #%"PRIu64"!", commit_num); - init_reply("ERROR: FUNDS LOST. Unknown commitment!"); + htlcs_info = init_reply(tx, "ERROR: FUNDS LOST. Unknown commitment!"); } else { status_broken("ERROR: Unknown commitment #%"PRIu64 ", recovering our funds!", commit_num); - init_reply("ERROR: Unknown commitment, recovering our funds!"); + htlcs_info = init_reply(tx, "ERROR: Unknown commitment, recovering our funds!"); } /* update our accounting notions for this channel. @@ -3975,29 +4015,21 @@ static void handle_unknown_commitment(const struct tx_parts *tx, update_ledger_unknown(&tx->txid, tx_blockheight, amt_salvaged); /* Tell master to give up on HTLCs immediately. */ - for (size_t i = 0; i < tal_count(htlcs); i++) { + for (size_t i = 0; i < tal_count(htlcs_info->htlcs); i++) { u8 *msg; - if (!tell_if_missing[i]) + if (!htlcs_info->tell_if_missing[i]) continue; - msg = towire_onchaind_missing_htlc_output(NULL, &htlcs[i]); + msg = towire_onchaind_missing_htlc_output(NULL, + &htlcs_info->htlcs[i]); wire_sync_write(REQ_FD, take(msg)); } + tal_free(htlcs_info); wait_for_resolved(outs); } -static int cmp_htlc_cltv(const struct htlc_stub *a, - const struct htlc_stub *b, void *unused) -{ - if (a->cltv_expiry < b->cltv_expiry) - return -1; - else if (a->cltv_expiry > b->cltv_expiry) - return 1; - return 0; -} - int main(int argc, char *argv[]) { setup_locale(); @@ -4014,10 +4046,7 @@ int main(int argc, char *argv[]) struct bitcoin_txid our_broadcast_txid; struct bitcoin_signature *remote_htlc_sigs; struct amount_sat funding_sats; - u64 num_htlcs; u8 *scriptpubkey[NUM_SIDES]; - struct htlc_stub *htlcs; - bool *tell_if_missing, *tell_immediately; u32 locktime, tx_blockheight; struct pubkey *possible_remote_per_commitment_point; int mutual_outnum; @@ -4055,7 +4084,6 @@ int main(int argc, char *argv[]) &tx_blockheight, &reasonable_depth, &remote_htlc_sigs, - &num_htlcs, &min_possible_feerate, &max_possible_feerate, &possible_remote_per_commitment_point, @@ -4075,25 +4103,6 @@ int main(int argc, char *argv[]) /* We need to keep tx around, but there's only one: not really a leak */ tal_steal(ctx, notleak(tx)); - /* FIXME: Filter as we go, don't load them all into mem! */ - htlcs = tal_arr(tmpctx, struct htlc_stub, num_htlcs); - tell_if_missing = tal_arr(htlcs, bool, num_htlcs); - tell_immediately = tal_arr(htlcs, bool, num_htlcs); - if (!htlcs || !tell_if_missing || !tell_immediately) - status_failed(STATUS_FAIL_INTERNAL_ERROR, - "Can't allocate %"PRIu64" htlcs", num_htlcs); - - for (u64 i = 0; i < num_htlcs; i++) { - msg = wire_sync_read(tmpctx, REQ_FD); - if (!fromwire_onchaind_htlc(msg, &htlcs[i], - &tell_if_missing[i], - &tell_immediately[i])) - master_badmsg(WIRE_ONCHAIND_HTLC, msg); - } - - /* Sort by CLTV, so matches are in CLTV order (and easy to skip dups) */ - asort(htlcs, tal_count(htlcs), cmp_htlc_cltv, NULL); - outs = tal_arr(ctx, struct tracked_output *, 0); wally_tx_input_get_txid(tx->inputs[0], &funding.txid); funding.n = tx->inputs[0]->index; @@ -4145,8 +4154,6 @@ int main(int argc, char *argv[]) if (is_local_commitment(&tx->txid, &our_broadcast_txid)) handle_our_unilateral(tx, tx_blockheight, basepoints, - htlcs, - tell_if_missing, tell_immediately, opener, remote_htlc_sigs, outs, @@ -4164,8 +4171,6 @@ int main(int argc, char *argv[]) tx_blockheight, &revocation_preimage, basepoints, - htlcs, - tell_if_missing, tell_immediately, opener, outs, open_is_replay); @@ -4183,9 +4188,6 @@ int main(int argc, char *argv[]) handle_their_unilateral(tx, tx_blockheight, &old_remote_per_commit_point, basepoints, - htlcs, - tell_if_missing, - tell_immediately, opener, outs, open_is_replay); @@ -4194,9 +4196,6 @@ int main(int argc, char *argv[]) handle_their_unilateral(tx, tx_blockheight, &remote_per_commit_point, basepoints, - htlcs, - tell_if_missing, - tell_immediately, opener, outs, open_is_replay); @@ -4204,8 +4203,6 @@ int main(int argc, char *argv[]) handle_unknown_commitment(tx, tx_blockheight, possible_remote_per_commitment_point, basepoints, - htlcs, - tell_if_missing, outs, open_is_replay); } diff --git a/onchaind/onchaind_wire.csv b/onchaind/onchaind_wire.csv index ee24243af263..0193f4fbbe5b 100644 --- a/onchaind/onchaind_wire.csv +++ b/onchaind/onchaind_wire.csv @@ -40,7 +40,6 @@ msgdata,onchaind_init,tx_blockheight,u32, msgdata,onchaind_init,reasonable_depth,u32, msgdata,onchaind_init,num_htlc_sigs,u16, msgdata,onchaind_init,htlc_signature,bitcoin_signature,num_htlc_sigs -msgdata,onchaind_init,num_htlcs,u64, msgdata,onchaind_init,min_possible_feerate,u32, msgdata,onchaind_init,max_possible_feerate,u32, msgdata,onchaind_init,possible_remote_per_commit_point,?pubkey, @@ -53,16 +52,17 @@ msgdata,onchaind_init,is_replay,bool, # We need this for BIP125 rule 4 msgdata,onchaind_init,min_relay_feerate,u32, +# This says we're ready; give us htlcs and preimages. +msgtype,onchaind_init_reply,5101 +msgdata,onchaind_init_reply,commit_num,u64, + #include -# This is all the HTLCs: one per message -msgtype,onchaind_htlc,5002 -msgdata,onchaind_htlc,htlc,htlc_stub, +msgtype,onchaind_htlcs,5002 +msgdata,onchaind_htlcs,num_htlcs,u32, +msgdata,onchaind_htlcs,htlc,htlc_stub,num_htlcs # If it's not in the commitment tx, tell us (immediately or htlc_missing_depth) -msgdata,onchaind_htlc,tell_if_missing,bool, -msgdata,onchaind_htlc,tell_immediately,bool, - -# This says we're ready; give us preimages. -msgtype,onchaind_init_reply,5101 +msgdata,onchaind_htlcs,tell_if_missing,bool,num_htlcs +msgdata,onchaind_htlcs,tell_immediately,bool,num_htlcs # onchaind->master: Send out a tx. # If is_rbf is false then master should rebroadcast the tx. diff --git a/onchaind/test/run-grind_feerate-bug.c b/onchaind/test/run-grind_feerate-bug.c index 9d393069b530..17b360244997 100644 --- a/onchaind/test/run-grind_feerate-bug.c +++ b/onchaind/test/run-grind_feerate-bug.c @@ -44,11 +44,11 @@ bool fromwire_onchaind_depth(const void *p UNNEEDED, struct bitcoin_txid *txid U /* Generated stub for fromwire_onchaind_dev_memleak */ bool fromwire_onchaind_dev_memleak(const void *p UNNEEDED) { fprintf(stderr, "fromwire_onchaind_dev_memleak called!\n"); abort(); } -/* Generated stub for fromwire_onchaind_htlc */ -bool fromwire_onchaind_htlc(const void *p UNNEEDED, struct htlc_stub *htlc UNNEEDED, bool *tell_if_missing UNNEEDED, bool *tell_immediately UNNEEDED) -{ fprintf(stderr, "fromwire_onchaind_htlc called!\n"); abort(); } +/* Generated stub for fromwire_onchaind_htlcs */ +bool fromwire_onchaind_htlcs(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct htlc_stub **htlc UNNEEDED, bool **tell_if_missing UNNEEDED, bool **tell_immediately UNNEEDED) +{ fprintf(stderr, "fromwire_onchaind_htlcs called!\n"); abort(); } /* Generated stub for fromwire_onchaind_init */ -bool fromwire_onchaind_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct amount_msat *our_msat UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *delayed_to_us_feerate UNNEEDED, u32 *htlc_feerate UNNEEDED, u32 *penalty_feerate UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *opener UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct tx_parts **tx_parts UNNEEDED, u32 *locktime UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, u64 *num_htlcs UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED, struct pubkey *local_funding_pubkey UNNEEDED, struct pubkey *remote_funding_pubkey UNNEEDED, u64 *local_static_remotekey_start UNNEEDED, u64 *remote_static_remotekey_start UNNEEDED, bool *option_anchor_outputs UNNEEDED, bool *is_replay UNNEEDED, u32 *min_relay_feerate UNNEEDED) +bool fromwire_onchaind_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct amount_msat *our_msat UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *delayed_to_us_feerate UNNEEDED, u32 *htlc_feerate UNNEEDED, u32 *penalty_feerate UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *opener UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct tx_parts **tx_parts UNNEEDED, u32 *locktime UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED, struct pubkey *local_funding_pubkey UNNEEDED, struct pubkey *remote_funding_pubkey UNNEEDED, u64 *local_static_remotekey_start UNNEEDED, u64 *remote_static_remotekey_start UNNEEDED, bool *option_anchor_outputs UNNEEDED, bool *is_replay UNNEEDED, u32 *min_relay_feerate UNNEEDED) { fprintf(stderr, "fromwire_onchaind_init called!\n"); abort(); } /* Generated stub for fromwire_onchaind_known_preimage */ bool fromwire_onchaind_known_preimage(const void *p UNNEEDED, struct preimage *preimage UNNEEDED, bool *is_replay UNNEEDED) @@ -242,7 +242,7 @@ u8 *towire_onchaind_extracted_preimage(const tal_t *ctx UNNEEDED, const struct p u8 *towire_onchaind_htlc_timeout(const tal_t *ctx UNNEEDED, const struct htlc_stub *htlc UNNEEDED) { fprintf(stderr, "towire_onchaind_htlc_timeout called!\n"); abort(); } /* Generated stub for towire_onchaind_init_reply */ -u8 *towire_onchaind_init_reply(const tal_t *ctx UNNEEDED) +u8 *towire_onchaind_init_reply(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED) { fprintf(stderr, "towire_onchaind_init_reply called!\n"); abort(); } /* Generated stub for towire_onchaind_missing_htlc_output */ u8 *towire_onchaind_missing_htlc_output(const tal_t *ctx UNNEEDED, const struct htlc_stub *htlc UNNEEDED) diff --git a/onchaind/test/run-grind_feerate.c b/onchaind/test/run-grind_feerate.c index c89cca79ec02..5f5f8495ae7b 100644 --- a/onchaind/test/run-grind_feerate.c +++ b/onchaind/test/run-grind_feerate.c @@ -49,11 +49,11 @@ bool fromwire_onchaind_depth(const void *p UNNEEDED, struct bitcoin_txid *txid U /* Generated stub for fromwire_onchaind_dev_memleak */ bool fromwire_onchaind_dev_memleak(const void *p UNNEEDED) { fprintf(stderr, "fromwire_onchaind_dev_memleak called!\n"); abort(); } -/* Generated stub for fromwire_onchaind_htlc */ -bool fromwire_onchaind_htlc(const void *p UNNEEDED, struct htlc_stub *htlc UNNEEDED, bool *tell_if_missing UNNEEDED, bool *tell_immediately UNNEEDED) -{ fprintf(stderr, "fromwire_onchaind_htlc called!\n"); abort(); } +/* Generated stub for fromwire_onchaind_htlcs */ +bool fromwire_onchaind_htlcs(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct htlc_stub **htlc UNNEEDED, bool **tell_if_missing UNNEEDED, bool **tell_immediately UNNEEDED) +{ fprintf(stderr, "fromwire_onchaind_htlcs called!\n"); abort(); } /* Generated stub for fromwire_onchaind_init */ -bool fromwire_onchaind_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct amount_msat *our_msat UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *delayed_to_us_feerate UNNEEDED, u32 *htlc_feerate UNNEEDED, u32 *penalty_feerate UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *opener UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct tx_parts **tx_parts UNNEEDED, u32 *locktime UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, u64 *num_htlcs UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED, struct pubkey *local_funding_pubkey UNNEEDED, struct pubkey *remote_funding_pubkey UNNEEDED, u64 *local_static_remotekey_start UNNEEDED, u64 *remote_static_remotekey_start UNNEEDED, bool *option_anchor_outputs UNNEEDED, bool *is_replay UNNEEDED, u32 *min_relay_feerate UNNEEDED) +bool fromwire_onchaind_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct amount_msat *our_msat UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *delayed_to_us_feerate UNNEEDED, u32 *htlc_feerate UNNEEDED, u32 *penalty_feerate UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *opener UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct tx_parts **tx_parts UNNEEDED, u32 *locktime UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED, struct pubkey *local_funding_pubkey UNNEEDED, struct pubkey *remote_funding_pubkey UNNEEDED, u64 *local_static_remotekey_start UNNEEDED, u64 *remote_static_remotekey_start UNNEEDED, bool *option_anchor_outputs UNNEEDED, bool *is_replay UNNEEDED, u32 *min_relay_feerate UNNEEDED) { fprintf(stderr, "fromwire_onchaind_init called!\n"); abort(); } /* Generated stub for fromwire_onchaind_known_preimage */ bool fromwire_onchaind_known_preimage(const void *p UNNEEDED, struct preimage *preimage UNNEEDED, bool *is_replay UNNEEDED) @@ -271,7 +271,7 @@ u8 *towire_onchaind_extracted_preimage(const tal_t *ctx UNNEEDED, const struct p u8 *towire_onchaind_htlc_timeout(const tal_t *ctx UNNEEDED, const struct htlc_stub *htlc UNNEEDED) { fprintf(stderr, "towire_onchaind_htlc_timeout called!\n"); abort(); } /* Generated stub for towire_onchaind_init_reply */ -u8 *towire_onchaind_init_reply(const tal_t *ctx UNNEEDED) +u8 *towire_onchaind_init_reply(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED) { fprintf(stderr, "towire_onchaind_init_reply called!\n"); abort(); } /* Generated stub for towire_onchaind_missing_htlc_output */ u8 *towire_onchaind_missing_htlc_output(const tal_t *ctx UNNEEDED, const struct htlc_stub *htlc UNNEEDED) diff --git a/onchaind/test/run-onchainstress.c b/onchaind/test/run-onchainstress.c deleted file mode 100644 index e79e6d50a8a2..000000000000 --- a/onchaind/test/run-onchainstress.c +++ /dev/null @@ -1,223 +0,0 @@ -#include "../onchaind.c" -#include "../onchaind_wiregen.c" -#include "../onchaind_wire.c" -#include "../../hsmd/hsmd_wiregen.c" -#include -#include -#include -#include -#include -#include - -volatile bool logging_io; -struct backtrace_state *backtrace_state; - -/* AUTOGENERATED MOCKS START */ -/* Generated stub for dup_onionreply */ -struct onionreply *dup_onionreply(const tal_t *ctx UNNEEDED, - const struct onionreply *r TAKES UNNEEDED) -{ fprintf(stderr, "dup_onionreply called!\n"); abort(); } -/* Generated stub for fromwire_bip32_key_version */ -void fromwire_bip32_key_version(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, - struct bip32_key_version *version UNNEEDED) -{ fprintf(stderr, "fromwire_bip32_key_version called!\n"); abort(); } -/* Generated stub for fromwire_chain_coin_mvt */ -void fromwire_chain_coin_mvt(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct chain_coin_mvt *mvt UNNEEDED) -{ fprintf(stderr, "fromwire_chain_coin_mvt called!\n"); abort(); } -/* Generated stub for fromwire_ext_key */ -void fromwire_ext_key(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct ext_key *bip32 UNNEEDED) -{ fprintf(stderr, "fromwire_ext_key called!\n"); abort(); } -/* Generated stub for fromwire_node_id */ -void fromwire_node_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct node_id *id UNNEEDED) -{ fprintf(stderr, "fromwire_node_id called!\n"); abort(); } -/* Generated stub for fromwire_onionreply */ -struct onionreply *fromwire_onionreply(const tal_t *ctx UNNEEDED, - const u8 **cursor UNNEEDED, size_t *max UNNEEDED) -{ fprintf(stderr, "fromwire_onionreply called!\n"); abort(); } -/* Generated stub for fromwire_utxo */ -struct utxo *fromwire_utxo(const tal_t *ctx UNNEEDED, const u8 **ptr UNNEEDED, size_t *max UNNEEDED) -{ fprintf(stderr, "fromwire_utxo called!\n"); abort(); } -/* Generated stub for master_badmsg */ -void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg) -{ fprintf(stderr, "master_badmsg called!\n"); abort(); } -/* Generated stub for memleak_find_allocations */ -struct htable *memleak_find_allocations(const tal_t *ctx UNNEEDED, - const void *exclude1 UNNEEDED, - const void *exclude2 UNNEEDED) -{ fprintf(stderr, "memleak_find_allocations called!\n"); abort(); } -/* Generated stub for new_coin_penalty_sat */ -struct chain_coin_mvt *new_coin_penalty_sat(const tal_t *ctx UNNEEDED, - const char *account_name UNNEEDED, - const struct bitcoin_txid *txid UNNEEDED, - const struct bitcoin_outpoint *outpoint UNNEEDED, - u32 blockheight UNNEEDED, - struct amount_sat amount UNNEEDED) -{ fprintf(stderr, "new_coin_penalty_sat called!\n"); abort(); } -/* Generated stub for new_coin_withdrawal */ -struct chain_coin_mvt *new_coin_withdrawal(const tal_t *ctx UNNEEDED, - const char *account_name UNNEEDED, - const struct bitcoin_txid *tx_txid UNNEEDED, - const struct bitcoin_outpoint *outpoint UNNEEDED, - u32 blockheight UNNEEDED, - struct amount_msat amount UNNEEDED) -{ fprintf(stderr, "new_coin_withdrawal called!\n"); abort(); } -/* Generated stub for status_failed */ -void status_failed(enum status_failreason code UNNEEDED, - const char *fmt UNNEEDED, ...) -{ fprintf(stderr, "status_failed called!\n"); abort(); } -/* Generated stub for status_vfmt */ -void status_vfmt(enum log_level level UNNEEDED, - const struct node_id *peer UNNEEDED, - const char *fmt UNNEEDED, va_list ap UNNEEDED) -{ fprintf(stderr, "status_vfmt called!\n"); abort(); } -/* Generated stub for towire_bip32_key_version */ -void towire_bip32_key_version(u8 **cursor UNNEEDED, const struct bip32_key_version *version UNNEEDED) -{ fprintf(stderr, "towire_bip32_key_version called!\n"); abort(); } -/* Generated stub for towire_ext_key */ -void towire_ext_key(u8 **pptr UNNEEDED, const struct ext_key *bip32 UNNEEDED) -{ fprintf(stderr, "towire_ext_key called!\n"); abort(); } -/* Generated stub for towire_node_id */ -void towire_node_id(u8 **pptr UNNEEDED, const struct node_id *id UNNEEDED) -{ fprintf(stderr, "towire_node_id called!\n"); abort(); } -/* Generated stub for towire_onionreply */ -void towire_onionreply(u8 **cursor UNNEEDED, const struct onionreply *r UNNEEDED) -{ fprintf(stderr, "towire_onionreply called!\n"); abort(); } -/* Generated stub for towire_utxo */ -void towire_utxo(u8 **pptr UNNEEDED, const struct utxo *utxo UNNEEDED) -{ fprintf(stderr, "towire_utxo called!\n"); abort(); } -/* Generated stub for version */ -const char *version(void) -{ fprintf(stderr, "version called!\n"); abort(); } -/* AUTOGENERATED MOCKS END */ -#if DEVELOPER -/* Generated stub for dev_disconnect_init */ -void dev_disconnect_init(int fd UNNEEDED) -{ fprintf(stderr, "dev_disconnect_init called!\n"); abort(); } -/* Generated stub for dump_memleak */ -bool dump_memleak(struct htable *memtable UNNEEDED, - void (*print)(const char *fmt UNNEEDED, ...)) -{ fprintf(stderr, "dump_memleak called!\n"); abort(); } -/* Generated stub for memleak_init */ -void memleak_init(void) -{ fprintf(stderr, "memleak_init called!\n"); abort(); } -/* Generated stub for memleak_remove_region */ -void memleak_remove_region(struct htable *memtable UNNEEDED, - const void *p UNNEEDED, size_t bytelen UNNEEDED) -{ fprintf(stderr, "memleak_remove_region called!\n"); abort(); } -/* Generated stub for memleak_status_broken */ -void memleak_status_broken(const char *fmt UNNEEDED, ...) -{ fprintf(stderr, "memleak_status_broken called!\n"); abort(); } -#endif - -/* Noops */ -void status_setup_sync(int fd UNNEEDED) -{ -} -void status_fmt(enum log_level level, - const struct node_id *peer, - const char *fmt, ...) -{ -} -void *notleak_(const void *ptr UNNEEDED, bool plus_children UNNEEDED) -{ - return (void *)ptr; -} -void peer_billboard(bool perm UNNEEDED, const char *fmt UNNEEDED, ...) -{ -} -struct chain_coin_mvt *new_coin_chain_fees(const tal_t *ctx UNNEEDED, - const char *account_name UNNEEDED, - const struct bitcoin_txid *tx_txid UNNEEDED, - u32 blockheight UNNEEDED, - struct amount_msat amount UNNEEDED) -{ - return NULL; -} - -/* Generated stub for new_coin_chain_fees_sat */ -struct chain_coin_mvt *new_coin_chain_fees_sat(const tal_t *ctx UNNEEDED, - const char *account_name UNNEEDED, - const struct bitcoin_txid *tx_txid UNNEEDED, - u32 blockheight UNNEEDED, - struct amount_sat amount UNNEEDED) -{ - return NULL; -} -/* Generated stub for new_coin_journal_entry */ -struct chain_coin_mvt *new_coin_journal_entry(const tal_t *ctx UNNEEDED, - const char *account_name UNNEEDED, - const struct bitcoin_txid *txid UNNEEDED, - const struct bitcoin_outpoint *outpoint UNNEEDED, - u32 blockheight UNNEEDED, - struct amount_msat amount UNNEEDED, - bool is_credit UNNEEDED) -{ - return NULL; -} -struct chain_coin_mvt *new_coin_onchain_htlc_sat(const tal_t *ctx UNNEEDED, - const char *account_name UNNEEDED, - const struct bitcoin_txid *txid UNNEEDED, - const struct bitcoin_outpoint *outpoint UNNEEDED, - struct sha256 payment_hash UNNEEDED, - u32 blockheight UNNEEDED, - struct amount_sat amount UNNEEDED, - bool is_credit UNNEEDED) -{ - return NULL; -} -struct chain_coin_mvt *new_coin_withdrawal_sat(const tal_t *ctx UNNEEDED, - const char *account_name UNNEEDED, - const struct bitcoin_txid *tx_txid UNNEEDED, - const struct bitcoin_outpoint *outpoint UNNEEDED, - u32 blockheight UNNEEDED, - struct amount_sat amount UNNEEDED) -{ - return NULL; -} -void towire_chain_coin_mvt(u8 **pptr UNNEEDED, const struct chain_coin_mvt *mvt UNNEEDED) -{ -} - -bool wire_sync_write(int fd, const void *msg TAKES) -{ - if (taken(msg)) - tal_free(msg); - return true; -} - -u8 *wire_sync_read(const tal_t *ctx, int fd) -{ - char line[5000]; - u8 *ret; - static gzFile stream; - size_t hexlen; - - /* Don't run this under valgrind in CI: takes too long! */ - if (getenv("VALGRIND") && streq(getenv("VALGRIND"), "1")) - goto exit; - - if (!stream) { - stream = gzopen("onchaind/test/onchainstress-data.gz", "rb"); - if (!stream) - err(1, "opening onchaind/test/onchainstress-data.gz"); - } - - do { - if (!gzgets(stream, line, sizeof(line))) - goto exit; - } while (!strstarts(line, "read ")); - - /* Ignore prefix and \n at end */ - hexlen = strlen(line) - strlen("read ") - 1; - ret = tal_arr(ctx, u8, hex_data_size(hexlen)); - if (!hex_decode(line + strlen("read "), hexlen, ret, tal_bytelen(ret))) - errx(1, "Bad hex string '%s'", line); - return ret; - -exit: - daemon_shutdown(); - /* Free top-level ctx pointer! */ - while (tal_first(NULL)) - tal_free(tal_first(NULL)); - exit(0); -} From 4e3ca8861bdec3418807d7b636e1b75968a12f1c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Oct 2021 14:15:36 +1030 Subject: [PATCH 14/16] onchaind: queue any unexpected messages while waiting for htlcs. In particular, we could get depth notifications. Signed-off-by: Rusty Russell --- onchaind/onchaind.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/onchaind/onchaind.c b/onchaind/onchaind.c index eafe7b5d09f7..87bce4eb9a3b 100644 --- a/onchaind/onchaind.c +++ b/onchaind/onchaind.c @@ -66,6 +66,9 @@ static u32 reasonable_depth; /* The messages to send at that depth. */ static u8 **missing_htlc_msgs; +/* The messages which were sent to us before init_reply was processed. */ +static u8 **queued_msgs; + /* Our recorded channel balance at 'chain time' */ static struct amount_msat our_msat; @@ -2151,6 +2154,8 @@ static void memleak_remove_globals(struct htable *memtable, const tal_t *topctx) memleak_remove_pointer(memtable, topctx); memleak_remove_region(memtable, missing_htlc_msgs, tal_bytelen(missing_htlc_msgs)); + memleak_remove_region(memtable, + queued_msgs, tal_bytelen(queued_msgs)); } static bool handle_dev_memleak(struct tracked_output **outs, const u8 *msg) @@ -2193,13 +2198,19 @@ static void wait_for_resolved(struct tracked_output **outs) billboard_update(outs); while (num_not_irrevocably_resolved(outs) != 0) { - u8 *msg = wire_sync_read(outs, REQ_FD); + u8 *msg; struct bitcoin_txid txid; u32 input_num, depth, tx_blockheight; struct preimage preimage; bool is_replay; struct tx_parts *tx_parts; + if (tal_count(queued_msgs)) { + msg = tal_steal(outs, queued_msgs[0]); + tal_arr_remove(&queued_msgs, 0); + } else + msg = wire_sync_read(outs, REQ_FD); + status_debug("Got new message %s", onchaind_wire_name(fromwire_peektype(msg))); @@ -2253,13 +2264,19 @@ static struct htlcs_info *init_reply(const tal_t *ctx, const char *what) peer_billboard(true, what); /* Read in htlcs */ - /* FIXME: queue other messages! */ - msg = wire_sync_read(tmpctx, REQ_FD); - if (!fromwire_onchaind_htlcs(htlcs_info, msg, - &htlcs_info->htlcs, - &htlcs_info->tell_if_missing, - &htlcs_info->tell_immediately)) - master_badmsg(WIRE_ONCHAIND_HTLCS, msg); + for (;;) { + msg = wire_sync_read(queued_msgs, REQ_FD); + if (fromwire_onchaind_htlcs(htlcs_info, msg, + &htlcs_info->htlcs, + &htlcs_info->tell_if_missing, + &htlcs_info->tell_immediately)) { + tal_free(msg); + break; + } + + /* Process later */ + tal_arr_expand(&queued_msgs, msg); + } /* We want htlcs to be a valid tal parent, so make it a zero-length * array if NULL (fromwire makes it NULL if there are no entries) */ @@ -4057,6 +4074,7 @@ int main(int argc, char *argv[]) status_setup_sync(REQ_FD); missing_htlc_msgs = tal_arr(ctx, u8 *, 0); + queued_msgs = tal_arr(ctx, u8 *, 0); msg = wire_sync_read(tmpctx, REQ_FD); if (!fromwire_onchaind_init(tmpctx, msg, From 04b2dcc88a76b138b74b5c42dc8bcad2d565724c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Oct 2021 14:15:36 +1030 Subject: [PATCH 15/16] wallet: only hand onchaind the HTLCs it needs to know. This will make closing long-lived channels more efficient, and it's just nicer. Signed-off-by: Rusty Russell --- lightningd/onchain_control.c | 3 ++- wallet/wallet.c | 6 ++++-- wallet/wallet.h | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index d2ee1ab7d904..c325a6c9de17 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -130,7 +130,8 @@ static void handle_onchain_init_reply(struct channel *channel, const u8 *msg) /* Tell it about any relevant HTLCs */ /* FIXME: Filter by commitnum! */ - stubs = wallet_htlc_stubs(tmpctx, channel->peer->ld->wallet, channel); + stubs = wallet_htlc_stubs(tmpctx, channel->peer->ld->wallet, channel, + commit_num); tell = tal_arr(stubs, bool, tal_count(stubs)); tell_immediate = tal_arr(stubs, bool, tal_count(stubs)); diff --git a/wallet/wallet.c b/wallet/wallet.c index a28d99ec98bb..d483e1ee75c1 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -2836,7 +2836,7 @@ const struct invoice_details *wallet_invoice_details(const tal_t *ctx, } struct htlc_stub *wallet_htlc_stubs(const tal_t *ctx, struct wallet *wallet, - struct channel *chan) + struct channel *chan, u64 commit_num) { struct htlc_stub *stubs; struct sha256 payment_hash; @@ -2845,9 +2845,11 @@ struct htlc_stub *wallet_htlc_stubs(const tal_t *ctx, struct wallet *wallet, stmt = db_prepare_v2(wallet->db, SQL("SELECT channel_id, direction, cltv_expiry, " "channel_htlc_id, payment_hash " - "FROM channel_htlcs WHERE channel_id = ?;")); + "FROM channel_htlcs WHERE channel_id = ? AND min_commit_num <= ? AND ((max_commit_num IS NULL) OR max_commit_num >= ?);")); db_bind_u64(stmt, 0, chan->dbid); + db_bind_u64(stmt, 1, commit_num); + db_bind_u64(stmt, 2, commit_num); db_query_prepared(stmt); stubs = tal_arr(ctx, struct htlc_stub, 0); diff --git a/wallet/wallet.h b/wallet/wallet.h index 85de90b1f5e2..ad2bcbfc0643 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -1058,9 +1058,10 @@ const struct invoice_details *wallet_invoice_details(const tal_t *ctx, * @ctx: Allocation context for the return value * @wallet: Wallet to load from * @chan: Channel to fetch stubs for + * @commit_num: The commitment number of the commit tx. */ struct htlc_stub *wallet_htlc_stubs(const tal_t *ctx, struct wallet *wallet, - struct channel *chan); + struct channel *chan, u64 commit_num); /** * wallet_payment_setup - Remember this payment for later committing. From c9d1b7fc4c6d2ebcb6732a757732fe83dacd1e04 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Oct 2021 14:16:28 +1030 Subject: [PATCH 16/16] CI: suppress postgres vaccuuming. ``` [gw1] [ 98%] PASSED tests/test_wallet.py::test_hsmtool_dump_descriptors tests/test_wallet.py::test_fundchannel_listtransaction [gw0] [ 98%] PASSED tests/test_plugin.py::test_channel_opened_notification tests/test_wallet.py::test_hsmtool_generatehsm [gw0] [ 98%] PASSED tests/test_wallet.py::test_hsmtool_generatehsm tests/test_wallet.py::test_withdraw_nlocktime_fuzz [gw1] [ 98%] ERROR tests/test_wallet.py::test_fundchannel_listtransaction tests/test_wallet.py::test_fundchannel_listtransaction tests/test_wallet.py::test_withdraw_nlocktime_fuzz tests/test_wallet.py::test_fundchannel_listtransaction [gw0] [ 99%] ERROR tests/test_wallet.py::test_withdraw_nlocktime_fuzz tests/test_wallet.py::test_multiwithdraw_simple [gw1] [ 99%] ERROR tests/test_wallet.py::test_fundchannel_listtransaction tests/test_wallet.py::test_withdraw_nlocktime tests/test_wallet.py::test_multiwithdraw_simple tests/test_wallet.py::test_withdraw_nlocktime tests/test_wallet.py::test_multiwithdraw_simple tests/test_wallet.py::test_withdraw_nlocktime [gw0] [ 99%] ERROR tests/test_wallet.py::test_multiwithdraw_simple tests/test_wallet.py::test_repro_4258 [gw1] [ 99%] ERROR tests/test_wallet.py::test_withdraw_nlocktime ... 2021-10-12 06:36:09.203 UTC [224552] STATEMENT: SELECT version FROM version LIMIT 1 2021-10-12 06:36:09.566 UTC [224523] PANIC: could not write to file "pg_wal/xlogtemp.224523": No space left on device 2021-10-12 06:36:09.566 UTC [224523] STATEMENT: VACUUM FULL; Error vacuuming db: BEGIN command failed: PANIC: could not write to file "pg_wal/xlogtemp.224523": No space left on device server closed the connection unexpectedly This probably means the server terminated abnormally before or while processing the request. ``` --- .github/scripts/build.sh | 1 + wallet/db_postgres.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/.github/scripts/build.sh b/.github/scripts/build.sh index 861f30b83e62..f74f2f646a9e 100755 --- a/.github/scripts/build.sh +++ b/.github/scripts/build.sh @@ -19,6 +19,7 @@ export TEST_NETWORK=${NETWORK:-"regtest"} export TIMEOUT=900 export VALGRIND=${VALGRIND:-0} export FUZZING=${FUZZING:-0} +export LIGHTNINGD_POSTGRES_NO_VACUUM=1 pip3 install --user -U \ -r requirements.lock diff --git a/wallet/db_postgres.c b/wallet/db_postgres.c index 29920a358420..973097fe1fe9 100644 --- a/wallet/db_postgres.c +++ b/wallet/db_postgres.c @@ -254,6 +254,14 @@ static void db_postgres_teardown(struct db *db) static bool db_postgres_vacuum(struct db *db) { PGresult *res; + +#if DEVELOPER + /* This can use a lot of diskspacem breaking CI! */ + if (getenv("LIGHTNINGD_POSTGRES_NO_VACUUM") + && streq(getenv("LIGHTNINGD_POSTGRES_NO_VACUUM"), "1")) + return true; +#endif + res = PQexec(db->conn, "VACUUM FULL;"); if (PQresultStatus(res) != PGRES_COMMAND_OK) { db->error = tal_fmt(db, "BEGIN command failed: %s",