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/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/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/bitcoin/tx.c b/bitcoin/tx.c index d676b06dafad..81a5635c79b6 100644 --- a/bitcoin/tx.c +++ b/bitcoin/tx.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -195,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) { @@ -387,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) { @@ -394,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) { @@ -414,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) @@ -677,6 +697,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 +715,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, @@ -781,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/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; 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/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/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/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 17244bb028a2..e3a9899ba78a 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) { @@ -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..c325a6c9de17 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -70,14 +70,80 @@ 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, + commit_num); + 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); } /** @@ -185,18 +251,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 +447,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 +465,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); } @@ -494,7 +558,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: @@ -504,45 +568,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, @@ -566,7 +591,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; @@ -611,12 +635,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, @@ -636,7 +654,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 +667,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 +687,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, @@ -697,7 +715,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, @@ -710,18 +727,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/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/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/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 34cc8ce4ea4e..ca7f0acdef88 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) @@ -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.index = output; + w->out = *outpoint; w->channel = channel; w->cb = cb; @@ -266,7 +264,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..35d818e892c5 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); @@ -59,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 425a5da74ebe..87bce4eb9a3b 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; @@ -67,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; @@ -100,11 +102,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; @@ -198,7 +199,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)); @@ -216,8 +217,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)); @@ -267,10 +268,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; @@ -294,15 +294,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))); } @@ -338,7 +339,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, @@ -371,8 +372,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)); } @@ -393,8 +394,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))); } @@ -685,7 +686,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( @@ -776,8 +777,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; @@ -792,8 +792,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, @@ -807,7 +807,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. */ @@ -998,10 +998,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, @@ -1010,17 +1009,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; @@ -1041,14 +1038,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; } @@ -1489,22 +1486,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; @@ -1545,7 +1542,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; @@ -1562,14 +1560,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: * @@ -1577,14 +1575,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?", @@ -1642,6 +1640,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) { @@ -1649,6 +1648,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, @@ -1664,15 +1664,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: * @@ -1704,6 +1707,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; @@ -1712,19 +1716,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: @@ -1763,11 +1766,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, @@ -1786,11 +1789,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? */ @@ -1798,7 +1803,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) @@ -1808,6 +1813,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: @@ -1821,13 +1829,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; @@ -1847,10 +1857,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: @@ -1870,7 +1883,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; @@ -1970,7 +1983,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? */ @@ -1984,7 +1997,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); } @@ -1992,7 +2005,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); } @@ -2083,8 +2096,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], @@ -2142,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) @@ -2184,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))); @@ -2213,11 +2233,61 @@ 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 */ + 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) */ + 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, @@ -2227,7 +2297,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. */ @@ -2243,6 +2315,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; @@ -2252,8 +2325,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); @@ -2327,7 +2401,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, @@ -2515,11 +2589,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. */ @@ -2527,12 +2599,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); @@ -2580,9 +2652,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, @@ -2605,8 +2676,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); @@ -2635,9 +2706,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, @@ -2649,8 +2717,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: @@ -2706,7 +2775,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], @@ -2731,6 +2800,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); @@ -2741,8 +2814,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); @@ -2751,8 +2824,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); @@ -2770,8 +2843,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); @@ -2784,9 +2858,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); @@ -2797,9 +2871,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); @@ -2834,10 +2908,10 @@ 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, - max(to_self_delay[LOCAL], csv), + amt, + max_unsigned(to_self_delay[LOCAL], csv), script[LOCAL], local_wscript, is_replay); @@ -2869,8 +2943,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); @@ -2886,36 +2962,36 @@ 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); } - 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 [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, 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); } 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, @@ -2927,12 +3003,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 */ @@ -2942,13 +3019,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); } @@ -3003,14 +3080,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)); @@ -3022,7 +3099,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, @@ -3057,14 +3134,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, @@ -3081,10 +3158,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); @@ -3093,7 +3170,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, @@ -3113,9 +3190,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) @@ -3129,8 +3203,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); @@ -3228,7 +3304,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], @@ -3253,6 +3329,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); @@ -3260,8 +3341,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); @@ -3272,8 +3354,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; @@ -3288,8 +3371,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); @@ -3302,9 +3386,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); @@ -3315,9 +3399,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); @@ -3346,8 +3430,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, @@ -3375,8 +3460,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); @@ -3399,7 +3486,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: @@ -3407,23 +3494,23 @@ 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], + &htlcs_info->htlcs[which_htlc], htlc_scripts[which_htlc], NULL); 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], + &htlcs_info->htlcs[which_htlc], htlc_scripts[which_htlc], NULL); /* BOLT #5: @@ -3439,8 +3526,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); @@ -3458,9 +3545,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) @@ -3470,8 +3554,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. */ @@ -3548,7 +3633,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); @@ -3581,15 +3666,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); @@ -3598,8 +3689,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); @@ -3618,8 +3710,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); @@ -3631,9 +3724,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); @@ -3644,9 +3737,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); @@ -3677,8 +3770,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); @@ -3706,8 +3800,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); @@ -3726,30 +3822,30 @@ 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 * [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, NULL); which_htlc = resolve_our_htlc_theircommit(out, matches, - htlcs, + htlcs_info->htlcs, htlc_scripts, 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, @@ -3760,17 +3856,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, @@ -3812,7 +3909,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))); } @@ -3820,8 +3917,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) { @@ -3829,6 +3924,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); @@ -3867,10 +3963,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])) @@ -3890,9 +3990,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); @@ -3901,7 +4002,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, @@ -3917,12 +4018,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. @@ -3931,29 +4032,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(); @@ -3966,13 +4059,11 @@ 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; - u64 num_htlcs; + struct amount_sat funding_sats; 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; @@ -3983,12 +4074,13 @@ 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, &shachain, &chainparams, - &funding, + &funding_sats, &our_msat, &old_remote_per_commit_point, &remote_per_commit_point, @@ -4010,7 +4102,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, @@ -4030,32 +4121,13 @@ 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], &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", @@ -4065,7 +4137,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: * @@ -4100,8 +4172,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, @@ -4119,8 +4189,6 @@ int main(int argc, char *argv[]) tx_blockheight, &revocation_preimage, basepoints, - htlcs, - tell_if_missing, tell_immediately, opener, outs, open_is_replay); @@ -4138,9 +4206,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); @@ -4149,9 +4214,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); @@ -4159,8 +4221,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 694ac7498dd4..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. @@ -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..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) @@ -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) @@ -248,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) @@ -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..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) @@ -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) @@ -278,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 0044a3e9feb8..000000000000 --- a/onchaind/test/run-onchainstress.c +++ /dev/null @@ -1,229 +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_txid *out_txid UNNEEDED, - u32 vout 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) -{ 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_txid *out_txid UNNEEDED, - u32 vout 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_txid *out_txid UNNEEDED, - u32 vout 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_txid *out_txid UNNEEDED, - u32 vout 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); -} 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/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); 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-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 06e1e89bdc20..0eed31095a10 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 @@ -30,26 +32,26 @@ 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; 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); - 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); @@ -59,21 +61,29 @@ 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) 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, @@ -81,8 +91,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.. */ } 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 e08c62d8afeb..5c884cb16d4e 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -835,6 +835,23 @@ 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}, + /* 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. */ @@ -1187,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 */ @@ -1237,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) @@ -1255,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; } @@ -1443,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/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..973097fe1fe9 100644 --- a/wallet/db_postgres.c +++ b/wallet/db_postgres.c @@ -251,6 +251,28 @@ 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", + 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 +295,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); 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 33e788b01a6b..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, @@ -1717,6 +1710,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 +1737,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 +1759,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/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 0fc3f2878c1e..d483e1ee75c1 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); @@ -968,7 +963,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 +999,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) { @@ -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); @@ -1936,7 +1931,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 +1950,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)); } @@ -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++; } @@ -2314,8 +2312,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 +2338,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 +2370,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 +2402,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,12 +2414,15 @@ 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, 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)); @@ -2426,12 +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=?")); - /* FIXME: htlc_state_in_db */ - db_bind_int(stmt, 0, new_state); - db_bind_u64(stmt, 6, htlc_dbid); + db_bind_int(stmt, 0, htlc_state_in_db(new_state)); + db_bind_u64(stmt, 7, htlc_dbid); if (payment_key) db_bind_preimage(stmt, 1, payment_key); @@ -2452,7 +2458,23 @@ 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 (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, @@ -2814,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; @@ -2823,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); @@ -3560,7 +3584,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, @@ -3569,9 +3592,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); @@ -3625,11 +3649,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 = ? " @@ -3638,8 +3662,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)); @@ -3647,29 +3671,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," @@ -3680,8 +3703,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); @@ -3689,7 +3712,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) @@ -3718,8 +3741,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); @@ -3727,7 +3750,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); } } @@ -3771,8 +3794,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 @@ -3909,10 +3932,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 95e4814aa417..ad2bcbfc0643 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; @@ -254,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; @@ -326,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); /** @@ -381,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, @@ -419,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 @@ -642,6 +710,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. @@ -654,6 +723,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, @@ -988,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. @@ -1172,13 +1243,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); @@ -1206,8 +1278,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); @@ -1350,8 +1423,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); }