From 265f960cfebd802834a15aea5f59593ecfd28d06 Mon Sep 17 00:00:00 2001 From: niftynei Date: Tue, 22 Jun 2021 13:25:59 -0500 Subject: [PATCH] liquidity-ads: persist channel blockheight states to disk Adds new tables to database, backfills, basically copies the fee_rates state machine for channeld. --- channeld/Makefile | 1 + channeld/channeld.c | 200 +++++- channeld/channeld_wire.csv | 8 + channeld/channeld_wiregen.c | 36 +- channeld/channeld_wiregen.h | 14 +- channeld/full_channel.c | 54 +- channeld/full_channel.h | 9 + channeld/test/run-full_channel.c | 4 + closingd/closingd_wiregen.c | 2 +- closingd/closingd_wiregen.h | 2 +- common/blockheight_states.c | 164 +++++ common/blockheight_states.h | 79 +++ common/initial_channel.c | 16 +- common/initial_channel.h | 8 +- common/peer_status_wiregen.c | 2 +- common/peer_status_wiregen.h | 2 +- common/status_wiregen.c | 2 +- common/status_wiregen.h | 2 +- common/type_to_string.h | 1 + connectd/connectd_gossipd_wiregen.c | 2 +- connectd/connectd_gossipd_wiregen.h | 2 +- connectd/connectd_wiregen.c | 2 +- connectd/connectd_wiregen.h | 2 +- devtools/Makefile | 1 + devtools/mkcommit.c | 4 + gossipd/gossip_store_wiregen.c | 2 +- gossipd/gossip_store_wiregen.h | 2 +- gossipd/gossipd_peerd_wiregen.c | 2 +- gossipd/gossipd_peerd_wiregen.h | 2 +- gossipd/gossipd_wiregen.c | 2 +- gossipd/gossipd_wiregen.h | 2 +- hsmd/hsmd_wiregen.c | 2 +- hsmd/hsmd_wiregen.h | 2 +- lightningd/Makefile | 1 + lightningd/channel.c | 17 +- lightningd/channel.h | 8 +- lightningd/channel_control.c | 45 +- lightningd/dual_open_control.c | 31 +- lightningd/opening_control.c | 4 + lightningd/peer_control.c | 5 + lightningd/test/run-invoice-select-inchan.c | 5 + onchaind/onchaind_wiregen.c | 2 +- onchaind/onchaind_wiregen.h | 2 +- openingd/Makefile | 1 + openingd/dualopend.c | 37 +- openingd/dualopend_wire.csv | 2 + openingd/dualopend_wiregen.c | 14 +- openingd/dualopend_wiregen.h | 10 +- openingd/openingd.c | 4 +- openingd/openingd_wiregen.c | 2 +- openingd/openingd_wiregen.h | 2 +- tests/fuzz/fuzz-initial_channel.c | 24 +- tools/generate-wire.py | 1 + wallet/db.c | 39 ++ wallet/db_postgres_sqlgen.c | 56 +- wallet/db_sqlite3_sqlgen.c | 56 +- wallet/statements_gettextgen.po | 652 ++++++++++---------- wallet/test/Makefile | 1 + wallet/test/run-wallet.c | 55 +- wallet/wallet.c | 120 +++- wire/bolt12_wiregen.c | 2 +- wire/bolt12_wiregen.h | 2 +- wire/common_wiregen.c | 2 +- wire/common_wiregen.h | 2 +- wire/onion_printgen.c | 2 +- wire/onion_printgen.h | 2 +- wire/onion_wiregen.c | 2 +- wire/onion_wiregen.h | 2 +- wire/peer_printgen.c | 2 +- wire/peer_printgen.h | 2 +- wire/peer_wiregen.c | 2 +- wire/peer_wiregen.h | 2 +- 72 files changed, 1414 insertions(+), 441 deletions(-) create mode 100644 common/blockheight_states.c create mode 100644 common/blockheight_states.h diff --git a/channeld/Makefile b/channeld/Makefile index c3b9b1611..8fb4cc12f 100644 --- a/channeld/Makefile +++ b/channeld/Makefile @@ -35,6 +35,7 @@ CHANNELD_COMMON_OBJS := \ common/billboard.o \ common/bip32.o \ common/blinding.o \ + common/blockheight_states.o \ common/channel_config.o \ common/channel_id.o \ common/crypto_state.o \ diff --git a/channeld/channeld.c b/channeld/channeld.c index 5bee06853..6e8cef587 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -134,6 +134,9 @@ struct peer { /* The feerate we want. */ u32 desired_feerate; + /* Current blockheight */ + u32 our_blockheight; + /* Announcement related information */ struct node_id node_ids[NUM_SIDES]; struct short_channel_id short_channel_ids[NUM_SIDES]; @@ -837,6 +840,75 @@ static void handle_peer_feechange(struct peer *peer, const u8 *msg) status_debug("peer updated fee to %u", feerate); } +static void handle_peer_blockheight_change(struct peer *peer, const u8 *msg) +{ + struct channel_id channel_id; + u32 blockheight, current; + + if (!fromwire_update_blockheight(msg, &channel_id, &blockheight)) + peer_failed_warn(peer->pps, &peer->channel_id, + "Bad update_blockheight %s", + tal_hex(msg, msg)); + + /* BOLT- #2: + * A receiving node: + * ... + * - if the sender is not the initiator: + * - MUST fail the channel. + */ + if (peer->channel->opener != REMOTE) + peer_failed_warn(peer->pps, &peer->channel_id, + "update_blockheight from non-opener?"); + + current = get_blockheight(peer->channel->blockheight_states, + peer->channel->opener, LOCAL); + + status_debug("update_blockheight %u. last update height %u," + " our current height %u", + blockheight, current, peer->our_blockheight); + + /* BOLT- #2: + * A receiving node: + * - if the `update_blockheight` is less than the last + * received `blockheight`: + * - SHOULD fail the channel. + * ... + * - if `blockheight` is more than 1008 blocks behind + * the current blockheight: + * - SHOULD fail the channel + */ + /* Overflow check */ + if (blockheight + 1008 < blockheight) + peer_failed_warn(peer->pps, &peer->channel_id, + "blockheight + 1008 overflow (%u)", + blockheight); + + /* If they're behind the last one they sent, we just warn and + * reconnect, as they might be catching up */ + /* FIXME: track for how long they send backwards blockheight? */ + if (blockheight < current) + peer_failed_warn(peer->pps, &peer->channel_id, + "update_blockheight %u older than previous %u", + blockheight, current); + + /* BOLT- #2: + * A receiving node: + * ... + * - if `blockheight` is more than 1008 blocks behind + * the current blockheight: + * - SHOULD fail the channel + */ + assert(blockheight < blockheight + 1008); + if (blockheight + 1008 < peer->our_blockheight) + peer_failed_err(peer->pps, &peer->channel_id, + "update_blockheight %u outside" + " permissible range", blockheight); + + channel_update_blockheight(peer->channel, blockheight); + + status_debug("peer updated blockheight to %u", blockheight); +} + static struct changed_htlc *changed_htlc_arr(const tal_t *ctx, const struct htlc **changed_htlcs) { @@ -1140,6 +1212,41 @@ static bool want_fee_update(const struct peer *peer, u32 *target) return val != current; } +/* Do we want to update blockheight? */ +static bool want_blockheight_update(const struct peer *peer, u32 *height) +{ + u32 last; + + if (peer->channel->opener != LOCAL) + return false; + + if (peer->channel->lease_expiry == 0) + return false; + +#if EXPERIMENTAL_FEATURES + /* No fee update while quiescing! */ + if (peer->stfu) + return false; +#endif + /* What's the current blockheight */ + last = get_blockheight(peer->channel->blockheight_states, + peer->channel->opener, LOCAL); + + if (peer->our_blockheight < last) { + status_broken("current blockheight %u less than last %u", + peer->our_blockheight, last); + return false; + } + + if (peer->our_blockheight == last) + return false; + + if (height) + *height = peer->our_blockheight; + + return true; +} + static void send_commit(struct peer *peer) { u8 *msg; @@ -1150,6 +1257,7 @@ static void send_commit(struct peer *peer) const struct htlc **htlc_map; struct wally_tx_output *direct_outputs[NUM_SIDES]; struct penalty_base *pbase; + u32 our_blockheight; u32 feerate_target; #if DEVELOPER @@ -1218,6 +1326,22 @@ static void send_commit(struct peer *peer) } } + if (want_blockheight_update(peer, &our_blockheight)) { + if (blockheight_changes_done(peer->channel->blockheight_states, + false)) { + u8 *msg; + + channel_update_blockheight(peer->channel, + our_blockheight); + + msg = towire_update_blockheight(NULL, + &peer->channel_id, + our_blockheight); + + sync_crypto_write(peer->pps, take(msg)); + } + } + /* BOLT #2: * * A sending node: @@ -1226,9 +1350,13 @@ static void send_commit(struct peer *peer) */ changed_htlcs = tal_arr(tmpctx, const struct htlc *, 0); if (!channel_sending_commit(peer->channel, &changed_htlcs)) { - status_debug("Can't send commit: nothing to send, feechange %s (%s)", + status_debug("Can't send commit: nothing to send," + " feechange %s (%s)" + " blockheight %s (%s)", want_fee_update(peer, NULL) ? "wanted": "not wanted", - type_to_string(tmpctx, struct fee_states, peer->channel->fee_states)); + type_to_string(tmpctx, struct fee_states, peer->channel->fee_states), + want_blockheight_update(peer, NULL) ? "wanted" : "not wanted", + type_to_string(tmpctx, struct height_states, peer->channel->blockheight_states)); /* Covers the case where we've just been told to shutdown. */ maybe_send_shutdown(peer); @@ -2099,8 +2227,8 @@ static void peer_in(struct peer *peer, const u8 *msg) handle_peer_feechange(peer, msg); return; case WIRE_UPDATE_BLOCKHEIGHT: - /* FIXME: do this! */ - break; + handle_peer_blockheight_change(peer, msg); + return; case WIRE_REVOKE_AND_ACK: handle_peer_revoke_and_ack(peer, msg); return; @@ -3172,6 +3300,49 @@ static void handle_feerates(struct peer *peer, const u8 *inmsg) } } +static void handle_blockheight(struct peer *peer, const u8 *inmsg) +{ + u32 blockheight; + + if (!fromwire_channeld_blockheight(inmsg, &blockheight)) + master_badmsg(WIRE_CHANNELD_BLOCKHEIGHT, inmsg); + + /* Save it, so we know */ + peer->our_blockheight = blockheight; + if (peer->channel->opener == LOCAL) + start_commit_timer(peer); + else { + u32 peer_height = get_blockheight(peer->channel->blockheight_states, + peer->channel->opener, + REMOTE); + /* BOLT- #2: + * The node _not responsible_ for initiating the channel: + * ... + * - if last received `blockheight` is > 1008 behind + * currently known blockheight: + * - SHOULD fail he channel + */ + assert(peer_height + 1008 > peer_height); + if (peer_height + 1008 < blockheight) + peer_failed_err(peer->pps, &peer->channel_id, + "Peer is too far behind, terminating" + " leased channel. Our current" + " %u, theirs %u", + blockheight, peer_height); + /* We're behind them... what do. It's possible they're lying, + * but if we're in a lease this is actually in our favor so + * we log it but otherwise continue on unchanged */ + if (peer_height > blockheight + && peer_height > blockheight + 100) + status_unusual("Peer reporting we've fallen %u" + " blocks behind. Our height %u," + " their height %u", + peer_height - blockheight, + blockheight, peer_height); + + } +} + static void handle_specific_feerates(struct peer *peer, const u8 *inmsg) { u32 base_old = peer->fee_base; @@ -3350,6 +3521,11 @@ static void req_in(struct peer *peer, const u8 *msg) return; handle_feerates(peer, msg); return; + case WIRE_CHANNELD_BLOCKHEIGHT: + if (handle_master_request_later(peer, msg)) + return; + handle_blockheight(peer, msg); + return; case WIRE_CHANNELD_FULFILL_HTLC: if (handle_master_request_later(peer, msg)) return; @@ -3438,7 +3614,8 @@ static void init_channel(struct peer *peer) u8 *fwd_msg; const u8 *msg; struct fee_states *fee_states; - u32 minimum_depth; + struct height_states *blockheight_states; + u32 minimum_depth, lease_expiry; struct secret last_remote_per_commit_secret; secp256k1_ecdsa_signature *remote_ann_node_sig; secp256k1_ecdsa_signature *remote_ann_bitcoin_sig; @@ -3459,6 +3636,9 @@ static void init_channel(struct peer *peer) &funding_txid, &funding_txout, &funding, &minimum_depth, + &peer->our_blockheight, + &blockheight_states, + &lease_expiry, &conf[LOCAL], &conf[REMOTE], &fee_states, &peer->feerate_min, @@ -3529,7 +3709,8 @@ static void init_channel(struct peer *peer) " next_idx_local = %"PRIu64 " next_idx_remote = %"PRIu64 " revocations_received = %"PRIu64 - " feerates %s range %u-%u", + " feerates %s range %u-%u" + " blockheights %s, our current %u", side_to_str(opener), type_to_string(tmpctx, struct pubkey, &peer->remote_per_commit), @@ -3538,7 +3719,9 @@ static void init_channel(struct peer *peer) peer->next_index[LOCAL], peer->next_index[REMOTE], peer->revocations_received, type_to_string(tmpctx, struct fee_states, fee_states), - peer->feerate_min, peer->feerate_max); + peer->feerate_min, peer->feerate_max, + type_to_string(tmpctx, struct height_states, blockheight_states), + peer->our_blockheight); status_debug("option_static_remotekey = %u", option_static_remotekey); @@ -3568,7 +3751,8 @@ static void init_channel(struct peer *peer) &funding_txid, funding_txout, minimum_depth, - 0, /* FIXME: channel lease_expiry */ + take(blockheight_states), + lease_expiry, funding, local_msat, take(fee_states), diff --git a/channeld/channeld_wire.csv b/channeld/channeld_wire.csv index 7fd521e21..66bf7d957 100644 --- a/channeld/channeld_wire.csv +++ b/channeld/channeld_wire.csv @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -17,6 +18,9 @@ msgdata,channeld_init,funding_txid,bitcoin_txid, msgdata,channeld_init,funding_txout,u16, msgdata,channeld_init,funding_satoshi,amount_sat, msgdata,channeld_init,minimum_depth,u32, +msgdata,channeld_init,our_blockheight,u32, +msgdata,channeld_init,blockheight_states,height_states, +msgdata,channeld_init,lease_expiry,u32, msgdata,channeld_init,our_config,channel_config, msgdata,channeld_init,their_config,channel_config, msgdata,channeld_init,fee_states,fee_states, @@ -227,3 +231,7 @@ msgtype,channeld_dev_quiesce_reply,1109 # Tell master we're upgrading the commitment tx. msgtype,channeld_upgraded,1011 msgdata,channeld_upgraded,option_static_remotekey,bool, + +# Tell peer about our latest and greatest blockheight. +msgtype,channeld_blockheight,1012 +msgdata,channeld_blockheight,blockheight,u32, diff --git a/channeld/channeld_wiregen.c b/channeld/channeld_wiregen.c index be5e88e33..53082063e 100644 --- a/channeld/channeld_wiregen.c +++ b/channeld/channeld_wiregen.c @@ -49,6 +49,7 @@ const char *channeld_wire_name(int e) case WIRE_CHANNELD_DEV_QUIESCE: return "WIRE_CHANNELD_DEV_QUIESCE"; case WIRE_CHANNELD_DEV_QUIESCE_REPLY: return "WIRE_CHANNELD_DEV_QUIESCE_REPLY"; case WIRE_CHANNELD_UPGRADED: return "WIRE_CHANNELD_UPGRADED"; + case WIRE_CHANNELD_BLOCKHEIGHT: return "WIRE_CHANNELD_BLOCKHEIGHT"; } snprintf(invalidbuf, sizeof(invalidbuf), "INVALID %i", e); @@ -87,6 +88,7 @@ bool channeld_wire_is_defined(u16 type) case WIRE_CHANNELD_DEV_QUIESCE:; case WIRE_CHANNELD_DEV_QUIESCE_REPLY:; case WIRE_CHANNELD_UPGRADED:; + case WIRE_CHANNELD_BLOCKHEIGHT:; return true; } return false; @@ -98,7 +100,7 @@ bool channeld_wire_is_defined(u16 type) /* WIRE: CHANNELD_INIT */ /* Begin! (passes gossipd-client fd) */ -u8 *towire_channeld_init(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_features, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, u32 minimum_depth, const struct channel_config *our_config, const struct channel_config *their_config, const struct fee_states *fee_states, u32 feerate_min, u32 feerate_max, u32 feerate_penalty, const struct bitcoin_signature *first_commit_sig, const struct per_peer_state *per_peer_state, const struct pubkey *remote_fundingkey, const struct basepoints *remote_basepoints, const struct pubkey *remote_per_commit, const struct pubkey *old_remote_per_commit, enum side opener, u32 fee_base, u32 fee_proportional, struct amount_msat local_msatoshi, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct node_id *local_node_id, const struct node_id *remote_node_id, u32 commit_msec, u16 cltv_delta, bool last_was_revoke, const struct changed_htlc *last_sent_commit, u64 next_index_local, u64 next_index_remote, u64 revocations_received, u64 next_htlc_id, const struct existing_htlc **htlcs, bool local_funding_locked, bool remote_funding_locked, const struct short_channel_id *funding_short_id, bool reestablish, bool send_shutdown, bool remote_shutdown_received, const u8 *final_scriptpubkey, u8 flags, const u8 *init_peer_pkt, bool reached_announce_depth, const struct secret *last_remote_secret, const u8 *their_features, const u8 *upfront_shutdown_script, const secp256k1_ecdsa_signature *remote_ann_node_sig, const secp256k1_ecdsa_signature *remote_ann_bitcoin_sig, bool option_static_remotekey, bool option_anchor_outputs, bool dev_fast_gossip, bool dev_fail_process_onionpacket, const struct penalty_base *pbases, const u8 *reestablish_only) +u8 *towire_channeld_init(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_features, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, u32 minimum_depth, u32 our_blockheight, const struct height_states *blockheight_states, u32 lease_expiry, const struct channel_config *our_config, const struct channel_config *their_config, const struct fee_states *fee_states, u32 feerate_min, u32 feerate_max, u32 feerate_penalty, const struct bitcoin_signature *first_commit_sig, const struct per_peer_state *per_peer_state, const struct pubkey *remote_fundingkey, const struct basepoints *remote_basepoints, const struct pubkey *remote_per_commit, const struct pubkey *old_remote_per_commit, enum side opener, u32 fee_base, u32 fee_proportional, struct amount_msat local_msatoshi, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct node_id *local_node_id, const struct node_id *remote_node_id, u32 commit_msec, u16 cltv_delta, bool last_was_revoke, const struct changed_htlc *last_sent_commit, u64 next_index_local, u64 next_index_remote, u64 revocations_received, u64 next_htlc_id, const struct existing_htlc **htlcs, bool local_funding_locked, bool remote_funding_locked, const struct short_channel_id *funding_short_id, bool reestablish, bool send_shutdown, bool remote_shutdown_received, const u8 *final_scriptpubkey, u8 flags, const u8 *init_peer_pkt, bool reached_announce_depth, const struct secret *last_remote_secret, const u8 *their_features, const u8 *upfront_shutdown_script, const secp256k1_ecdsa_signature *remote_ann_node_sig, const secp256k1_ecdsa_signature *remote_ann_bitcoin_sig, bool option_static_remotekey, bool option_anchor_outputs, bool dev_fast_gossip, bool dev_fail_process_onionpacket, const struct penalty_base *pbases, const u8 *reestablish_only) { u16 num_last_sent_commit = tal_count(last_sent_commit); u16 num_existing_htlcs = tal_count(htlcs); @@ -118,6 +120,9 @@ u8 *towire_channeld_init(const tal_t *ctx, const struct chainparams *chainparams towire_u16(&p, funding_txout); towire_amount_sat(&p, funding_satoshi); towire_u32(&p, minimum_depth); + towire_u32(&p, our_blockheight); + towire_height_states(&p, blockheight_states); + towire_u32(&p, lease_expiry); towire_channel_config(&p, our_config); towire_channel_config(&p, their_config); towire_fee_states(&p, fee_states); @@ -192,7 +197,7 @@ u8 *towire_channeld_init(const tal_t *ctx, const struct chainparams *chainparams return memcheck(p, tal_count(p)); } -bool fromwire_channeld_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_features, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, u32 *minimum_depth, struct channel_config *our_config, struct channel_config *their_config, struct fee_states **fee_states, u32 *feerate_min, u32 *feerate_max, u32 *feerate_penalty, struct bitcoin_signature *first_commit_sig, struct per_peer_state **per_peer_state, struct pubkey *remote_fundingkey, struct basepoints *remote_basepoints, struct pubkey *remote_per_commit, struct pubkey *old_remote_per_commit, enum side *opener, u32 *fee_base, u32 *fee_proportional, struct amount_msat *local_msatoshi, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct node_id *local_node_id, struct node_id *remote_node_id, u32 *commit_msec, u16 *cltv_delta, bool *last_was_revoke, struct changed_htlc **last_sent_commit, u64 *next_index_local, u64 *next_index_remote, u64 *revocations_received, u64 *next_htlc_id, struct existing_htlc ***htlcs, bool *local_funding_locked, bool *remote_funding_locked, struct short_channel_id *funding_short_id, bool *reestablish, bool *send_shutdown, bool *remote_shutdown_received, u8 **final_scriptpubkey, u8 *flags, u8 **init_peer_pkt, bool *reached_announce_depth, struct secret *last_remote_secret, u8 **their_features, u8 **upfront_shutdown_script, secp256k1_ecdsa_signature **remote_ann_node_sig, secp256k1_ecdsa_signature **remote_ann_bitcoin_sig, bool *option_static_remotekey, bool *option_anchor_outputs, bool *dev_fast_gossip, bool *dev_fail_process_onionpacket, struct penalty_base **pbases, u8 **reestablish_only) +bool fromwire_channeld_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_features, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, u32 *minimum_depth, u32 *our_blockheight, struct height_states **blockheight_states, u32 *lease_expiry, struct channel_config *our_config, struct channel_config *their_config, struct fee_states **fee_states, u32 *feerate_min, u32 *feerate_max, u32 *feerate_penalty, struct bitcoin_signature *first_commit_sig, struct per_peer_state **per_peer_state, struct pubkey *remote_fundingkey, struct basepoints *remote_basepoints, struct pubkey *remote_per_commit, struct pubkey *old_remote_per_commit, enum side *opener, u32 *fee_base, u32 *fee_proportional, struct amount_msat *local_msatoshi, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct node_id *local_node_id, struct node_id *remote_node_id, u32 *commit_msec, u16 *cltv_delta, bool *last_was_revoke, struct changed_htlc **last_sent_commit, u64 *next_index_local, u64 *next_index_remote, u64 *revocations_received, u64 *next_htlc_id, struct existing_htlc ***htlcs, bool *local_funding_locked, bool *remote_funding_locked, struct short_channel_id *funding_short_id, bool *reestablish, bool *send_shutdown, bool *remote_shutdown_received, u8 **final_scriptpubkey, u8 *flags, u8 **init_peer_pkt, bool *reached_announce_depth, struct secret *last_remote_secret, u8 **their_features, u8 **upfront_shutdown_script, secp256k1_ecdsa_signature **remote_ann_node_sig, secp256k1_ecdsa_signature **remote_ann_bitcoin_sig, bool *option_static_remotekey, bool *option_anchor_outputs, bool *dev_fast_gossip, bool *dev_fail_process_onionpacket, struct penalty_base **pbases, u8 **reestablish_only) { u16 num_last_sent_commit; u16 num_existing_htlcs; @@ -215,6 +220,9 @@ bool fromwire_channeld_init(const tal_t *ctx, const void *p, const struct chainp *funding_txout = fromwire_u16(&cursor, &plen); *funding_satoshi = fromwire_amount_sat(&cursor, &plen); *minimum_depth = fromwire_u32(&cursor, &plen); + *our_blockheight = fromwire_u32(&cursor, &plen); + *blockheight_states = fromwire_height_states(ctx, &cursor, &plen); + *lease_expiry = fromwire_u32(&cursor, &plen); fromwire_channel_config(&cursor, &plen, our_config); fromwire_channel_config(&cursor, &plen, their_config); *fee_states = fromwire_fee_states(ctx, &cursor, &plen); @@ -1145,4 +1153,26 @@ bool fromwire_channeld_upgraded(const void *p, bool *option_static_remotekey) *option_static_remotekey = fromwire_bool(&cursor, &plen); return cursor != NULL; } -// SHA256STAMP:7fe345eb02876c231759ec37daba697e85ac3a43137e4b7cb67d136587e2bda5 + +/* WIRE: CHANNELD_BLOCKHEIGHT */ +/* Tell peer about our latest and greatest blockheight. */ +u8 *towire_channeld_blockheight(const tal_t *ctx, u32 blockheight) +{ + u8 *p = tal_arr(ctx, u8, 0); + + towire_u16(&p, WIRE_CHANNELD_BLOCKHEIGHT); + towire_u32(&p, blockheight); + + return memcheck(p, tal_count(p)); +} +bool fromwire_channeld_blockheight(const void *p, u32 *blockheight) +{ + const u8 *cursor = p; + size_t plen = tal_count(p); + + if (fromwire_u16(&cursor, &plen) != WIRE_CHANNELD_BLOCKHEIGHT) + return false; + *blockheight = fromwire_u32(&cursor, &plen); + return cursor != NULL; +} +// SHA256STAMP:40a8d4ea75d57eeddfb5cc648a9ca3e3914dfe500a6054b6a6942f4023a17d82 diff --git a/channeld/channeld_wiregen.h b/channeld/channeld_wiregen.h index 6854874b8..f53e5e9a4 100644 --- a/channeld/channeld_wiregen.h +++ b/channeld/channeld_wiregen.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -75,6 +76,8 @@ enum channeld_wire { WIRE_CHANNELD_DEV_QUIESCE_REPLY = 1109, /* Tell master we're upgrading the commitment tx. */ WIRE_CHANNELD_UPGRADED = 1011, + /* Tell peer about our latest and greatest blockheight. */ + WIRE_CHANNELD_BLOCKHEIGHT = 1012, }; const char *channeld_wire_name(int e); @@ -91,8 +94,8 @@ bool channeld_wire_is_defined(u16 type); /* WIRE: CHANNELD_INIT */ /* Begin! (passes gossipd-client fd) */ -u8 *towire_channeld_init(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_features, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, u32 minimum_depth, const struct channel_config *our_config, const struct channel_config *their_config, const struct fee_states *fee_states, u32 feerate_min, u32 feerate_max, u32 feerate_penalty, const struct bitcoin_signature *first_commit_sig, const struct per_peer_state *per_peer_state, const struct pubkey *remote_fundingkey, const struct basepoints *remote_basepoints, const struct pubkey *remote_per_commit, const struct pubkey *old_remote_per_commit, enum side opener, u32 fee_base, u32 fee_proportional, struct amount_msat local_msatoshi, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct node_id *local_node_id, const struct node_id *remote_node_id, u32 commit_msec, u16 cltv_delta, bool last_was_revoke, const struct changed_htlc *last_sent_commit, u64 next_index_local, u64 next_index_remote, u64 revocations_received, u64 next_htlc_id, const struct existing_htlc **htlcs, bool local_funding_locked, bool remote_funding_locked, const struct short_channel_id *funding_short_id, bool reestablish, bool send_shutdown, bool remote_shutdown_received, const u8 *final_scriptpubkey, u8 flags, const u8 *init_peer_pkt, bool reached_announce_depth, const struct secret *last_remote_secret, const u8 *their_features, const u8 *upfront_shutdown_script, const secp256k1_ecdsa_signature *remote_ann_node_sig, const secp256k1_ecdsa_signature *remote_ann_bitcoin_sig, bool option_static_remotekey, bool option_anchor_outputs, bool dev_fast_gossip, bool dev_fail_process_onionpacket, const struct penalty_base *pbases, const u8 *reestablish_only); -bool fromwire_channeld_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_features, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, u32 *minimum_depth, struct channel_config *our_config, struct channel_config *their_config, struct fee_states **fee_states, u32 *feerate_min, u32 *feerate_max, u32 *feerate_penalty, struct bitcoin_signature *first_commit_sig, struct per_peer_state **per_peer_state, struct pubkey *remote_fundingkey, struct basepoints *remote_basepoints, struct pubkey *remote_per_commit, struct pubkey *old_remote_per_commit, enum side *opener, u32 *fee_base, u32 *fee_proportional, struct amount_msat *local_msatoshi, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct node_id *local_node_id, struct node_id *remote_node_id, u32 *commit_msec, u16 *cltv_delta, bool *last_was_revoke, struct changed_htlc **last_sent_commit, u64 *next_index_local, u64 *next_index_remote, u64 *revocations_received, u64 *next_htlc_id, struct existing_htlc ***htlcs, bool *local_funding_locked, bool *remote_funding_locked, struct short_channel_id *funding_short_id, bool *reestablish, bool *send_shutdown, bool *remote_shutdown_received, u8 **final_scriptpubkey, u8 *flags, u8 **init_peer_pkt, bool *reached_announce_depth, struct secret *last_remote_secret, u8 **their_features, u8 **upfront_shutdown_script, secp256k1_ecdsa_signature **remote_ann_node_sig, secp256k1_ecdsa_signature **remote_ann_bitcoin_sig, bool *option_static_remotekey, bool *option_anchor_outputs, bool *dev_fast_gossip, bool *dev_fail_process_onionpacket, struct penalty_base **pbases, u8 **reestablish_only); +u8 *towire_channeld_init(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_features, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, u32 minimum_depth, u32 our_blockheight, const struct height_states *blockheight_states, u32 lease_expiry, const struct channel_config *our_config, const struct channel_config *their_config, const struct fee_states *fee_states, u32 feerate_min, u32 feerate_max, u32 feerate_penalty, const struct bitcoin_signature *first_commit_sig, const struct per_peer_state *per_peer_state, const struct pubkey *remote_fundingkey, const struct basepoints *remote_basepoints, const struct pubkey *remote_per_commit, const struct pubkey *old_remote_per_commit, enum side opener, u32 fee_base, u32 fee_proportional, struct amount_msat local_msatoshi, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct node_id *local_node_id, const struct node_id *remote_node_id, u32 commit_msec, u16 cltv_delta, bool last_was_revoke, const struct changed_htlc *last_sent_commit, u64 next_index_local, u64 next_index_remote, u64 revocations_received, u64 next_htlc_id, const struct existing_htlc **htlcs, bool local_funding_locked, bool remote_funding_locked, const struct short_channel_id *funding_short_id, bool reestablish, bool send_shutdown, bool remote_shutdown_received, const u8 *final_scriptpubkey, u8 flags, const u8 *init_peer_pkt, bool reached_announce_depth, const struct secret *last_remote_secret, const u8 *their_features, const u8 *upfront_shutdown_script, const secp256k1_ecdsa_signature *remote_ann_node_sig, const secp256k1_ecdsa_signature *remote_ann_bitcoin_sig, bool option_static_remotekey, bool option_anchor_outputs, bool dev_fast_gossip, bool dev_fail_process_onionpacket, const struct penalty_base *pbases, const u8 *reestablish_only); +bool fromwire_channeld_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_features, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, u32 *minimum_depth, u32 *our_blockheight, struct height_states **blockheight_states, u32 *lease_expiry, struct channel_config *our_config, struct channel_config *their_config, struct fee_states **fee_states, u32 *feerate_min, u32 *feerate_max, u32 *feerate_penalty, struct bitcoin_signature *first_commit_sig, struct per_peer_state **per_peer_state, struct pubkey *remote_fundingkey, struct basepoints *remote_basepoints, struct pubkey *remote_per_commit, struct pubkey *old_remote_per_commit, enum side *opener, u32 *fee_base, u32 *fee_proportional, struct amount_msat *local_msatoshi, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct node_id *local_node_id, struct node_id *remote_node_id, u32 *commit_msec, u16 *cltv_delta, bool *last_was_revoke, struct changed_htlc **last_sent_commit, u64 *next_index_local, u64 *next_index_remote, u64 *revocations_received, u64 *next_htlc_id, struct existing_htlc ***htlcs, bool *local_funding_locked, bool *remote_funding_locked, struct short_channel_id *funding_short_id, bool *reestablish, bool *send_shutdown, bool *remote_shutdown_received, u8 **final_scriptpubkey, u8 *flags, u8 **init_peer_pkt, bool *reached_announce_depth, struct secret *last_remote_secret, u8 **their_features, u8 **upfront_shutdown_script, secp256k1_ecdsa_signature **remote_ann_node_sig, secp256k1_ecdsa_signature **remote_ann_bitcoin_sig, bool *option_static_remotekey, bool *option_anchor_outputs, bool *dev_fast_gossip, bool *dev_fail_process_onionpacket, struct penalty_base **pbases, u8 **reestablish_only); /* WIRE: CHANNELD_FUNDING_DEPTH */ /* master->channeld funding hit new depth(funding locked if >= lock depth) */ @@ -230,6 +233,11 @@ bool fromwire_channeld_dev_quiesce_reply(const void *p); u8 *towire_channeld_upgraded(const tal_t *ctx, bool option_static_remotekey); bool fromwire_channeld_upgraded(const void *p, bool *option_static_remotekey); +/* WIRE: CHANNELD_BLOCKHEIGHT */ +/* Tell peer about our latest and greatest blockheight. */ +u8 *towire_channeld_blockheight(const tal_t *ctx, u32 blockheight); +bool fromwire_channeld_blockheight(const void *p, u32 *blockheight); + #endif /* LIGHTNING_CHANNELD_CHANNELD_WIREGEN_H */ -// SHA256STAMP:7fe345eb02876c231759ec37daba697e85ac3a43137e4b7cb67d136587e2bda5 +// SHA256STAMP:40a8d4ea75d57eeddfb5cc648a9ca3e3914dfe500a6054b6a6942f4023a17d82 diff --git a/channeld/full_channel.c b/channeld/full_channel.c index 3418dee06..684859a50 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -95,6 +96,7 @@ struct channel *new_full_channel(const tal_t *ctx, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, u32 minimum_depth, + const struct height_states *blockheight_states, u32 lease_expiry, struct amount_sat funding, struct amount_msat local_msat, @@ -114,6 +116,7 @@ struct channel *new_full_channel(const tal_t *ctx, funding_txid, funding_txout, minimum_depth, + blockheight_states, lease_expiry, funding, local_msat, @@ -979,6 +982,34 @@ static bool fee_incstate(struct channel *channel, return true; } +static bool blockheight_incstate(struct channel *channel, + enum side sidechanged, + enum htlc_state hstate) +{ + int preflags, postflags; + + preflags = htlc_state_flags(hstate); + postflags = htlc_state_flags(hstate + 1); + + /* You can't change sides. */ + assert((preflags & (HTLC_LOCAL_F_OWNER|HTLC_REMOTE_F_OWNER)) + == (postflags & (HTLC_LOCAL_F_OWNER|HTLC_REMOTE_F_OWNER))); + + /* These only advance through ADDING states. */ + if (!(htlc_state_flags(hstate) & HTLC_ADDING)) + return false; + + if (!inc_height_state(channel->blockheight_states, hstate)) + return false; + + status_debug("Blockheight: %s->%s %s now %u", + htlc_state_name(hstate), + htlc_state_name(hstate+1), + side_to_str(sidechanged), + *channel->blockheight_states->height[hstate+1]); + return true; +} + /* Returns flags which were changed. */ static int change_htlcs(struct channel *channel, enum side sidechanged, @@ -1022,11 +1053,16 @@ static int change_htlcs(struct channel *channel, } } - /* Update fees (do backwards, to avoid double-increment!). */ + /* Update fees and blockheight (do backwards, to avoid + * double-increment!). */ for (i = n_hstates - 1; i >= 0; i--) { if (fee_incstate(channel, sidechanged, htlc_states[i])) cflags |= (htlc_state_flags(htlc_states[i]) ^ htlc_state_flags(htlc_states[i]+1)); + + if (blockheight_incstate(channel, sidechanged, htlc_states[i])) + cflags |= (htlc_state_flags(htlc_states[i]) + ^ htlc_state_flags(htlc_states[i]+1)); } return cflags; @@ -1154,6 +1190,16 @@ bool channel_update_feerate(struct channel *channel, u32 feerate_per_kw) return true; } +void channel_update_blockheight(struct channel *channel, + u32 blockheight) +{ + status_debug("Setting %s blockheight to %u", + side_to_str(!channel->opener), blockheight); + + start_height_update(channel->blockheight_states, channel->opener, + blockheight); +} + bool channel_sending_commit(struct channel *channel, const struct htlc ***htlcs) { @@ -1278,10 +1324,14 @@ bool pending_updates(const struct channel *channel, struct htlc_map_iter it; const struct htlc *htlc; - /* Initiator might have fee changes in play. */ + /* Initiator might have fee changes or blockheight updates in play. */ if (side == channel->opener) { if (!feerate_changes_done(channel->fee_states, uncommitted_ok)) return true; + + if (!blockheight_changes_done(channel->blockheight_states, + uncommitted_ok)) + return true; } for (htlc = htlc_map_first(channel->htlcs, &it); diff --git a/channeld/full_channel.h b/channeld/full_channel.h index c7151ddb6..56b7c1514 100644 --- a/channeld/full_channel.h +++ b/channeld/full_channel.h @@ -17,6 +17,7 @@ struct existing_htlc; * @funding_txid: The commitment transaction id. * @funding_txout: The commitment transaction 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. * @local_msat: The amount for the local side (remainder goes to remote) @@ -38,6 +39,7 @@ struct channel *new_full_channel(const tal_t *ctx, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, u32 minimum_depth, + const struct height_states *blockheight_states, u32 lease_expiry, struct amount_sat funding, struct amount_msat local_msat, @@ -184,6 +186,13 @@ bool can_opener_afford_feerate(const struct channel *channel, u32 feerate); */ bool channel_update_feerate(struct channel *channel, u32 feerate_per_kw); +/* + * channel_update_blockheight: Change blockheight on non-opener side. + * @channel: The channel + * @blockheight: current blockheight + */ +void channel_update_blockheight(struct channel *channel, u32 blockheight); + /** * channel_feerate: Get fee rate for this side of channel. * @channel: The channel diff --git a/channeld/test/run-full_channel.c b/channeld/test/run-full_channel.c index e21350a64..db33e6ec5 100644 --- a/channeld/test/run-full_channel.c +++ b/channeld/test/run-full_channel.c @@ -1,3 +1,4 @@ +#include "../../common/blockheight_states.c" #include "../../common/channel_id.c" #include "../../common/fee_states.c" #include "../../common/initial_channel.c" @@ -370,6 +371,7 @@ int main(int argc, const char *argv[]) const struct htlc **htlc_map, **htlcs; const u8 *funding_wscript, *funding_wscript_alt; bool option_anchor_outputs = false; + u32 blockheight = 0; size_t i; chainparams = chainparams_for_network("bitcoin"); @@ -481,6 +483,7 @@ int main(int argc, const char *argv[]) derive_channel_id(&cid, &funding_txid, funding_output_index); lchannel = new_full_channel(tmpctx, &cid, &funding_txid, funding_output_index, 0, + take(new_height_states(NULL, LOCAL, &blockheight)), 0, /* No channel lease */ funding_amount, to_local, take(new_fee_states(NULL, LOCAL, @@ -493,6 +496,7 @@ int main(int argc, const char *argv[]) false, false, LOCAL); rchannel = new_full_channel(tmpctx, &cid, &funding_txid, funding_output_index, 0, + take(new_height_states(NULL, REMOTE, &blockheight)), 0, /* No channel lease */ funding_amount, to_remote, take(new_fee_states(NULL, REMOTE, diff --git a/closingd/closingd_wiregen.c b/closingd/closingd_wiregen.c index 9c840a5a0..e8c766b39 100644 --- a/closingd/closingd_wiregen.c +++ b/closingd/closingd_wiregen.c @@ -195,4 +195,4 @@ bool fromwire_closingd_complete(const void *p) return false; return cursor != NULL; } -// SHA256STAMP:a8b0af1ae87e71bc448585060b8d449c3e5f0d0f4f3ac195dcd4d84f8176ae17 +// SHA256STAMP:681e83ed1e1950220b1e9dbf168e5583e23120981b9a084eab5bc6ce1bc9a1aa diff --git a/closingd/closingd_wiregen.h b/closingd/closingd_wiregen.h index b948b737f..7d46f18b6 100644 --- a/closingd/closingd_wiregen.h +++ b/closingd/closingd_wiregen.h @@ -56,4 +56,4 @@ bool fromwire_closingd_complete(const void *p); #endif /* LIGHTNING_CLOSINGD_CLOSINGD_WIREGEN_H */ -// SHA256STAMP:a8b0af1ae87e71bc448585060b8d449c3e5f0d0f4f3ac195dcd4d84f8176ae17 +// SHA256STAMP:681e83ed1e1950220b1e9dbf168e5583e23120981b9a084eab5bc6ce1bc9a1aa diff --git a/common/blockheight_states.c b/common/blockheight_states.c new file mode 100644 index 000000000..3a5a151d1 --- /dev/null +++ b/common/blockheight_states.c @@ -0,0 +1,164 @@ +#include +#include +#include +#include +#include +#include +#include + +struct height_states *new_height_states(const tal_t *ctx, + enum side opener, + const u32 *blockheight) +{ + struct height_states *states = tal(ctx, struct height_states); + + /* Set to NULL except terminal value */ + for (size_t i = 0; i < ARRAY_SIZE(states->height); i++) + states->height[i] = NULL; + + if (blockheight) + /* We reuse fee states! */ + states->height[last_fee_state(opener)] + = tal_dup(states, u32, blockheight); + return states; +} + +u32 get_blockheight(const struct height_states *height_states, + enum side opener, + enum side side) +{ + /* The first non-NULL blockheight committed to this side is current */ + /* We use the same states as update_fee */ + for (enum htlc_state i = first_fee_state(opener); + i <= last_fee_state(opener); + i++) { + if (!height_states->height[i]) + continue; + if (!(htlc_state_flags(i) & HTLC_FLAG(side, HTLC_F_COMMITTED))) + continue; + return *height_states->height[i]; + } + + /* Some blockheight should always be set! */ + abort(); +} + +void start_height_update(struct height_states *height_states, + enum side opener, + u32 blockheight) +{ + /* Same as the feerate states */ + enum htlc_state start = first_fee_state(opener); + + /* BOLT #2: + * Unlike an HTLC, `update_fee` is never closed but simply replaced. + */ + if (height_states->height[start] == NULL) + height_states->height[start] = tal(height_states, u32); + *height_states->height[start] = blockheight; +} + + +/* Are blockheights all agreed by both sides? */ +bool blockheight_changes_done(const struct height_states *height_states, + bool ignore_uncommitted) +{ + size_t num_blockheights = 0; + for (size_t i = 0; i < ARRAY_SIZE(height_states->height); i++) { + if (ignore_uncommitted + && (i == RCVD_ADD_HTLC || i == SENT_ADD_HTLC)) + continue; + num_blockheights += (height_states->height[i] != NULL); + } + return num_blockheights == 1; +} + +bool inc_height_state(struct height_states *height_states, + enum htlc_state hstate) +{ + /* These only advance through ADDING states. */ + assert(htlc_state_flags(hstate) & HTLC_ADDING); + + if (!height_states->height[hstate]) + return false; + + /* FIXME: We can never clash, except at final state unless someone + * has violated protocol (eg, send two revoke_and_ack back-to-back) */ + tal_free(height_states->height[hstate+1]); + height_states->height[hstate+1] = height_states->height[hstate]; + height_states->height[hstate] = NULL; + return true; +} + +struct height_states *dup_height_states(const tal_t *ctx, + const struct height_states *states TAKES) +{ + struct height_states *n; + + if (taken(states)) + return cast_const(struct height_states *, + tal_steal(ctx, states)); + + n = tal_dup(ctx, struct height_states, states); + for (size_t i = 0; i < ARRAY_SIZE(n->height); i++) { + if (n->height[i]) + n->height[i] = tal_dup(n, u32, n->height[i]); + + } + return n; +} + +/* FIXME: we don't know opener inside fromwire_height_states, so can't do + * this there :( */ +bool height_states_valid(const struct height_states *states, enum side opener) +{ + /* We use the same states as update fee */ + return states->height[last_fee_state(opener)] != NULL; +} + +void towire_height_states(u8 **pptr, const struct height_states *states) +{ + for (enum htlc_state i = 0; i < ARRAY_SIZE(states->height); i++) { + /* We don't send uncommitted feestates */ + if (!(htlc_state_flags(i) & (HTLC_REMOTE_F_COMMITTED + | HTLC_LOCAL_F_COMMITTED)) + || states->height[i] == NULL) { + towire_bool(pptr, false); + continue; + } + towire_bool(pptr, true); + towire_u32(pptr, *states->height[i]); + } +} + +struct height_states *fromwire_height_states(const tal_t *ctx, const u8 **cursor, size_t *max) +{ + struct height_states *states = tal(ctx, struct height_states); + + for (enum htlc_state i = 0; i < ARRAY_SIZE(states->height); i++) { + if (fromwire_bool(cursor, max)) { + states->height[i] = tal(states, u32); + *states->height[i] = fromwire_u32(cursor, max); + } else { + states->height[i] = NULL; + } + } + if (!*cursor) + return tal_free(states); + return states; +} + +static const char *fmt_height_states(const tal_t *ctx, + const struct height_states *states) +{ + char *ret = tal_strdup(ctx, "{"); + for (enum htlc_state i = 0; i < ARRAY_SIZE(states->height); i++) { + if (states->height[i] != NULL) + tal_append_fmt(&ret, " %s:%u", + htlc_state_name(i), + *states->height[i]); + } + tal_append_fmt(&ret, " }"); + return ret; +} +REGISTER_TYPE_TO_STRING(height_states, fmt_height_states); diff --git a/common/blockheight_states.h b/common/blockheight_states.h new file mode 100644 index 000000000..715517533 --- /dev/null +++ b/common/blockheight_states.h @@ -0,0 +1,79 @@ +#ifndef LIGHTNING_COMMON_BLOCKHEIGHT_STATES_H +#define LIGHTNING_COMMON_BLOCKHEIGHT_STATES_H +#include "config.h" +#include +#include + +struct height_states { + /* Current blockheight: goes through same + * state machine as feestate addition. + * + * We need to know if there's an actual change pending though (even if + * it's a "change" to an idential feerate!) so we use pointers. + */ + u32 *height[HTLC_STATE_INVALID]; +}; + +/** + * new_height_states: Initialize a height_states structure as at + * open-of-channel. + * @ctx: the tal ctx to allocate off + * @opener: which side opened the channel + * (and thus, proposes blockheight updates). + * @blockheight: the initial blockheight (if any). + */ +struct height_states *new_height_states(const tal_t *ctx, + enum side opener, + const u32 *blockheight); + +/** + * get_blockheight: Get the current blockheight + * @height_states: the blockheight state machine + * @opener: which side opened the channel + * (and thus, proposes blockheight updates). + * @side: which side to get the blockheight for + */ +u32 get_blockheight(const struct height_states *height_states, + enum side opener, + enum side side); + +/** + * start_height_update: feed a new blockheight update into state machine. + * @height_states: the height state machine + * @opener: which side opened the channel (and thus, proposes + * blockheight updates). + * @blockheight: the new blockheight. + */ +void start_height_update(struct height_states *height_states, + enum side opener, + u32 blockheight); +/** + * inc_height_state: move this blockheight to the next state. + * @height_states: the blockheight state machine + * @hstate: state + * + * Moves height_states[hstate] to height_states[hstate+1], if not NULL. + * Returns true if it wasn't NULL. + */ +bool inc_height_state(struct height_states *height_states, + enum htlc_state hstate); + +/* Are blockheights all agreed by both sides? */ +bool blockheight_changes_done(const struct height_states *height_states, + bool ignore_uncommitted); + +/* Duplicate a set of height states */ +struct height_states *dup_height_states(const tal_t *ctx, + const struct height_states *states TAKES); + +/* Marshal and unmarshal */ +void towire_height_states(u8 **pptr, const struct height_states *height_states); +/* FIXME: You must check that height_states_valid! */ +struct height_states *fromwire_height_states(const tal_t *ctx, + const u8 **cursor, size_t *max); + +/** + * is this height_state struct valid for this side? + */ +bool height_states_valid(const struct height_states *states, enum side opener); +#endif /* LIGHTNING_COMMON_BLOCKHEIGHT_STATES_H */ diff --git a/common/initial_channel.c b/common/initial_channel.c index 3cf1b1e10..f65e6a35d 100644 --- a/common/initial_channel.c +++ b/common/initial_channel.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,7 @@ struct channel *new_initial_channel(const tal_t *ctx, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, u32 minimum_depth, + const struct height_states *height_states TAKES, u32 lease_expiry, struct amount_sat funding, struct amount_msat local_msatoshi, @@ -58,6 +60,13 @@ struct channel *new_initial_channel(const tal_t *ctx, /* takes() if necessary */ channel->fee_states = dup_fee_states(channel, fee_states); + /* takes() if necessary */ + if (!height_states) + channel->blockheight_states = NULL; + else + channel->blockheight_states + = dup_height_states(channel, height_states); + channel->view[LOCAL].owed[LOCAL] = channel->view[REMOTE].owed[LOCAL] = local_msatoshi; @@ -108,8 +117,11 @@ struct bitcoin_tx *initial_channel_tx(const tal_t *ctx, if (channel->lease_expiry == 0) csv_lock = 1; else - /* FIXME: */ - csv_lock = 1; + /* For the initial commitment, starts max lease */ + csv_lock = channel->lease_expiry + - get_blockheight(channel->blockheight_states, + channel->opener, + side); *wscript = bitcoin_redeem_2of2(ctx, &channel->funding_pubkey[side], diff --git a/common/initial_channel.h b/common/initial_channel.h index 187286ff0..959c66ba4 100644 --- a/common/initial_channel.h +++ b/common/initial_channel.h @@ -62,6 +62,10 @@ struct channel { /* Fee changes, some which may be in transit */ struct fee_states *fee_states; + /* Blockheight changes, some which may be in transit + * (option_will_fund)*/ + struct height_states *blockheight_states; + /* What it looks like to each side. */ struct channel_view view[NUM_SIDES]; @@ -82,7 +86,8 @@ struct channel { * @funding_txid: The commitment transaction id. * @funding_txout: The commitment transaction output number. * @minimum_depth: The minimum confirmations needed for funding transaction. - * @lease_expiry: Block the lease expires + * @height_states: The blockheight update states. + * @lease_expiry: Block the lease expires. * @funding_satoshis: The commitment transaction amount. * @local_msatoshi: The amount for the local side (remainder goes to remote) * @fee_states: The fee update states. @@ -103,6 +108,7 @@ struct channel *new_initial_channel(const tal_t *ctx, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, u32 minimum_depth, + const struct height_states *height_states TAKES, u32 lease_expiry, struct amount_sat funding, struct amount_msat local_msatoshi, diff --git a/common/peer_status_wiregen.c b/common/peer_status_wiregen.c index 3ffd2af45..fa756278e 100644 --- a/common/peer_status_wiregen.c +++ b/common/peer_status_wiregen.c @@ -80,4 +80,4 @@ bool fromwire_status_peer_error(const tal_t *ctx, const void *p, struct channel_ fromwire_u8_array(&cursor, &plen, *error_for_them, len); return cursor != NULL; } -// SHA256STAMP:9eae5e1735b52e459db2548ff73399a8cb503ddbf72defc5bfa4022f3682ffd5 +// SHA256STAMP:db80a04b587e0918ef55f7e82519f7ff86620c5ec4fd845452214059c1cdbd41 diff --git a/common/peer_status_wiregen.h b/common/peer_status_wiregen.h index a1bc77494..94978e02c 100644 --- a/common/peer_status_wiregen.h +++ b/common/peer_status_wiregen.h @@ -34,4 +34,4 @@ bool fromwire_status_peer_error(const tal_t *ctx, const void *p, struct channel_ #endif /* LIGHTNING_COMMON_PEER_STATUS_WIREGEN_H */ -// SHA256STAMP:9eae5e1735b52e459db2548ff73399a8cb503ddbf72defc5bfa4022f3682ffd5 +// SHA256STAMP:db80a04b587e0918ef55f7e82519f7ff86620c5ec4fd845452214059c1cdbd41 diff --git a/common/status_wiregen.c b/common/status_wiregen.c index dce8d303a..90da24ae2 100644 --- a/common/status_wiregen.c +++ b/common/status_wiregen.c @@ -214,4 +214,4 @@ bool fromwire_status_version(const tal_t *ctx, const void *p, wirestring **versi *version = fromwire_wirestring(ctx, &cursor, &plen); return cursor != NULL; } -// SHA256STAMP:676725f967cd09851ed0d872ed58ed058fa9de7d95acca7169e0262e7d0b2c64 +// SHA256STAMP:6f868de7019bd204be0d90618a044c20ec1170430e3196674040ddb7f7278e80 diff --git a/common/status_wiregen.h b/common/status_wiregen.h index 81c2a6ee7..202ac0143 100644 --- a/common/status_wiregen.h +++ b/common/status_wiregen.h @@ -58,4 +58,4 @@ bool fromwire_status_version(const tal_t *ctx, const void *p, wirestring **versi #endif /* LIGHTNING_COMMON_STATUS_WIREGEN_H */ -// SHA256STAMP:676725f967cd09851ed0d872ed58ed058fa9de7d95acca7169e0262e7d0b2c64 +// SHA256STAMP:6f868de7019bd204be0d90618a044c20ec1170430e3196674040ddb7f7278e80 diff --git a/common/type_to_string.h b/common/type_to_string.h index e82dbd31b..fda0df7d1 100644 --- a/common/type_to_string.h +++ b/common/type_to_string.h @@ -37,6 +37,7 @@ union printable_types { const struct amount_msat *amount_msat; const struct amount_sat *amount_sat; const struct fee_states *fee_states; + const struct height_states *height_states; const char *charp_; const struct wally_psbt *wally_psbt; const struct wally_tx *wally_tx; diff --git a/connectd/connectd_gossipd_wiregen.c b/connectd/connectd_gossipd_wiregen.c index f25aa2b08..1830b4707 100644 --- a/connectd/connectd_gossipd_wiregen.c +++ b/connectd/connectd_gossipd_wiregen.c @@ -161,4 +161,4 @@ bool fromwire_gossipd_get_addrs_reply(const tal_t *ctx, const void *p, struct wi fromwire_wireaddr(&cursor, &plen, *addrs + i); return cursor != NULL; } -// SHA256STAMP:5565fac68fbf90e24ef5f8230483b52952d342080d44ce9fb8ae0e9843ad1529 +// SHA256STAMP:a115dcd604f1bcbe48bf57b25bfc2b59ec7eff3c4790812fa1c460aee2b50811 diff --git a/connectd/connectd_gossipd_wiregen.h b/connectd/connectd_gossipd_wiregen.h index 81f127815..2dfc3b12b 100644 --- a/connectd/connectd_gossipd_wiregen.h +++ b/connectd/connectd_gossipd_wiregen.h @@ -54,4 +54,4 @@ bool fromwire_gossipd_get_addrs_reply(const tal_t *ctx, const void *p, struct wi #endif /* LIGHTNING_CONNECTD_CONNECTD_GOSSIPD_WIREGEN_H */ -// SHA256STAMP:5565fac68fbf90e24ef5f8230483b52952d342080d44ce9fb8ae0e9843ad1529 +// SHA256STAMP:a115dcd604f1bcbe48bf57b25bfc2b59ec7eff3c4790812fa1c460aee2b50811 diff --git a/connectd/connectd_wiregen.c b/connectd/connectd_wiregen.c index 122ad6021..63e764fa3 100644 --- a/connectd/connectd_wiregen.c +++ b/connectd/connectd_wiregen.c @@ -443,4 +443,4 @@ bool fromwire_connectd_dev_memleak_reply(const void *p, bool *leak) *leak = fromwire_bool(&cursor, &plen); return cursor != NULL; } -// SHA256STAMP:533fec0547d283247c2fbd2ef52c7df86614f5152c8f3282e0e1e699de3af5d4 +// SHA256STAMP:27a03f6c7a77a83be6fc4d063fd37d4bc47e7280310f19d72859ff3f409e05ca diff --git a/connectd/connectd_wiregen.h b/connectd/connectd_wiregen.h index 42acf72a8..e4f5c6504 100644 --- a/connectd/connectd_wiregen.h +++ b/connectd/connectd_wiregen.h @@ -110,4 +110,4 @@ bool fromwire_connectd_dev_memleak_reply(const void *p, bool *leak); #endif /* LIGHTNING_CONNECTD_CONNECTD_WIREGEN_H */ -// SHA256STAMP:533fec0547d283247c2fbd2ef52c7df86614f5152c8f3282e0e1e699de3af5d4 +// SHA256STAMP:27a03f6c7a77a83be6fc4d063fd37d4bc47e7280310f19d72859ff3f409e05ca diff --git a/devtools/Makefile b/devtools/Makefile index a9c532fe5..76ef117bd 100644 --- a/devtools/Makefile +++ b/devtools/Makefile @@ -18,6 +18,7 @@ DEVTOOLS_COMMON_OBJS := \ common/bech32_util.o \ common/bigsize.o \ common/bolt11.o \ + common/blockheight_states.o \ common/channel_id.o \ common/crypto_state.o \ common/decode_array.o \ diff --git a/devtools/mkcommit.c b/devtools/mkcommit.c index 8f0ba013a..3abf94cf6 100644 --- a/devtools/mkcommit.c +++ b/devtools/mkcommit.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -271,6 +272,7 @@ int main(int argc, char *argv[]) struct pubkey local_htlc_pubkey, remote_htlc_pubkey; bool option_static_remotekey = false, option_anchor_outputs = false; struct sha256_double hash; + u32 blockheight = 0; setup_locale(); chainparams = chainparams_for_network("bitcoin"); @@ -394,6 +396,8 @@ int main(int argc, char *argv[]) channel = new_full_channel(NULL, &cid, &funding_txid, funding_outnum, 1, + take(new_height_states(NULL, fee_payer, + &blockheight)), 0, /* Defaults to no lease */ funding_amount, local_msat, diff --git a/gossipd/gossip_store_wiregen.c b/gossipd/gossip_store_wiregen.c index 918cecbdc..7dee245ad 100644 --- a/gossipd/gossip_store_wiregen.c +++ b/gossipd/gossip_store_wiregen.c @@ -210,4 +210,4 @@ bool fromwire_gossipd_local_add_channel_obs(const tal_t *ctx, const void *p, str fromwire_u8_array(&cursor, &plen, *features, flen); return cursor != NULL; } -// SHA256STAMP:f5b4fcddb25b45895865636a90b9a5e0f9d2acfba04f4e9ecc14d2dfcad1e01a +// SHA256STAMP:a709d2e8f179fb393064e210e72f1118fd60f67134d5f94fe33dc58a62f38ff7 diff --git a/gossipd/gossip_store_wiregen.h b/gossipd/gossip_store_wiregen.h index a7c4b3a11..8788114fb 100644 --- a/gossipd/gossip_store_wiregen.h +++ b/gossipd/gossip_store_wiregen.h @@ -63,4 +63,4 @@ bool fromwire_gossipd_local_add_channel_obs(const tal_t *ctx, const void *p, str #endif /* LIGHTNING_GOSSIPD_GOSSIP_STORE_WIREGEN_H */ -// SHA256STAMP:f5b4fcddb25b45895865636a90b9a5e0f9d2acfba04f4e9ecc14d2dfcad1e01a +// SHA256STAMP:a709d2e8f179fb393064e210e72f1118fd60f67134d5f94fe33dc58a62f38ff7 diff --git a/gossipd/gossipd_peerd_wiregen.c b/gossipd/gossipd_peerd_wiregen.c index caffb94f9..f44c95924 100644 --- a/gossipd/gossipd_peerd_wiregen.c +++ b/gossipd/gossipd_peerd_wiregen.c @@ -161,4 +161,4 @@ bool fromwire_gossipd_local_channel_announcement(const tal_t *ctx, const void *p fromwire_u8_array(&cursor, &plen, *cannount, len); return cursor != NULL; } -// SHA256STAMP:bf705b59df34f8e21f337759dfd6d56e610be91c1838a1eef25c807d5b2e7184 +// SHA256STAMP:3b60c444839f3c615c80609a295f43fd95f1bd6e9b4a66e56c95cf0e4e7607b1 diff --git a/gossipd/gossipd_peerd_wiregen.h b/gossipd/gossipd_peerd_wiregen.h index 5274f1ee2..5dd30cd8a 100644 --- a/gossipd/gossipd_peerd_wiregen.h +++ b/gossipd/gossipd_peerd_wiregen.h @@ -57,4 +57,4 @@ bool fromwire_gossipd_local_channel_announcement(const tal_t *ctx, const void *p #endif /* LIGHTNING_GOSSIPD_GOSSIPD_PEERD_WIREGEN_H */ -// SHA256STAMP:bf705b59df34f8e21f337759dfd6d56e610be91c1838a1eef25c807d5b2e7184 +// SHA256STAMP:3b60c444839f3c615c80609a295f43fd95f1bd6e9b4a66e56c95cf0e4e7607b1 diff --git a/gossipd/gossipd_wiregen.c b/gossipd/gossipd_wiregen.c index 08d364955..0c0b3171b 100644 --- a/gossipd/gossipd_wiregen.c +++ b/gossipd/gossipd_wiregen.c @@ -777,4 +777,4 @@ bool fromwire_gossipd_new_lease_rates(const void *p, struct lease_rates *rates) fromwire_lease_rates(&cursor, &plen, rates); return cursor != NULL; } -// SHA256STAMP:c511c2859bffa718708c4cceedd59807d0a43cd48060a59bf7cbabfa2f6515f9 +// SHA256STAMP:a0408d2e1f668c085378bc2729e08d8712a95edc48d12df8c6cbf063aeddbf32 diff --git a/gossipd/gossipd_wiregen.h b/gossipd/gossipd_wiregen.h index f1c39c19e..7a21446be 100644 --- a/gossipd/gossipd_wiregen.h +++ b/gossipd/gossipd_wiregen.h @@ -188,4 +188,4 @@ bool fromwire_gossipd_new_lease_rates(const void *p, struct lease_rates *rates); #endif /* LIGHTNING_GOSSIPD_GOSSIPD_WIREGEN_H */ -// SHA256STAMP:c511c2859bffa718708c4cceedd59807d0a43cd48060a59bf7cbabfa2f6515f9 +// SHA256STAMP:a0408d2e1f668c085378bc2729e08d8712a95edc48d12df8c6cbf063aeddbf32 diff --git a/hsmd/hsmd_wiregen.c b/hsmd/hsmd_wiregen.c index 587250c95..1ffce0751 100644 --- a/hsmd/hsmd_wiregen.c +++ b/hsmd/hsmd_wiregen.c @@ -1331,4 +1331,4 @@ bool fromwire_hsmd_sign_option_will_fund_offer_reply(const void *p, secp256k1_ec fromwire_secp256k1_ecdsa_signature(&cursor, &plen, rsig); return cursor != NULL; } -// SHA256STAMP:c1ec339d1925da25ee587ffb4fb5e35d0b3c578e525f519384c8fecc1054dc2a +// SHA256STAMP:5cc29ba49eb086d023342733bcaeb16b5b8e3c5b7b9d5826e70dd4f46b0d1dd2 diff --git a/hsmd/hsmd_wiregen.h b/hsmd/hsmd_wiregen.h index 7fbabc6a6..830d52f62 100644 --- a/hsmd/hsmd_wiregen.h +++ b/hsmd/hsmd_wiregen.h @@ -295,4 +295,4 @@ bool fromwire_hsmd_sign_option_will_fund_offer_reply(const void *p, secp256k1_ec #endif /* LIGHTNING_HSMD_HSMD_WIREGEN_H */ -// SHA256STAMP:c1ec339d1925da25ee587ffb4fb5e35d0b3c578e525f519384c8fecc1054dc2a +// SHA256STAMP:5cc29ba49eb086d023342733bcaeb16b5b8e3c5b7b9d5826e70dd4f46b0d1dd2 diff --git a/lightningd/Makefile b/lightningd/Makefile index 117ccf225..c4dfafdd3 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -69,6 +69,7 @@ LIGHTNINGD_COMMON_OBJS := \ common/bigsize.o \ common/bip32.o \ common/blinding.o \ + common/blockheight_states.o \ common/bolt11.o \ common/bolt11_json.o \ common/bolt12.o \ diff --git a/lightningd/channel.c b/lightningd/channel.c index 1a5d2ee1d..a4ead163d 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -163,8 +164,8 @@ new_inflight(struct channel *channel, const struct bitcoin_signature last_sig, const u32 lease_expiry, const secp256k1_ecdsa_signature *lease_commit_sig, - const u32 lease_chan_max_msat, - const u16 lease_chan_max_ppt) + const u32 lease_chan_max_msat, const u16 lease_chan_max_ppt, + const u32 lease_blockheight_start) { struct wally_psbt *last_tx_psbt_clone; struct channel_inflight *inflight @@ -189,8 +190,16 @@ new_inflight(struct channel *channel, inflight->last_sig = last_sig; inflight->tx_broadcast = false; + /* Channel lease infos */ + inflight->lease_blockheight_start = lease_blockheight_start; inflight->lease_expiry = lease_expiry; - inflight->lease_commit_sig = tal_dup(inflight, secp256k1_ecdsa_signature, lease_commit_sig); + if (lease_commit_sig) + inflight->lease_commit_sig + = tal_dup(inflight, secp256k1_ecdsa_signature, + lease_commit_sig); + else + inflight->lease_commit_sig = NULL; + inflight->lease_chan_max_msat = lease_chan_max_msat; inflight->lease_chan_max_ppt = lease_chan_max_ppt; @@ -353,6 +362,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid, enum state_change reason, /* NULL or stolen */ const struct bitcoin_outpoint *shutdown_wrong_funding, + const struct height_states *height_states TAKES, u32 lease_expiry, secp256k1_ecdsa_signature *lease_commit_sig STEALS, u32 lease_chan_max_msat, @@ -449,6 +459,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid, channel->lease_commit_sig = tal_steal(channel, lease_commit_sig); channel->lease_chan_max_msat = lease_chan_max_msat; channel->lease_chan_max_ppt = lease_chan_max_ppt; + channel->blockheight_states = dup_height_states(channel, height_states); list_add_tail(&peer->channels, &channel->list); channel->rr_number = peer->ld->rr_counter++; diff --git a/lightningd/channel.h b/lightningd/channel.h index 2dbf8d54b..196119445 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -51,6 +51,7 @@ struct channel_inflight { secp256k1_ecdsa_signature *lease_commit_sig; u32 lease_chan_max_msat; u16 lease_chan_max_ppt; + u32 lease_blockheight_start; }; struct open_attempt { @@ -150,6 +151,9 @@ struct channel { /* Fee status */ const struct fee_states *fee_states; + /* Height states (option_will_fund, update_blockheight) */ + const struct height_states *blockheight_states; + /* Our local basepoints */ struct basepoints local_basepoints; @@ -292,6 +296,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid, enum state_change reason, /* NULL or stolen */ const struct bitcoin_outpoint *shutdown_wrong_funding STEALS, + const struct height_states *height_states TAKES, u32 lease_expiry, secp256k1_ecdsa_signature *lease_commit_sig STEALS, u32 lease_chan_max_msat, @@ -311,7 +316,8 @@ new_inflight(struct channel *channel, const u32 lease_expiry, const secp256k1_ecdsa_signature *lease_commit_sig, const u32 lease_chan_max_msat, - const u16 lease_chan_max_ppt); + const u16 lease_chan_max_ppt, + const u32 lease_blockheight_start); /* Given a txid, find an inflight channel stub. Returns NULL if none found */ struct channel_inflight *channel_inflight_find(struct channel *channel, diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index 1df8e749f..02d0f4b42 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -69,6 +69,30 @@ static void try_update_feerates(struct lightningd *ld, struct channel *channel) update_feerates(ld, channel); } +static void try_update_blockheight(struct lightningd *ld, + struct channel *channel, + u32 blockheight) +{ + u8 *msg; + + /* We use the same heuristic for channel states as feerates */ + if (!channel_fees_can_change(channel)) + return; + + /* Can't if no daemon listening. */ + if (!channel->owner) + return; + + /* We don't update the blockheight for non-leased chans */ + if (channel->lease_expiry == 0) + return; + + log_debug(ld->log, "update_blockheight: height = %u", blockheight); + + msg = towire_channeld_blockheight(NULL, blockheight); + subd_send_msg(channel->owner, take(msg)); +} + void notify_feerate_change(struct lightningd *ld) { struct peer *peer; @@ -155,6 +179,9 @@ static void lockin_complete(struct channel *channel) /* Fees might have changed (and we use IMMEDIATE once we're funded), * so update now. */ try_update_feerates(channel->peer->ld, channel); + + try_update_blockheight(channel->peer->ld, channel, + get_block_height(channel->peer->ld->topology)); channel_record_open(channel); } @@ -451,6 +478,7 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds) case WIRE_CHANNELD_SEND_SHUTDOWN: case WIRE_CHANNELD_DEV_REENABLE_COMMIT: case WIRE_CHANNELD_FEERATES: + case WIRE_CHANNELD_BLOCKHEIGHT: case WIRE_CHANNELD_SPECIFIC_FEERATES: case WIRE_CHANNELD_DEV_MEMLEAK: case WIRE_CHANNELD_DEV_QUIESCE: @@ -587,6 +615,9 @@ void peer_start_channeld(struct channel *channel, channel->funding_outnum, channel->funding, channel->minimum_depth, + get_block_height(ld->topology), + channel->blockheight_states, + channel->lease_expiry, &channel->our_config, &channel->channel_info.their_config, channel->fee_states, @@ -647,9 +678,13 @@ void peer_start_channeld(struct channel *channel, /* We don't expect a response: we are triggered by funding_depth_cb. */ subd_send_msg(channel->owner, take(initmsg)); - /* On restart, feerate might not be what we expect: adjust now. */ - if (channel->opener == LOCAL) + /* On restart, feerate and blockheight + * might not be what we expect: adjust now. */ + if (channel->opener == LOCAL) { try_update_feerates(ld, channel); + try_update_blockheight(ld, channel, + get_block_height(ld->topology)); + } } bool channel_tell_depth(struct lightningd *ld, @@ -757,7 +792,11 @@ void channel_notify_new_block(struct lightningd *ld, continue; if (is_fundee_should_forget(ld, channel, block_height)) { tal_arr_expand(&to_forget, channel); - } + } else + /* Let channels know about new blocks, + * required for lease updates */ + try_update_blockheight(ld, channel, + block_height); } } diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index 88302d836..34fd7d5ba 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -1116,7 +1117,8 @@ wallet_update_channel(struct lightningd *ld, const u32 lease_expiry, secp256k1_ecdsa_signature *lease_commit_sig STEALS, const u32 lease_chan_max_msat, - const u16 lease_chan_max_ppt) + const u16 lease_chan_max_ppt, + const u32 lease_blockheight_start) { struct amount_msat our_msat; struct channel_inflight *inflight; @@ -1143,6 +1145,11 @@ wallet_update_channel(struct lightningd *ld, channel->lease_chan_max_msat = lease_chan_max_msat; channel->lease_chan_max_ppt = lease_chan_max_ppt; + tal_free(channel->blockheight_states); + channel->blockheight_states = new_height_states(channel, + channel->opener, + &lease_blockheight_start); + channel_set_last_tx(channel, tal_steal(channel, remote_commit), remote_commit_sig, @@ -1164,7 +1171,8 @@ wallet_update_channel(struct lightningd *ld, channel->lease_expiry, channel->lease_commit_sig, channel->lease_chan_max_msat, - channel->lease_chan_max_ppt); + channel->lease_chan_max_ppt, + lease_blockheight_start); wallet_inflight_add(ld->wallet, inflight); return inflight; @@ -1186,6 +1194,7 @@ wallet_commit_channel(struct lightningd *ld, const u8 *our_upfront_shutdown_script, const u8 *remote_upfront_shutdown_script, struct wally_psbt *psbt STEALS, + const u32 lease_blockheight_start, const u32 lease_expiry, secp256k1_ecdsa_signature *lease_commit_sig STEALS, const u32 lease_chan_max_msat, @@ -1257,6 +1266,9 @@ wallet_commit_channel(struct lightningd *ld, channel->first_blocknum = get_block_height(ld->topology); /* Update lease info for channel */ + channel->blockheight_states = new_height_states(channel, + channel->opener, + &lease_blockheight_start); channel->lease_expiry = lease_expiry; tal_free(channel->lease_commit_sig); @@ -1281,7 +1293,8 @@ wallet_commit_channel(struct lightningd *ld, channel->lease_expiry, channel->lease_commit_sig, channel->lease_chan_max_msat, - channel->lease_chan_max_ppt); + channel->lease_chan_max_ppt, + lease_blockheight_start); wallet_inflight_add(ld->wallet, inflight); return inflight; @@ -2837,7 +2850,7 @@ static void handle_commit_received(struct subd *dualopend, struct bitcoin_txid funding_txid; u16 funding_outnum, lease_chan_max_ppt; u32 feerate_funding, feerate_commitment, lease_expiry, - lease_chan_max_msat; + lease_chan_max_msat, lease_blockheight_start; struct amount_sat total_funding, funding_ours; u8 *remote_upfront_shutdown_script, *local_upfront_shutdown_script; @@ -2870,6 +2883,7 @@ static void handle_commit_received(struct subd *dualopend, &feerate_commitment, &local_upfront_shutdown_script, &remote_upfront_shutdown_script, + &lease_blockheight_start, &lease_expiry, &lease_commit_sig, &lease_chan_max_msat, @@ -2915,6 +2929,7 @@ static void handle_commit_received(struct subd *dualopend, local_upfront_shutdown_script, remote_upfront_shutdown_script, psbt, + lease_blockheight_start, lease_expiry, lease_commit_sig, lease_chan_max_msat, @@ -2951,7 +2966,8 @@ static void handle_commit_received(struct subd *dualopend, lease_expiry, lease_commit_sig, lease_chan_max_msat, - lease_chan_max_ppt))) { + lease_chan_max_ppt, + lease_blockheight_start))) { channel_internal_error(channel, "wallet_update_channel failed" " (chan %s)", @@ -3224,7 +3240,7 @@ void peer_restart_dualopend(struct peer *peer, struct per_peer_state *pps, struct channel *channel) { - u32 max_to_self_delay; + u32 max_to_self_delay, blockheight; struct amount_msat min_effective_htlc_capacity; struct channel_config unused_config; struct channel_inflight *inflight; @@ -3268,6 +3284,8 @@ void peer_restart_dualopend(struct peer *peer, inflight = channel_current_inflight(channel); assert(inflight); + blockheight = get_blockheight(channel->blockheight_states, + channel->opener, LOCAL); msg = towire_dualopend_reinit(NULL, chainparams, @@ -3301,6 +3319,7 @@ void peer_restart_dualopend(struct peer *peer, inflight->remote_tx_sigs, channel->fee_states, channel->channel_flags, + blockheight, inflight->lease_expiry, inflight->lease_commit_sig, inflight->lease_chan_max_msat, diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index bf4fd543f..995acc762 100644 --- a/lightningd/opening_control.c +++ b/lightningd/opening_control.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -105,6 +106,7 @@ wallet_commit_channel(struct lightningd *ld, s64 final_key_idx; u64 static_remotekey_start; bool option_anchor_outputs; + u32 lease_start_blockheight = 0; /* No leases on v1 */ /* We cannot both be the fundee *and* have a `fundchannel_start` * command running! @@ -217,6 +219,8 @@ wallet_commit_channel(struct lightningd *ld, NUM_SIDES, /* closer not yet known */ uc->fc ? REASON_USER : REASON_REMOTE, NULL, + take(new_height_states(NULL, uc->fc ? LOCAL : REMOTE, + &lease_start_blockheight)), 0, NULL, 0, 0); /* No leases on v1s */ /* Now we finally put it in the database. */ diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index f2d9a36c6..b0aaf76ae 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -1352,6 +1352,11 @@ static void update_channel_from_inflight(struct lightningd *ld, channel->lease_chan_max_msat = inflight->lease_chan_max_msat; channel->lease_chan_max_ppt = inflight->lease_chan_max_ppt; + tal_free(channel->blockheight_states); + channel->blockheight_states = new_height_states(channel, + channel->opener, + &inflight->lease_blockheight_start); + /* Make a 'clone' of this tx */ psbt_copy = clone_psbt(channel, inflight->last_tx->psbt); channel_set_last_tx(channel, diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index e5ccd4c75..d16263f54 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -454,6 +454,11 @@ void merkle_tlv(const struct tlv_field *fields UNNEEDED, struct sha256 *merkle U struct bolt11 *new_bolt11(const tal_t *ctx UNNEEDED, const struct amount_msat *msat TAKES UNNEEDED) { fprintf(stderr, "new_bolt11 called!\n"); abort(); } +/* Generated stub for new_height_states */ +struct height_states *new_height_states(const tal_t *ctx UNNEEDED, + enum side opener UNNEEDED, + const u32 *blockheight UNNEEDED) +{ fprintf(stderr, "new_height_states called!\n"); abort(); } /* Generated stub for new_reltimer_ */ struct oneshot *new_reltimer_(struct timers *timers UNNEEDED, const tal_t *ctx UNNEEDED, diff --git a/onchaind/onchaind_wiregen.c b/onchaind/onchaind_wiregen.c index a42f776e8..b8656a6c6 100644 --- a/onchaind/onchaind_wiregen.c +++ b/onchaind/onchaind_wiregen.c @@ -637,4 +637,4 @@ bool fromwire_onchaind_notify_coin_mvt(const void *p, struct chain_coin_mvt *mvt fromwire_chain_coin_mvt(&cursor, &plen, mvt); return cursor != NULL; } -// SHA256STAMP:746e39c14fccea8ff63ee097aa2b742ff0cdb63bd6dfaecd02b8b1c9fab58376 +// SHA256STAMP:40630b923c5c303627b75b8ca663b0d8a060039d2171571f6ecab580695dfdba diff --git a/onchaind/onchaind_wiregen.h b/onchaind/onchaind_wiregen.h index 7b6cc5751..7f9de0d68 100644 --- a/onchaind/onchaind_wiregen.h +++ b/onchaind/onchaind_wiregen.h @@ -161,4 +161,4 @@ bool fromwire_onchaind_notify_coin_mvt(const void *p, struct chain_coin_mvt *mvt #endif /* LIGHTNING_ONCHAIND_ONCHAIND_WIREGEN_H */ -// SHA256STAMP:746e39c14fccea8ff63ee097aa2b742ff0cdb63bd6dfaecd02b8b1c9fab58376 +// SHA256STAMP:40630b923c5c303627b75b8ca663b0d8a060039d2171571f6ecab580695dfdba diff --git a/openingd/Makefile b/openingd/Makefile index 98b176ec0..655119611 100644 --- a/openingd/Makefile +++ b/openingd/Makefile @@ -36,6 +36,7 @@ OPENINGD_COMMON_OBJS := \ common/bigsize.o \ common/billboard.o \ common/bip32.o \ + common/blockheight_states.o \ common/channel_config.o \ common/channel_id.o \ common/crypto_state.o \ diff --git a/openingd/dualopend.c b/openingd/dualopend.c index 05f0d1ba3..4bf1dee01 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -124,6 +125,9 @@ struct tx_state { /* Rates that we're using for this open... */ struct lease_rates *rates; + /* Lease blockheight start */ + u32 blockheight; + /* If delay til the channel funds lease expires */ u32 lease_expiry; @@ -144,6 +148,7 @@ static struct tx_state *new_tx_state(const tal_t *ctx) tx_state->remote_funding_sigs_rcvd = false; tx_state->lease_expiry = 0; + tx_state->blockheight = 0; tx_state->lease_commit_sig = NULL; tx_state->lease_chan_max_msat = 0; tx_state->lease_chan_max_ppt = 0; @@ -1697,6 +1702,8 @@ static void revert_channel_state(struct state *state) &tx_state->funding_txid, tx_state->funding_txout, state->minimum_depth, + take(new_height_states(NULL, opener, + &tx_state->blockheight)), tx_state->lease_expiry, total, our_msats, @@ -1796,6 +1803,9 @@ static u8 *accepter_commits(struct state *state, &tx_state->funding_txid, tx_state->funding_txout, state->minimum_depth, + take(new_height_states(NULL, REMOTE, + &tx_state->blockheight)), + tx_state->lease_expiry, total, our_msats, @@ -1922,6 +1932,7 @@ static u8 *accepter_commits(struct state *state, state->feerate_per_kw_commitment, state->upfront_shutdown_script[LOCAL], state->upfront_shutdown_script[REMOTE], + tx_state->blockheight, tx_state->lease_expiry, tx_state->lease_commit_sig, tx_state->lease_chan_max_msat, @@ -2003,7 +2014,6 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) char *err_reason; u8 *msg; struct amount_sat total, requested_amt, lease_fee; - u32 lease_blockheight_start; enum dualopend_wire msg_type; struct tx_state *tx_state = state->tx_state; @@ -2043,12 +2053,10 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) /* FIXME: Do we support this? */ requested_amt = amount_sat(open_tlv->request_funds->requested_sats); - lease_blockheight_start + tx_state->blockheight = open_tlv->request_funds->blockheight; - } else { + } else requested_amt = AMOUNT_SAT(0); - lease_blockheight_start = 0; - } /* BOLT-* #2 * If the peer's revocation basepoint is unknown (e.g. @@ -2115,7 +2123,7 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) tx_state->tx_locktime, state->upfront_shutdown_script[REMOTE], requested_amt, - lease_blockheight_start); + tx_state->blockheight); wire_sync_write(REQ_FD, take(msg)); msg = wire_sync_read(tmpctx, REQ_FD); @@ -2228,7 +2236,7 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) if (open_tlv->request_funds && tx_state->rates) accept_tlv_add_offer(a_tlv, tx_state, tx_state->rates, state->our_funding_pubkey, - lease_blockheight_start); + tx_state->blockheight); msg = towire_accept_channel2(tmpctx, &state->channel_id, @@ -2258,7 +2266,7 @@ static void accepter_start(struct state *state, const u8 *oc2_msg) /* Add our fee to our amount now */ if (tx_state->rates) { tx_state->lease_expiry - = lease_blockheight_start + LEASE_RATE_DURATION; + = tx_state->blockheight + LEASE_RATE_DURATION; /* BOLT- #2: * The lease fee is added to the accepter's balance @@ -2402,6 +2410,8 @@ static u8 *opener_commits(struct state *state, &tx_state->funding_txid, tx_state->funding_txout, state->minimum_depth, + take(new_height_states(NULL, LOCAL, + &state->tx_state->blockheight)), tx_state->lease_expiry, total, our_msats, @@ -2572,6 +2582,7 @@ static u8 *opener_commits(struct state *state, state->feerate_per_kw_commitment, state->upfront_shutdown_script[LOCAL], state->upfront_shutdown_script[REMOTE], + tx_state->blockheight, tx_state->lease_expiry, tx_state->lease_commit_sig, tx_state->lease_chan_max_msat, @@ -2586,7 +2597,6 @@ static void opener_start(struct state *state, u8 *msg) struct channel_id cid; char *err_reason; struct amount_sat total, requested_sats, lease_fee; - u32 current_blockheight; bool dry_run; struct tx_state *tx_state = state->tx_state; @@ -2598,7 +2608,7 @@ static void opener_start(struct state *state, u8 *msg) &tx_state->feerate_per_kw_funding, &state->channel_flags, &requested_sats, - ¤t_blockheight, + &tx_state->blockheight, &dry_run)) master_badmsg(WIRE_DUALOPEND_OPENER_INIT, msg); @@ -2633,7 +2643,7 @@ static void opener_start(struct state *state, u8 *msg) tal(open_tlv, struct tlv_opening_tlvs_request_funds); open_tlv->request_funds->requested_sats = requested_sats.satoshis; /* Raw: struct -> wire */ - open_tlv->request_funds->blockheight = current_blockheight; + open_tlv->request_funds->blockheight = tx_state->blockheight; } msg = towire_open_channel2(NULL, @@ -2746,7 +2756,7 @@ static void opener_start(struct state *state, u8 *msg) char *err_msg; struct lease_rates *rates = &a_tlv->will_fund->lease_rates; - tx_state->lease_expiry = current_blockheight + LEASE_RATE_DURATION; + tx_state->lease_expiry = tx_state->blockheight + LEASE_RATE_DURATION; msg = towire_dualopend_validate_lease(NULL, &a_tlv->will_fund->signature, @@ -3785,6 +3795,7 @@ int main(int argc, char *argv[]) &state->tx_state->remote_funding_sigs_rcvd, &fee_states, &state->channel_flags, + &state->tx_state->blockheight, &state->tx_state->lease_expiry, &state->tx_state->lease_commit_sig, &state->tx_state->lease_chan_max_msat, @@ -3797,6 +3808,8 @@ int main(int argc, char *argv[]) &state->tx_state->funding_txid, state->tx_state->funding_txout, state->minimum_depth, + take(new_height_states(NULL, opener, + &state->tx_state->blockheight)), state->tx_state->lease_expiry, total_funding, our_msat, diff --git a/openingd/dualopend_wire.csv b/openingd/dualopend_wire.csv index 1a7c48b9d..823b790ef 100644 --- a/openingd/dualopend_wire.csv +++ b/openingd/dualopend_wire.csv @@ -65,6 +65,7 @@ msgdata,dualopend_reinit,remote_shutdown_scriptpubkey,u8,remote_shutdown_len msgdata,dualopend_reinit,remote_funding_sigs_received,bool, msgdata,dualopend_reinit,fee_states,fee_states, msgdata,dualopend_reinit,channel_flags,u8, +msgdata,dualopend_reinit,lease_start_blockheight,u32, msgdata,dualopend_reinit,lease_expiry,u32, msgdata,dualopend_reinit,lease_commit_sig,?secp256k1_ecdsa_signature, msgdata,dualopend_reinit,lease_chan_max_msat,u32, @@ -146,6 +147,7 @@ msgdata,dualopend_commit_rcvd,local_shutdown_len,u16, msgdata,dualopend_commit_rcvd,local_shutdown_scriptpubkey,u8,local_shutdown_len msgdata,dualopend_commit_rcvd,remote_shutdown_len,u16, msgdata,dualopend_commit_rcvd,remote_shutdown_scriptpubkey,u8,remote_shutdown_len +msgdata,dualopend_commit_rcvd,lease_start_blockheight,u32, msgdata,dualopend_commit_rcvd,lease_expiry,u32, msgdata,dualopend_commit_rcvd,lease_commit_sig,?secp256k1_ecdsa_signature, msgdata,dualopend_commit_rcvd,lease_chan_max_msat,u32, diff --git a/openingd/dualopend_wiregen.c b/openingd/dualopend_wiregen.c index 19b218690..54083001c 100644 --- a/openingd/dualopend_wiregen.c +++ b/openingd/dualopend_wiregen.c @@ -152,7 +152,7 @@ bool fromwire_dualopend_init(const tal_t *ctx, const void *p, const struct chain /* WIRE: DUALOPEND_REINIT */ /* master-dualopend: peer has reconnected */ -u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_feature_set, const u8 *their_init_features, const struct channel_config *our_config, const struct channel_config *their_config, const struct channel_id *channel_id, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct pubkey *their_funding_pubkey, u32 minimum_depth, const struct bitcoin_txid *funding_txid, u16 funding_txout, u32 most_recent_feerate_per_kw_funding, struct amount_sat funding_satoshi, struct amount_msat our_funding, const struct basepoints *their_basepoints, const struct pubkey *remote_per_commit, const struct wally_psbt *funding_psbt, enum side opener, bool local_funding_locked, bool remote_funding_locked, bool send_shutdown, bool remote_shutdown_received, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey, bool remote_funding_sigs_received, const struct fee_states *fee_states, u8 channel_flags, u32 lease_expiry, const secp256k1_ecdsa_signature *lease_commit_sig, u32 lease_chan_max_msat, u16 lease_chan_max_ppt) +u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_feature_set, const u8 *their_init_features, const struct channel_config *our_config, const struct channel_config *their_config, const struct channel_id *channel_id, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct pubkey *their_funding_pubkey, u32 minimum_depth, const struct bitcoin_txid *funding_txid, u16 funding_txout, u32 most_recent_feerate_per_kw_funding, struct amount_sat funding_satoshi, struct amount_msat our_funding, const struct basepoints *their_basepoints, const struct pubkey *remote_per_commit, const struct wally_psbt *funding_psbt, enum side opener, bool local_funding_locked, bool remote_funding_locked, bool send_shutdown, bool remote_shutdown_received, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey, bool remote_funding_sigs_received, const struct fee_states *fee_states, u8 channel_flags, u32 lease_start_blockheight, u32 lease_expiry, const secp256k1_ecdsa_signature *lease_commit_sig, u32 lease_chan_max_msat, u16 lease_chan_max_ppt) { u16 their_init_features_len = tal_count(their_init_features); u16 local_shutdown_len = tal_count(local_shutdown_scriptpubkey); @@ -194,6 +194,7 @@ u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainpar towire_bool(&p, remote_funding_sigs_received); towire_fee_states(&p, fee_states); towire_u8(&p, channel_flags); + towire_u32(&p, lease_start_blockheight); towire_u32(&p, lease_expiry); if (!lease_commit_sig) towire_bool(&p, false); @@ -206,7 +207,7 @@ u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainpar return memcheck(p, tal_count(p)); } -bool fromwire_dualopend_reinit(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_feature_set, u8 **their_init_features, struct channel_config *our_config, struct channel_config *their_config, struct channel_id *channel_id, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct pubkey *their_funding_pubkey, u32 *minimum_depth, struct bitcoin_txid *funding_txid, u16 *funding_txout, u32 *most_recent_feerate_per_kw_funding, struct amount_sat *funding_satoshi, struct amount_msat *our_funding, struct basepoints *their_basepoints, struct pubkey *remote_per_commit, struct wally_psbt **funding_psbt, enum side *opener, bool *local_funding_locked, bool *remote_funding_locked, bool *send_shutdown, bool *remote_shutdown_received, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey, bool *remote_funding_sigs_received, struct fee_states **fee_states, u8 *channel_flags, u32 *lease_expiry, secp256k1_ecdsa_signature **lease_commit_sig, u32 *lease_chan_max_msat, u16 *lease_chan_max_ppt) +bool fromwire_dualopend_reinit(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_feature_set, u8 **their_init_features, struct channel_config *our_config, struct channel_config *their_config, struct channel_id *channel_id, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct pubkey *their_funding_pubkey, u32 *minimum_depth, struct bitcoin_txid *funding_txid, u16 *funding_txout, u32 *most_recent_feerate_per_kw_funding, struct amount_sat *funding_satoshi, struct amount_msat *our_funding, struct basepoints *their_basepoints, struct pubkey *remote_per_commit, struct wally_psbt **funding_psbt, enum side *opener, bool *local_funding_locked, bool *remote_funding_locked, bool *send_shutdown, bool *remote_shutdown_received, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey, bool *remote_funding_sigs_received, struct fee_states **fee_states, u8 *channel_flags, u32 *lease_start_blockheight, u32 *lease_expiry, secp256k1_ecdsa_signature **lease_commit_sig, u32 *lease_chan_max_msat, u16 *lease_chan_max_ppt) { u16 their_init_features_len; u16 local_shutdown_len; @@ -257,6 +258,7 @@ bool fromwire_dualopend_reinit(const tal_t *ctx, const void *p, const struct cha *remote_funding_sigs_received = fromwire_bool(&cursor, &plen); *fee_states = fromwire_fee_states(ctx, &cursor, &plen); *channel_flags = fromwire_u8(&cursor, &plen); + *lease_start_blockheight = fromwire_u32(&cursor, &plen); *lease_expiry = fromwire_u32(&cursor, &plen); if (!fromwire_bool(&cursor, &plen)) *lease_commit_sig = NULL; @@ -492,7 +494,7 @@ bool fromwire_dualopend_rbf_init(const tal_t *ctx, const void *p, struct amount_ /* WIRE: DUALOPEND_COMMIT_RCVD */ /* dualopend->master: ready to commit channel open to database and */ /* get some signatures for the funding_tx. */ -u8 *towire_dualopend_commit_rcvd(const tal_t *ctx, const struct channel_config *their_config, const struct bitcoin_tx *remote_first_commit, const struct penalty_base *pbase, const struct bitcoin_signature *first_commit_sig, const struct wally_psbt *psbt, const struct pubkey *revocation_basepoint, const struct pubkey *payment_basepoint, const struct pubkey *htlc_basepoint, const struct pubkey *delayed_payment_basepoint, const struct pubkey *their_per_commit_point, const struct pubkey *remote_fundingkey, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshis, struct amount_sat our_funding_sats, u8 channel_flags, u32 feerate_per_kw_funding, u32 feerate_per_kw_commitment, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey, u32 lease_expiry, const secp256k1_ecdsa_signature *lease_commit_sig, u32 lease_chan_max_msat, u16 lease_chan_max_ppt) +u8 *towire_dualopend_commit_rcvd(const tal_t *ctx, const struct channel_config *their_config, const struct bitcoin_tx *remote_first_commit, const struct penalty_base *pbase, const struct bitcoin_signature *first_commit_sig, const struct wally_psbt *psbt, const struct pubkey *revocation_basepoint, const struct pubkey *payment_basepoint, const struct pubkey *htlc_basepoint, const struct pubkey *delayed_payment_basepoint, const struct pubkey *their_per_commit_point, const struct pubkey *remote_fundingkey, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshis, struct amount_sat our_funding_sats, u8 channel_flags, u32 feerate_per_kw_funding, u32 feerate_per_kw_commitment, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey, u32 lease_start_blockheight, u32 lease_expiry, const secp256k1_ecdsa_signature *lease_commit_sig, u32 lease_chan_max_msat, u16 lease_chan_max_ppt) { u16 local_shutdown_len = tal_count(local_shutdown_scriptpubkey); u16 remote_shutdown_len = tal_count(remote_shutdown_scriptpubkey); @@ -526,6 +528,7 @@ u8 *towire_dualopend_commit_rcvd(const tal_t *ctx, const struct channel_config * towire_u8_array(&p, local_shutdown_scriptpubkey, local_shutdown_len); towire_u16(&p, remote_shutdown_len); towire_u8_array(&p, remote_shutdown_scriptpubkey, remote_shutdown_len); + towire_u32(&p, lease_start_blockheight); towire_u32(&p, lease_expiry); if (!lease_commit_sig) towire_bool(&p, false); @@ -538,7 +541,7 @@ u8 *towire_dualopend_commit_rcvd(const tal_t *ctx, const struct channel_config * return memcheck(p, tal_count(p)); } -bool fromwire_dualopend_commit_rcvd(const tal_t *ctx, const void *p, struct channel_config *their_config, struct bitcoin_tx **remote_first_commit, struct penalty_base **pbase, struct bitcoin_signature *first_commit_sig, struct wally_psbt **psbt, struct pubkey *revocation_basepoint, struct pubkey *payment_basepoint, struct pubkey *htlc_basepoint, struct pubkey *delayed_payment_basepoint, struct pubkey *their_per_commit_point, struct pubkey *remote_fundingkey, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshis, struct amount_sat *our_funding_sats, u8 *channel_flags, u32 *feerate_per_kw_funding, u32 *feerate_per_kw_commitment, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey, u32 *lease_expiry, secp256k1_ecdsa_signature **lease_commit_sig, u32 *lease_chan_max_msat, u16 *lease_chan_max_ppt) +bool fromwire_dualopend_commit_rcvd(const tal_t *ctx, const void *p, struct channel_config *their_config, struct bitcoin_tx **remote_first_commit, struct penalty_base **pbase, struct bitcoin_signature *first_commit_sig, struct wally_psbt **psbt, struct pubkey *revocation_basepoint, struct pubkey *payment_basepoint, struct pubkey *htlc_basepoint, struct pubkey *delayed_payment_basepoint, struct pubkey *their_per_commit_point, struct pubkey *remote_fundingkey, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshis, struct amount_sat *our_funding_sats, u8 *channel_flags, u32 *feerate_per_kw_funding, u32 *feerate_per_kw_commitment, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey, u32 *lease_start_blockheight, u32 *lease_expiry, secp256k1_ecdsa_signature **lease_commit_sig, u32 *lease_chan_max_msat, u16 *lease_chan_max_ppt) { u16 local_shutdown_len; u16 remote_shutdown_len; @@ -579,6 +582,7 @@ bool fromwire_dualopend_commit_rcvd(const tal_t *ctx, const void *p, struct chan // 2nd case remote_shutdown_scriptpubkey *remote_shutdown_scriptpubkey = remote_shutdown_len ? tal_arr(ctx, u8, remote_shutdown_len) : NULL; fromwire_u8_array(&cursor, &plen, *remote_shutdown_scriptpubkey, remote_shutdown_len); + *lease_start_blockheight = fromwire_u32(&cursor, &plen); *lease_expiry = fromwire_u32(&cursor, &plen); if (!fromwire_bool(&cursor, &plen)) *lease_commit_sig = NULL; @@ -1074,4 +1078,4 @@ bool fromwire_dualopend_validate_lease_reply(const tal_t *ctx, const void *p, wi } return cursor != NULL; } -// SHA256STAMP:ee275d023d9d8ba7e520d321908da0228f76e7ca0d6f76908d17e967177f16c8 +// SHA256STAMP:65d1bedd1e05436c5474d298811fbb9c3fc96ac4e84bef8081c4eee55de286ad diff --git a/openingd/dualopend_wiregen.h b/openingd/dualopend_wiregen.h index d568b6ee3..efbfb40d2 100644 --- a/openingd/dualopend_wiregen.h +++ b/openingd/dualopend_wiregen.h @@ -98,8 +98,8 @@ bool fromwire_dualopend_init(const tal_t *ctx, const void *p, const struct chain /* WIRE: DUALOPEND_REINIT */ /* master-dualopend: peer has reconnected */ -u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_feature_set, const u8 *their_init_features, const struct channel_config *our_config, const struct channel_config *their_config, const struct channel_id *channel_id, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct pubkey *their_funding_pubkey, u32 minimum_depth, const struct bitcoin_txid *funding_txid, u16 funding_txout, u32 most_recent_feerate_per_kw_funding, struct amount_sat funding_satoshi, struct amount_msat our_funding, const struct basepoints *their_basepoints, const struct pubkey *remote_per_commit, const struct wally_psbt *funding_psbt, enum side opener, bool local_funding_locked, bool remote_funding_locked, bool send_shutdown, bool remote_shutdown_received, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey, bool remote_funding_sigs_received, const struct fee_states *fee_states, u8 channel_flags, u32 lease_expiry, const secp256k1_ecdsa_signature *lease_commit_sig, u32 lease_chan_max_msat, u16 lease_chan_max_ppt); -bool fromwire_dualopend_reinit(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_feature_set, u8 **their_init_features, struct channel_config *our_config, struct channel_config *their_config, struct channel_id *channel_id, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct pubkey *their_funding_pubkey, u32 *minimum_depth, struct bitcoin_txid *funding_txid, u16 *funding_txout, u32 *most_recent_feerate_per_kw_funding, struct amount_sat *funding_satoshi, struct amount_msat *our_funding, struct basepoints *their_basepoints, struct pubkey *remote_per_commit, struct wally_psbt **funding_psbt, enum side *opener, bool *local_funding_locked, bool *remote_funding_locked, bool *send_shutdown, bool *remote_shutdown_received, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey, bool *remote_funding_sigs_received, struct fee_states **fee_states, u8 *channel_flags, u32 *lease_expiry, secp256k1_ecdsa_signature **lease_commit_sig, u32 *lease_chan_max_msat, u16 *lease_chan_max_ppt); +u8 *towire_dualopend_reinit(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_feature_set, const u8 *their_init_features, const struct channel_config *our_config, const struct channel_config *their_config, const struct channel_id *channel_id, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct pubkey *their_funding_pubkey, u32 minimum_depth, const struct bitcoin_txid *funding_txid, u16 funding_txout, u32 most_recent_feerate_per_kw_funding, struct amount_sat funding_satoshi, struct amount_msat our_funding, const struct basepoints *their_basepoints, const struct pubkey *remote_per_commit, const struct wally_psbt *funding_psbt, enum side opener, bool local_funding_locked, bool remote_funding_locked, bool send_shutdown, bool remote_shutdown_received, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey, bool remote_funding_sigs_received, const struct fee_states *fee_states, u8 channel_flags, u32 lease_start_blockheight, u32 lease_expiry, const secp256k1_ecdsa_signature *lease_commit_sig, u32 lease_chan_max_msat, u16 lease_chan_max_ppt); +bool fromwire_dualopend_reinit(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_feature_set, u8 **their_init_features, struct channel_config *our_config, struct channel_config *their_config, struct channel_id *channel_id, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct pubkey *their_funding_pubkey, u32 *minimum_depth, struct bitcoin_txid *funding_txid, u16 *funding_txout, u32 *most_recent_feerate_per_kw_funding, struct amount_sat *funding_satoshi, struct amount_msat *our_funding, struct basepoints *their_basepoints, struct pubkey *remote_per_commit, struct wally_psbt **funding_psbt, enum side *opener, bool *local_funding_locked, bool *remote_funding_locked, bool *send_shutdown, bool *remote_shutdown_received, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey, bool *remote_funding_sigs_received, struct fee_states **fee_states, u8 *channel_flags, u32 *lease_start_blockheight, u32 *lease_expiry, secp256k1_ecdsa_signature **lease_commit_sig, u32 *lease_chan_max_msat, u16 *lease_chan_max_ppt); /* WIRE: DUALOPEND_GOT_OFFER */ /* dualopend->master: they offered channel */ @@ -139,8 +139,8 @@ bool fromwire_dualopend_rbf_init(const tal_t *ctx, const void *p, struct amount_ /* WIRE: DUALOPEND_COMMIT_RCVD */ /* dualopend->master: ready to commit channel open to database and */ /* get some signatures for the funding_tx. */ -u8 *towire_dualopend_commit_rcvd(const tal_t *ctx, const struct channel_config *their_config, const struct bitcoin_tx *remote_first_commit, const struct penalty_base *pbase, const struct bitcoin_signature *first_commit_sig, const struct wally_psbt *psbt, const struct pubkey *revocation_basepoint, const struct pubkey *payment_basepoint, const struct pubkey *htlc_basepoint, const struct pubkey *delayed_payment_basepoint, const struct pubkey *their_per_commit_point, const struct pubkey *remote_fundingkey, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshis, struct amount_sat our_funding_sats, u8 channel_flags, u32 feerate_per_kw_funding, u32 feerate_per_kw_commitment, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey, u32 lease_expiry, const secp256k1_ecdsa_signature *lease_commit_sig, u32 lease_chan_max_msat, u16 lease_chan_max_ppt); -bool fromwire_dualopend_commit_rcvd(const tal_t *ctx, const void *p, struct channel_config *their_config, struct bitcoin_tx **remote_first_commit, struct penalty_base **pbase, struct bitcoin_signature *first_commit_sig, struct wally_psbt **psbt, struct pubkey *revocation_basepoint, struct pubkey *payment_basepoint, struct pubkey *htlc_basepoint, struct pubkey *delayed_payment_basepoint, struct pubkey *their_per_commit_point, struct pubkey *remote_fundingkey, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshis, struct amount_sat *our_funding_sats, u8 *channel_flags, u32 *feerate_per_kw_funding, u32 *feerate_per_kw_commitment, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey, u32 *lease_expiry, secp256k1_ecdsa_signature **lease_commit_sig, u32 *lease_chan_max_msat, u16 *lease_chan_max_ppt); +u8 *towire_dualopend_commit_rcvd(const tal_t *ctx, const struct channel_config *their_config, const struct bitcoin_tx *remote_first_commit, const struct penalty_base *pbase, const struct bitcoin_signature *first_commit_sig, const struct wally_psbt *psbt, const struct pubkey *revocation_basepoint, const struct pubkey *payment_basepoint, const struct pubkey *htlc_basepoint, const struct pubkey *delayed_payment_basepoint, const struct pubkey *their_per_commit_point, const struct pubkey *remote_fundingkey, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshis, struct amount_sat our_funding_sats, u8 channel_flags, u32 feerate_per_kw_funding, u32 feerate_per_kw_commitment, const u8 *local_shutdown_scriptpubkey, const u8 *remote_shutdown_scriptpubkey, u32 lease_start_blockheight, u32 lease_expiry, const secp256k1_ecdsa_signature *lease_commit_sig, u32 lease_chan_max_msat, u16 lease_chan_max_ppt); +bool fromwire_dualopend_commit_rcvd(const tal_t *ctx, const void *p, struct channel_config *their_config, struct bitcoin_tx **remote_first_commit, struct penalty_base **pbase, struct bitcoin_signature *first_commit_sig, struct wally_psbt **psbt, struct pubkey *revocation_basepoint, struct pubkey *payment_basepoint, struct pubkey *htlc_basepoint, struct pubkey *delayed_payment_basepoint, struct pubkey *their_per_commit_point, struct pubkey *remote_fundingkey, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshis, struct amount_sat *our_funding_sats, u8 *channel_flags, u32 *feerate_per_kw_funding, u32 *feerate_per_kw_commitment, u8 **local_shutdown_scriptpubkey, u8 **remote_shutdown_scriptpubkey, u32 *lease_start_blockheight, u32 *lease_expiry, secp256k1_ecdsa_signature **lease_commit_sig, u32 *lease_chan_max_msat, u16 *lease_chan_max_ppt); /* WIRE: DUALOPEND_PSBT_CHANGED */ /* dualopend->master: peer updated the psbt */ @@ -237,4 +237,4 @@ bool fromwire_dualopend_validate_lease_reply(const tal_t *ctx, const void *p, wi #endif /* LIGHTNING_OPENINGD_DUALOPEND_WIREGEN_H */ -// SHA256STAMP:ee275d023d9d8ba7e520d321908da0228f76e7ca0d6f76908d17e967177f16c8 +// SHA256STAMP:65d1bedd1e05436c5474d298811fbb9c3fc96ac4e84bef8081c4eee55de286ad diff --git a/openingd/openingd.c b/openingd/openingd.c index 22c07ee27..113210d8c 100644 --- a/openingd/openingd.c +++ b/openingd/openingd.c @@ -510,7 +510,7 @@ static bool funder_finalize_channel_setup(struct state *state, &state->funding_txid, state->funding_txout, state->minimum_depth, - 0, /* No lease lock */ + NULL, 0, /* No channel lease */ state->funding, local_msat, take(new_fee_states(NULL, LOCAL, @@ -1001,7 +1001,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) &state->funding_txid, state->funding_txout, state->minimum_depth, - 0, /* No channel lease */ + NULL, 0, /* No channel lease */ state->funding, state->push_msat, take(new_fee_states(NULL, REMOTE, diff --git a/openingd/openingd_wiregen.c b/openingd/openingd_wiregen.c index 993782631..be6688027 100644 --- a/openingd/openingd_wiregen.c +++ b/openingd/openingd_wiregen.c @@ -604,4 +604,4 @@ bool fromwire_openingd_dev_memleak_reply(const void *p, bool *leak) *leak = fromwire_bool(&cursor, &plen); return cursor != NULL; } -// SHA256STAMP:3dc596105e65c16cc549a7ae739c7e83ed11cce7d7effb206f317522ba741506 +// SHA256STAMP:779aa98c325bc5c87c31b24767f45f22edd135b8e2be4fe3ca1282d91950f0c4 diff --git a/openingd/openingd_wiregen.h b/openingd/openingd_wiregen.h index 949010fdf..d319eb102 100644 --- a/openingd/openingd_wiregen.h +++ b/openingd/openingd_wiregen.h @@ -128,4 +128,4 @@ bool fromwire_openingd_dev_memleak_reply(const void *p, bool *leak); #endif /* LIGHTNING_OPENINGD_OPENINGD_WIREGEN_H */ -// SHA256STAMP:3dc596105e65c16cc549a7ae739c7e83ed11cce7d7effb206f317522ba741506 +// SHA256STAMP:779aa98c325bc5c87c31b24767f45f22edd135b8e2be4fe3ca1282d91950f0c4 diff --git a/tests/fuzz/fuzz-initial_channel.c b/tests/fuzz/fuzz-initial_channel.c index c2e690e58..06e1e89bd 100644 --- a/tests/fuzz/fuzz-initial_channel.c +++ b/tests/fuzz/fuzz-initial_channel.c @@ -34,7 +34,7 @@ void run(const uint8_t *data, size_t size) u32 funding_txout, minimum_depth; struct amount_sat funding, max; struct amount_msat local_msatoshi; - u32 feerate_per_kw; + 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; @@ -51,6 +51,8 @@ void run(const uint8_t *data, size_t size) if (amount_sat_greater(funding, max)) funding = max; feerate_per_kw = fromwire_u32(&data, &size); + blockheight = fromwire_u32(&data, &size); + lease_expiry = fromwire_u32(&data, &size); fromwire_channel_config(&data, &size, &local); fromwire_channel_config(&data, &size, &remote); fromwire_basepoints(&data, &size, &local_basepoints); @@ -66,12 +68,20 @@ void run(const uint8_t *data, size_t size) return; for (enum side opener = 0; opener < NUM_SIDES; opener++) { - channel = new_initial_channel(tmpctx, &cid, &funding_txid, funding_txout, - minimum_depth, funding, local_msatoshi, - take(new_fee_states(NULL, opener, &feerate_per_kw)), - &local, &remote, &local_basepoints, - &remote_basepoints, &local_funding_pubkey, - &remote_funding_pubkey, option_static_remotekey, + channel = new_initial_channel(tmpctx, &cid, &funding_txid, + funding_txout, minimum_depth, + take(new_height_states(NULL, opener, + &blockheight)), + lease_expiry, + funding, local_msatoshi, + take(new_fee_states(NULL, opener, + &feerate_per_kw)), + &local, &remote, + &local_basepoints, + &remote_basepoints, + &local_funding_pubkey, + &remote_funding_pubkey, + option_static_remotekey, option_anchor_outputs, opener); /* TODO: make initial_channel_tx() work with ASAN.. */ diff --git a/tools/generate-wire.py b/tools/generate-wire.py index 38c372d9c..9845c9a0b 100755 --- a/tools/generate-wire.py +++ b/tools/generate-wire.py @@ -231,6 +231,7 @@ class Type(FieldSet): 'bitcoin_tx_output', 'exclude_entry', 'fee_states', + 'height_states', 'onionreply', 'feature_set', 'onionmsg_path', diff --git a/wallet/db.c b/wallet/db.c index 1eb917a9b..472f12923 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -62,6 +62,10 @@ static void fillin_missing_local_basepoints(struct lightningd *ld, struct db *db, const struct migration_context *mc); +static void fillin_missing_channel_blockheights(struct lightningd *ld, + struct db *db, + const struct migration_context *mc); + /* Do not reorder or remove elements from this array, it is used to * migrate existing databases from a previous state, based on the * string indices */ @@ -732,10 +736,18 @@ static struct migration dbmigrations[] = { {SQL("ALTER TABLE channel_funding_inflights ADD lease_chan_max_msat BIGINT DEFAULT NULL"), NULL}, {SQL("ALTER TABLE channel_funding_inflights ADD lease_chan_max_ppt INTEGER DEFAULT NULL"), NULL}, {SQL("ALTER TABLE channel_funding_inflights ADD lease_expiry INTEGER DEFAULT 0"), NULL}, + {SQL("ALTER TABLE channel_funding_inflights ADD lease_blockheight_start INTEGER DEFAULT 0"), NULL}, {SQL("ALTER TABLE channels ADD lease_commit_sig BLOB DEFAULT NULL"), NULL}, {SQL("ALTER TABLE channels ADD lease_chan_max_msat INTEGER DEFAULT NULL"), NULL}, {SQL("ALTER TABLE channels ADD lease_chan_max_ppt INTEGER DEFAULT NULL"), NULL}, {SQL("ALTER TABLE channels ADD lease_expiry INTEGER DEFAULT 0"), NULL}, + {SQL("CREATE TABLE channel_blockheights (" + " channel_id BIGINT REFERENCES channels(id) ON DELETE CASCADE," + " hstate INTEGER," + " blockheight INTEGER," + " UNIQUE (channel_id, hstate)" + ");"), + fillin_missing_channel_blockheights}, }; /* Leak tracking. */ @@ -1428,6 +1440,33 @@ static void fillin_missing_local_basepoints(struct lightningd *ld, tal_free(stmt); } +/* New 'channel_blockheights' table, every existing channel gets a + * 'initial blockheight' of 0 */ +static void fillin_missing_channel_blockheights(struct lightningd *ld, + struct db *db, + const struct migration_context *mc) +{ + struct db_stmt *stmt; + + /* Set all existing channels to 0 */ + /* If we're funder (LOCAL=0): + * Then our blockheight is set last (SENT_ADD_ACK_REVOCATION = 4) */ + stmt = db_prepare_v2(db, + SQL("INSERT INTO channel_blockheights" + " (channel_id, hstate, blockheight)" + " SELECT id, 4, 0 FROM channels" + " WHERE funder = 0;")); + db_exec_prepared_v2(take(stmt)); + /* If they're funder (REMOTE=1): + * Then their blockheight is last (RCVD_ADD_ACK_REVOCATION = 14) */ + stmt = db_prepare_v2(db, + SQL("INSERT INTO channel_blockheights" + " (channel_id, hstate, blockheight)" + " SELECT id, 14, 0 FROM channels" + " WHERE funder = 1;")); + db_exec_prepared_v2(take(stmt)); +} + void migrate_inflight_last_tx_to_psbt(struct lightningd *ld, struct db *db, const struct migration_context *mc) diff --git a/wallet/db_postgres_sqlgen.c b/wallet/db_postgres_sqlgen.c index d6f6abf05..5f945e521 100644 --- a/wallet/db_postgres_sqlgen.c +++ b/wallet/db_postgres_sqlgen.c @@ -980,6 +980,12 @@ struct db_query db_postgres_queries[] = { .placeholders = 0, .readonly = false, }, + { + .name = "ALTER TABLE channel_funding_inflights ADD lease_blockheight_start INTEGER DEFAULT 0", + .query = "ALTER TABLE channel_funding_inflights ADD lease_blockheight_start INTEGER DEFAULT 0", + .placeholders = 0, + .readonly = false, + }, { .name = "ALTER TABLE channels ADD lease_commit_sig BLOB DEFAULT NULL", .query = "ALTER TABLE channels ADD lease_commit_sig BYTEA DEFAULT NULL", @@ -1004,6 +1010,12 @@ struct db_query db_postgres_queries[] = { .placeholders = 0, .readonly = false, }, + { + .name = "CREATE TABLE channel_blockheights ( channel_id BIGINT REFERENCES channels(id) ON DELETE CASCADE, hstate INTEGER, blockheight INTEGER, UNIQUE (channel_id, hstate));", + .query = "CREATE TABLE channel_blockheights ( channel_id BIGINT REFERENCES channels(id) ON DELETE CASCADE, hstate INTEGER, blockheight INTEGER, UNIQUE (channel_id, hstate));", + .placeholders = 0, + .readonly = false, + }, { .name = "UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = ?", .query = "UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = $1", @@ -1100,6 +1112,18 @@ struct db_query db_postgres_queries[] = { .placeholders = 6, .readonly = false, }, + { + .name = "INSERT INTO channel_blockheights (channel_id, hstate, blockheight) SELECT id, 4, 0 FROM channels WHERE funder = 0;", + .query = "INSERT INTO channel_blockheights (channel_id, hstate, blockheight) SELECT id, 4, 0 FROM channels WHERE funder = 0;", + .placeholders = 0, + .readonly = false, + }, + { + .name = "INSERT INTO channel_blockheights (channel_id, hstate, blockheight) SELECT id, 14, 0 FROM channels WHERE funder = 1;", + .query = "INSERT INTO channel_blockheights (channel_id, hstate, blockheight) SELECT id, 14, 0 FROM channels WHERE funder = 1;", + .placeholders = 0, + .readonly = false, + }, { .name = "SELECT c.id, p.node_id, c.fundingkey_remote, inflight.last_tx, inflight.last_sig, inflight.funding_satoshi, inflight.funding_tx_id FROM channels c LEFT OUTER JOIN peers p ON p.id = c.peer_id LEFT OUTER JOIN channel_funding_inflights inflight ON c.id = inflight.channel_id WHERE inflight.last_tx IS NOT NULL;", .query = "SELECT c.id, p.node_id, c.fundingkey_remote, inflight.last_tx, inflight.last_sig, inflight.funding_satoshi, inflight.funding_tx_id FROM channels c LEFT OUTER JOIN peers p ON p.id = c.peer_id LEFT OUTER JOIN channel_funding_inflights inflight ON c.id = inflight.channel_id WHERE inflight.last_tx IS NOT NULL;", @@ -1341,9 +1365,15 @@ struct db_query db_postgres_queries[] = { .readonly = true, }, { - .name = "INSERT INTO channel_funding_inflights ( channel_id, funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);", - .query = "INSERT INTO channel_funding_inflights ( channel_id, funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9);", - .placeholders = 9, + .name = "SELECT hstate, blockheight FROM channel_blockheights WHERE channel_id = ?", + .query = "SELECT hstate, blockheight FROM channel_blockheights WHERE channel_id = $1", + .placeholders = 1, + .readonly = true, + }, + { + .name = "INSERT INTO channel_funding_inflights ( channel_id, funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig, lease_commit_sig, lease_chan_max_msat, lease_chan_max_ppt, lease_expiry, lease_blockheight_start) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", + .query = "INSERT INTO channel_funding_inflights ( channel_id, funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig, lease_commit_sig, lease_chan_max_msat, lease_chan_max_ppt, lease_expiry, lease_blockheight_start) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14);", + .placeholders = 14, .readonly = false, }, { @@ -1359,8 +1389,8 @@ struct db_query db_postgres_queries[] = { .readonly = false, }, { - .name = "SELECT funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig, funding_tx_remote_sigs_received, lease_expiry, lease_commit_sig, lease_chan_max_msat, lease_chan_max_ppt FROM channel_funding_inflights WHERE channel_id = ? ORDER BY funding_feerate", - .query = "SELECT funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig, funding_tx_remote_sigs_received, lease_expiry, lease_commit_sig, lease_chan_max_msat, lease_chan_max_ppt FROM channel_funding_inflights WHERE channel_id = $1 ORDER BY funding_feerate", + .name = "SELECT funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig, funding_tx_remote_sigs_received, lease_expiry, lease_commit_sig, lease_chan_max_msat, lease_chan_max_ppt, lease_blockheight_start FROM channel_funding_inflights WHERE channel_id = ? ORDER BY funding_feerate", + .query = "SELECT funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig, funding_tx_remote_sigs_received, lease_expiry, lease_commit_sig, lease_chan_max_msat, lease_chan_max_ppt, lease_blockheight_start FROM channel_funding_inflights WHERE channel_id = $1 ORDER BY funding_feerate", .placeholders = 1, .readonly = true, }, @@ -1460,6 +1490,18 @@ struct db_query db_postgres_queries[] = { .placeholders = 3, .readonly = false, }, + { + .name = "DELETE FROM channel_blockheights WHERE channel_id=?", + .query = "DELETE FROM channel_blockheights WHERE channel_id=$1", + .placeholders = 1, + .readonly = false, + }, + { + .name = "INSERT INTO channel_blockheights VALUES(?, ?, ?)", + .query = "INSERT INTO channel_blockheights VALUES($1, $2, $3)", + .placeholders = 3, + .readonly = false, + }, { .name = "UPDATE channels SET last_sent_commit=? WHERE id=?", .query = "UPDATE channels SET last_sent_commit=$1 WHERE id=$2", @@ -1966,10 +2008,10 @@ struct db_query db_postgres_queries[] = { }, }; -#define DB_POSTGRES_QUERY_COUNT 326 +#define DB_POSTGRES_QUERY_COUNT 333 #endif /* HAVE_POSTGRES */ #endif /* LIGHTNINGD_WALLET_GEN_DB_POSTGRES */ -// SHA256STAMP:85d581977cc3b124df4c81058cab78f13938dfa0cb4845526bb121e396bcf97d +// SHA256STAMP:1778bd4f49bef247c2b4789d1f7db3542fd606cbe186e299738aecbfbb2d44ae diff --git a/wallet/db_sqlite3_sqlgen.c b/wallet/db_sqlite3_sqlgen.c index b14a92fc9..130e28603 100644 --- a/wallet/db_sqlite3_sqlgen.c +++ b/wallet/db_sqlite3_sqlgen.c @@ -980,6 +980,12 @@ struct db_query db_sqlite3_queries[] = { .placeholders = 0, .readonly = false, }, + { + .name = "ALTER TABLE channel_funding_inflights ADD lease_blockheight_start INTEGER DEFAULT 0", + .query = "ALTER TABLE channel_funding_inflights ADD lease_blockheight_start INTEGER DEFAULT 0", + .placeholders = 0, + .readonly = false, + }, { .name = "ALTER TABLE channels ADD lease_commit_sig BLOB DEFAULT NULL", .query = "ALTER TABLE channels ADD lease_commit_sig BLOB DEFAULT NULL", @@ -1004,6 +1010,12 @@ struct db_query db_sqlite3_queries[] = { .placeholders = 0, .readonly = false, }, + { + .name = "CREATE TABLE channel_blockheights ( channel_id BIGINT REFERENCES channels(id) ON DELETE CASCADE, hstate INTEGER, blockheight INTEGER, UNIQUE (channel_id, hstate));", + .query = "CREATE TABLE channel_blockheights ( channel_id INTEGER REFERENCES channels(id) ON DELETE CASCADE, hstate INTEGER, blockheight INTEGER, UNIQUE (channel_id, hstate));", + .placeholders = 0, + .readonly = false, + }, { .name = "UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = ?", .query = "UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = ?", @@ -1100,6 +1112,18 @@ struct db_query db_sqlite3_queries[] = { .placeholders = 6, .readonly = false, }, + { + .name = "INSERT INTO channel_blockheights (channel_id, hstate, blockheight) SELECT id, 4, 0 FROM channels WHERE funder = 0;", + .query = "INSERT INTO channel_blockheights (channel_id, hstate, blockheight) SELECT id, 4, 0 FROM channels WHERE funder = 0;", + .placeholders = 0, + .readonly = false, + }, + { + .name = "INSERT INTO channel_blockheights (channel_id, hstate, blockheight) SELECT id, 14, 0 FROM channels WHERE funder = 1;", + .query = "INSERT INTO channel_blockheights (channel_id, hstate, blockheight) SELECT id, 14, 0 FROM channels WHERE funder = 1;", + .placeholders = 0, + .readonly = false, + }, { .name = "SELECT c.id, p.node_id, c.fundingkey_remote, inflight.last_tx, inflight.last_sig, inflight.funding_satoshi, inflight.funding_tx_id FROM channels c LEFT OUTER JOIN peers p ON p.id = c.peer_id LEFT OUTER JOIN channel_funding_inflights inflight ON c.id = inflight.channel_id WHERE inflight.last_tx IS NOT NULL;", .query = "SELECT c.id, p.node_id, c.fundingkey_remote, inflight.last_tx, inflight.last_sig, inflight.funding_satoshi, inflight.funding_tx_id FROM channels c LEFT OUTER JOIN peers p ON p.id = c.peer_id LEFT OUTER JOIN channel_funding_inflights inflight ON c.id = inflight.channel_id WHERE inflight.last_tx IS NOT NULL;", @@ -1341,9 +1365,15 @@ struct db_query db_sqlite3_queries[] = { .readonly = true, }, { - .name = "INSERT INTO channel_funding_inflights ( channel_id, funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);", - .query = "INSERT INTO channel_funding_inflights ( channel_id, funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);", - .placeholders = 9, + .name = "SELECT hstate, blockheight FROM channel_blockheights WHERE channel_id = ?", + .query = "SELECT hstate, blockheight FROM channel_blockheights WHERE channel_id = ?", + .placeholders = 1, + .readonly = true, + }, + { + .name = "INSERT INTO channel_funding_inflights ( channel_id, funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig, lease_commit_sig, lease_chan_max_msat, lease_chan_max_ppt, lease_expiry, lease_blockheight_start) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", + .query = "INSERT INTO channel_funding_inflights ( channel_id, funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig, lease_commit_sig, lease_chan_max_msat, lease_chan_max_ppt, lease_expiry, lease_blockheight_start) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", + .placeholders = 14, .readonly = false, }, { @@ -1359,8 +1389,8 @@ struct db_query db_sqlite3_queries[] = { .readonly = false, }, { - .name = "SELECT funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig, funding_tx_remote_sigs_received, lease_expiry, lease_commit_sig, lease_chan_max_msat, lease_chan_max_ppt FROM channel_funding_inflights WHERE channel_id = ? ORDER BY funding_feerate", - .query = "SELECT funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig, funding_tx_remote_sigs_received, lease_expiry, lease_commit_sig, lease_chan_max_msat, lease_chan_max_ppt FROM channel_funding_inflights WHERE channel_id = ? ORDER BY funding_feerate", + .name = "SELECT funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig, funding_tx_remote_sigs_received, lease_expiry, lease_commit_sig, lease_chan_max_msat, lease_chan_max_ppt, lease_blockheight_start FROM channel_funding_inflights WHERE channel_id = ? ORDER BY funding_feerate", + .query = "SELECT funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig, funding_tx_remote_sigs_received, lease_expiry, lease_commit_sig, lease_chan_max_msat, lease_chan_max_ppt, lease_blockheight_start FROM channel_funding_inflights WHERE channel_id = ? ORDER BY funding_feerate", .placeholders = 1, .readonly = true, }, @@ -1460,6 +1490,18 @@ struct db_query db_sqlite3_queries[] = { .placeholders = 3, .readonly = false, }, + { + .name = "DELETE FROM channel_blockheights WHERE channel_id=?", + .query = "DELETE FROM channel_blockheights WHERE channel_id=?", + .placeholders = 1, + .readonly = false, + }, + { + .name = "INSERT INTO channel_blockheights VALUES(?, ?, ?)", + .query = "INSERT INTO channel_blockheights VALUES(?, ?, ?)", + .placeholders = 3, + .readonly = false, + }, { .name = "UPDATE channels SET last_sent_commit=? WHERE id=?", .query = "UPDATE channels SET last_sent_commit=? WHERE id=?", @@ -1966,10 +2008,10 @@ struct db_query db_sqlite3_queries[] = { }, }; -#define DB_SQLITE3_QUERY_COUNT 326 +#define DB_SQLITE3_QUERY_COUNT 333 #endif /* HAVE_SQLITE3 */ #endif /* LIGHTNINGD_WALLET_GEN_DB_SQLITE3 */ -// SHA256STAMP:85d581977cc3b124df4c81058cab78f13938dfa0cb4845526bb121e396bcf97d +// SHA256STAMP:1778bd4f49bef247c2b4789d1f7db3542fd606cbe186e299738aecbfbb2d44ae diff --git a/wallet/statements_gettextgen.po b/wallet/statements_gettextgen.po index d174f8683..225b584cd 100644 --- a/wallet/statements_gettextgen.po +++ b/wallet/statements_gettextgen.po @@ -1,744 +1,760 @@ -#: wallet/db.c:69 +#: wallet/db.c:73 msgid "CREATE TABLE version (version INTEGER)" msgstr "" -#: wallet/db.c:70 +#: wallet/db.c:74 msgid "INSERT INTO version VALUES (1)" msgstr "" -#: wallet/db.c:71 +#: wallet/db.c:75 msgid "CREATE TABLE outputs ( prev_out_tx BLOB, prev_out_index INTEGER, value BIGINT, type INTEGER, status INTEGER, keyindex INTEGER, PRIMARY KEY (prev_out_tx, prev_out_index));" msgstr "" -#: wallet/db.c:80 +#: wallet/db.c:84 msgid "CREATE TABLE vars ( name VARCHAR(32), val VARCHAR(255), PRIMARY KEY (name));" msgstr "" -#: wallet/db.c:86 +#: wallet/db.c:90 msgid "CREATE TABLE shachains ( id BIGSERIAL, min_index BIGINT, num_valid BIGINT, PRIMARY KEY (id));" msgstr "" -#: wallet/db.c:93 +#: wallet/db.c:97 msgid "CREATE TABLE shachain_known ( shachain_id BIGINT REFERENCES shachains(id) ON DELETE CASCADE, pos INTEGER, idx BIGINT, hash BLOB, PRIMARY KEY (shachain_id, pos));" msgstr "" -#: wallet/db.c:101 +#: wallet/db.c:105 msgid "CREATE TABLE peers ( id BIGSERIAL, node_id BLOB UNIQUE, address TEXT, PRIMARY KEY (id));" msgstr "" -#: wallet/db.c:108 +#: wallet/db.c:112 msgid "CREATE TABLE channels ( id BIGSERIAL, peer_id BIGINT REFERENCES peers(id) ON DELETE CASCADE, short_channel_id TEXT, channel_config_local BIGINT, channel_config_remote BIGINT, state INTEGER, funder INTEGER, channel_flags INTEGER, minimum_depth INTEGER, next_index_local BIGINT, next_index_remote BIGINT, next_htlc_id BIGINT, funding_tx_id BLOB, funding_tx_outnum INTEGER, funding_satoshi BIGINT, funding_locked_remote INTEGER, push_msatoshi BIGINT, msatoshi_local BIGINT, fundingkey_remote BLOB, revocation_basepoint_remote BLOB, payment_basepoint_remote BLOB, htlc_basepoint_remote BLOB, delayed_payment_basepoint_remote BLOB, per_commit_remote BLOB, old_per_commit_remote BLOB, local_feerate_per_kw INTEGER, remote_feerate_per_kw INTEGER, shachain_remote_id BIGINT, shutdown_scriptpubkey_remote BLOB, shutdown_keyidx_local BIGINT, last_sent_commit_state BIGINT, last_sent_commit_id INTEGER, last_tx BLOB, last_sig BLOB, closing_fee_received INTEGER, closing_sig_received BLOB, PRIMARY KEY (id));" msgstr "" -#: wallet/db.c:150 +#: wallet/db.c:154 msgid "CREATE TABLE channel_configs ( id BIGSERIAL, dust_limit_satoshis BIGINT, max_htlc_value_in_flight_msat BIGINT, channel_reserve_satoshis BIGINT, htlc_minimum_msat BIGINT, to_self_delay INTEGER, max_accepted_htlcs INTEGER, PRIMARY KEY (id));" msgstr "" -#: wallet/db.c:161 +#: wallet/db.c:165 msgid "CREATE TABLE channel_htlcs ( id BIGSERIAL, channel_id BIGINT REFERENCES channels(id) ON DELETE CASCADE, channel_htlc_id BIGINT, direction INTEGER, origin_htlc BIGINT, msatoshi BIGINT, cltv_expiry INTEGER, payment_hash BLOB, payment_key BLOB, routing_onion BLOB, failuremsg BLOB, malformed_onion INTEGER, hstate INTEGER, shared_secret BLOB, PRIMARY KEY (id), UNIQUE (channel_id, channel_htlc_id, direction));" msgstr "" -#: wallet/db.c:181 +#: wallet/db.c:185 msgid "CREATE TABLE invoices ( id BIGSERIAL, state INTEGER, msatoshi BIGINT, payment_hash BLOB, payment_key BLOB, label TEXT, PRIMARY KEY (id), UNIQUE (label), UNIQUE (payment_hash));" msgstr "" -#: wallet/db.c:193 +#: wallet/db.c:197 msgid "CREATE TABLE payments ( id BIGSERIAL, timestamp INTEGER, status INTEGER, payment_hash BLOB, direction INTEGER, destination BLOB, msatoshi BIGINT, PRIMARY KEY (id), UNIQUE (payment_hash));" msgstr "" -#: wallet/db.c:206 +#: wallet/db.c:210 msgid "ALTER TABLE invoices ADD expiry_time BIGINT;" msgstr "" -#: wallet/db.c:207 +#: wallet/db.c:211 msgid "UPDATE invoices SET expiry_time=9223372036854775807;" msgstr "" -#: wallet/db.c:209 +#: wallet/db.c:213 msgid "ALTER TABLE invoices ADD pay_index BIGINT;" msgstr "" -#: wallet/db.c:210 +#: wallet/db.c:214 msgid "CREATE UNIQUE INDEX invoices_pay_index ON invoices(pay_index);" msgstr "" -#: wallet/db.c:212 +#: wallet/db.c:216 msgid "UPDATE invoices SET pay_index=id WHERE state=1;" msgstr "" -#: wallet/db.c:215 +#: wallet/db.c:219 msgid "INSERT INTO vars(name, val) VALUES('next_pay_index', COALESCE((SELECT MAX(pay_index) FROM invoices WHERE state=1), 0) + 1 );" msgstr "" -#: wallet/db.c:224 +#: wallet/db.c:228 msgid "ALTER TABLE channels ADD first_blocknum BIGINT;" msgstr "" -#: wallet/db.c:225 +#: wallet/db.c:229 msgid "UPDATE channels SET first_blocknum=1 WHERE short_channel_id IS NOT NULL;" msgstr "" -#: wallet/db.c:227 +#: wallet/db.c:231 msgid "ALTER TABLE outputs ADD COLUMN channel_id BIGINT;" msgstr "" -#: wallet/db.c:228 +#: wallet/db.c:232 msgid "ALTER TABLE outputs ADD COLUMN peer_id BLOB;" msgstr "" -#: wallet/db.c:229 +#: wallet/db.c:233 msgid "ALTER TABLE outputs ADD COLUMN commitment_point BLOB;" msgstr "" -#: wallet/db.c:230 +#: wallet/db.c:234 msgid "ALTER TABLE invoices ADD COLUMN msatoshi_received BIGINT;" msgstr "" -#: wallet/db.c:232 +#: wallet/db.c:236 msgid "UPDATE invoices SET msatoshi_received=0 WHERE state=1;" msgstr "" -#: wallet/db.c:233 +#: wallet/db.c:237 msgid "ALTER TABLE channels ADD COLUMN last_was_revoke INTEGER;" msgstr "" -#: wallet/db.c:237 wallet/db.c:530 +#: wallet/db.c:241 wallet/db.c:534 msgid "ALTER TABLE payments RENAME TO temp_payments;" msgstr "" -#: wallet/db.c:238 +#: wallet/db.c:242 msgid "CREATE TABLE payments ( id BIGSERIAL, timestamp INTEGER, status INTEGER, payment_hash BLOB, destination BLOB, msatoshi BIGINT, PRIMARY KEY (id), UNIQUE (payment_hash));" msgstr "" -#: wallet/db.c:249 +#: wallet/db.c:253 msgid "INSERT INTO payments SELECT id, timestamp, status, payment_hash, destination, msatoshi FROM temp_payments WHERE direction=1;" msgstr "" -#: wallet/db.c:252 wallet/db.c:605 +#: wallet/db.c:256 wallet/db.c:609 msgid "DROP TABLE temp_payments;" msgstr "" -#: wallet/db.c:254 +#: wallet/db.c:258 msgid "ALTER TABLE payments ADD COLUMN payment_preimage BLOB;" msgstr "" -#: wallet/db.c:256 +#: wallet/db.c:260 msgid "ALTER TABLE payments ADD COLUMN path_secrets BLOB;" msgstr "" -#: wallet/db.c:259 +#: wallet/db.c:263 msgid "ALTER TABLE invoices ADD paid_timestamp BIGINT;" msgstr "" -#: wallet/db.c:260 +#: wallet/db.c:264 msgid "UPDATE invoices SET paid_timestamp = CURRENT_TIMESTAMP() WHERE state = 1;" msgstr "" -#: wallet/db.c:268 +#: wallet/db.c:272 msgid "ALTER TABLE payments ADD COLUMN route_nodes BLOB;" msgstr "" -#: wallet/db.c:269 +#: wallet/db.c:273 msgid "ALTER TABLE payments ADD COLUMN route_channels BLOB;" msgstr "" -#: wallet/db.c:270 +#: wallet/db.c:274 msgid "CREATE TABLE htlc_sigs (channelid INTEGER REFERENCES channels(id) ON DELETE CASCADE, signature BLOB);" msgstr "" -#: wallet/db.c:273 +#: wallet/db.c:277 msgid "CREATE INDEX channel_idx ON htlc_sigs (channelid)" msgstr "" -#: wallet/db.c:275 +#: wallet/db.c:279 msgid "DELETE FROM channels WHERE state=1" msgstr "" -#: wallet/db.c:277 +#: wallet/db.c:281 msgid "CREATE TABLE db_upgrades (upgrade_from INTEGER, lightning_version TEXT);" msgstr "" -#: wallet/db.c:281 wallet/db.c:471 +#: wallet/db.c:285 wallet/db.c:475 msgid "DELETE FROM peers WHERE id NOT IN (SELECT peer_id FROM channels);" msgstr "" -#: wallet/db.c:285 +#: wallet/db.c:289 msgid "UPDATE channels SET STATE = 8 WHERE state > 8;" msgstr "" -#: wallet/db.c:287 +#: wallet/db.c:291 msgid "ALTER TABLE invoices ADD bolt11 TEXT;" msgstr "" -#: wallet/db.c:291 +#: wallet/db.c:295 msgid "CREATE TABLE blocks (height INT, hash BLOB, prev_hash BLOB, UNIQUE(height));" msgstr "" -#: wallet/db.c:301 +#: wallet/db.c:305 msgid "ALTER TABLE outputs ADD COLUMN confirmation_height INTEGER REFERENCES blocks(height) ON DELETE SET NULL;" msgstr "" -#: wallet/db.c:304 +#: wallet/db.c:308 msgid "ALTER TABLE outputs ADD COLUMN spend_height INTEGER REFERENCES blocks(height) ON DELETE SET NULL;" msgstr "" -#: wallet/db.c:308 +#: wallet/db.c:312 msgid "CREATE INDEX output_height_idx ON outputs (confirmation_height, spend_height);" msgstr "" -#: wallet/db.c:311 +#: wallet/db.c:315 msgid "CREATE TABLE utxoset ( txid BLOB, outnum INT, blockheight INT REFERENCES blocks(height) ON DELETE CASCADE, spendheight INT REFERENCES blocks(height) ON DELETE SET NULL, txindex INT, scriptpubkey BLOB, satoshis BIGINT, PRIMARY KEY(txid, outnum));" msgstr "" -#: wallet/db.c:321 +#: wallet/db.c:325 msgid "CREATE INDEX short_channel_id ON utxoset (blockheight, txindex, outnum)" msgstr "" -#: wallet/db.c:326 +#: wallet/db.c:330 msgid "CREATE INDEX utxoset_spend ON utxoset (spendheight)" msgstr "" -#: wallet/db.c:328 +#: wallet/db.c:332 msgid "UPDATE channels SET shutdown_keyidx_local=0 WHERE shutdown_keyidx_local = -1;" msgstr "" -#: wallet/db.c:334 +#: wallet/db.c:338 msgid "ALTER TABLE payments ADD failonionreply BLOB;" msgstr "" -#: wallet/db.c:336 +#: wallet/db.c:340 msgid "ALTER TABLE payments ADD faildestperm INTEGER;" msgstr "" -#: wallet/db.c:338 +#: wallet/db.c:342 msgid "ALTER TABLE payments ADD failindex INTEGER;" msgstr "" -#: wallet/db.c:340 +#: wallet/db.c:344 msgid "ALTER TABLE payments ADD failcode INTEGER;" msgstr "" -#: wallet/db.c:341 +#: wallet/db.c:345 msgid "ALTER TABLE payments ADD failnode BLOB;" msgstr "" -#: wallet/db.c:342 +#: wallet/db.c:346 msgid "ALTER TABLE payments ADD failchannel TEXT;" msgstr "" -#: wallet/db.c:344 +#: wallet/db.c:348 msgid "ALTER TABLE payments ADD failupdate BLOB;" msgstr "" -#: wallet/db.c:348 +#: wallet/db.c:352 msgid "UPDATE payments SET path_secrets = NULL , route_nodes = NULL , route_channels = NULL WHERE status <> 0;" msgstr "" -#: wallet/db.c:355 +#: wallet/db.c:359 msgid "ALTER TABLE channels ADD in_payments_offered INTEGER DEFAULT 0;" msgstr "" -#: wallet/db.c:356 +#: wallet/db.c:360 msgid "ALTER TABLE channels ADD in_payments_fulfilled INTEGER DEFAULT 0;" msgstr "" -#: wallet/db.c:357 +#: wallet/db.c:361 msgid "ALTER TABLE channels ADD in_msatoshi_offered BIGINT DEFAULT 0;" msgstr "" -#: wallet/db.c:358 +#: wallet/db.c:362 msgid "ALTER TABLE channels ADD in_msatoshi_fulfilled BIGINT DEFAULT 0;" msgstr "" -#: wallet/db.c:359 +#: wallet/db.c:363 msgid "ALTER TABLE channels ADD out_payments_offered INTEGER DEFAULT 0;" msgstr "" -#: wallet/db.c:360 +#: wallet/db.c:364 msgid "ALTER TABLE channels ADD out_payments_fulfilled INTEGER DEFAULT 0;" msgstr "" -#: wallet/db.c:361 +#: wallet/db.c:365 msgid "ALTER TABLE channels ADD out_msatoshi_offered BIGINT DEFAULT 0;" msgstr "" -#: wallet/db.c:362 +#: wallet/db.c:366 msgid "ALTER TABLE channels ADD out_msatoshi_fulfilled BIGINT DEFAULT 0;" msgstr "" -#: wallet/db.c:363 +#: wallet/db.c:367 msgid "UPDATE channels SET in_payments_offered = 0, in_payments_fulfilled = 0 , in_msatoshi_offered = 0, in_msatoshi_fulfilled = 0 , out_payments_offered = 0, out_payments_fulfilled = 0 , out_msatoshi_offered = 0, out_msatoshi_fulfilled = 0 ;" msgstr "" -#: wallet/db.c:372 +#: wallet/db.c:376 msgid "ALTER TABLE payments ADD msatoshi_sent BIGINT;" msgstr "" -#: wallet/db.c:373 +#: wallet/db.c:377 msgid "UPDATE payments SET msatoshi_sent = msatoshi;" msgstr "" -#: wallet/db.c:375 +#: wallet/db.c:379 msgid "DELETE FROM utxoset WHERE blockheight IN ( SELECT DISTINCT(blockheight) FROM utxoset LEFT OUTER JOIN blocks on (blockheight = blocks.height) WHERE blocks.hash IS NULL);" msgstr "" -#: wallet/db.c:383 +#: wallet/db.c:387 msgid "ALTER TABLE channels ADD min_possible_feerate INTEGER;" msgstr "" -#: wallet/db.c:384 +#: wallet/db.c:388 msgid "ALTER TABLE channels ADD max_possible_feerate INTEGER;" msgstr "" -#: wallet/db.c:387 +#: wallet/db.c:391 msgid "UPDATE channels SET min_possible_feerate=0, max_possible_feerate=250000;" msgstr "" -#: wallet/db.c:391 +#: wallet/db.c:395 msgid "ALTER TABLE channels ADD msatoshi_to_us_min BIGINT;" msgstr "" -#: wallet/db.c:392 +#: wallet/db.c:396 msgid "ALTER TABLE channels ADD msatoshi_to_us_max BIGINT;" msgstr "" -#: wallet/db.c:393 +#: wallet/db.c:397 msgid "UPDATE channels SET msatoshi_to_us_min = msatoshi_local , msatoshi_to_us_max = msatoshi_local ;" msgstr "" -#: wallet/db.c:402 +#: wallet/db.c:406 msgid "CREATE TABLE transactions ( id BLOB, blockheight INTEGER REFERENCES blocks(height) ON DELETE SET NULL, txindex INTEGER, rawtx BLOB, PRIMARY KEY (id));" msgstr "" -#: wallet/db.c:411 +#: wallet/db.c:415 msgid "ALTER TABLE payments ADD faildetail TEXT;" msgstr "" -#: wallet/db.c:412 +#: wallet/db.c:416 msgid "UPDATE payments SET faildetail = 'unspecified payment failure reason' WHERE status = 2;" msgstr "" -#: wallet/db.c:417 +#: wallet/db.c:421 msgid "CREATE TABLE channeltxs ( id BIGSERIAL, channel_id BIGINT REFERENCES channels(id) ON DELETE CASCADE, type INTEGER, transaction_id BLOB REFERENCES transactions(id) ON DELETE CASCADE, input_num INTEGER, blockheight INTEGER REFERENCES blocks(height) ON DELETE CASCADE, PRIMARY KEY(id));" msgstr "" -#: wallet/db.c:433 +#: wallet/db.c:437 msgid "DELETE FROM blocks WHERE height > (SELECT MIN(first_blocknum) FROM channels);" msgstr "" -#: wallet/db.c:439 +#: wallet/db.c:443 msgid "INSERT INTO blocks (height) VALUES ((SELECT MIN(first_blocknum) FROM channels)) ON CONFLICT(height) DO NOTHING;" msgstr "" -#: wallet/db.c:443 +#: wallet/db.c:447 msgid "DELETE FROM blocks WHERE height IS NULL;" msgstr "" -#: wallet/db.c:445 +#: wallet/db.c:449 msgid "ALTER TABLE invoices ADD description TEXT;" msgstr "" -#: wallet/db.c:447 +#: wallet/db.c:451 msgid "ALTER TABLE payments ADD description TEXT;" msgstr "" -#: wallet/db.c:449 +#: wallet/db.c:453 msgid "ALTER TABLE channels ADD future_per_commitment_point BLOB;" msgstr "" -#: wallet/db.c:451 +#: wallet/db.c:455 msgid "ALTER TABLE channels ADD last_sent_commit BLOB;" msgstr "" -#: wallet/db.c:456 +#: wallet/db.c:460 msgid "CREATE TABLE forwarded_payments ( in_htlc_id BIGINT REFERENCES channel_htlcs(id) ON DELETE SET NULL, out_htlc_id BIGINT REFERENCES channel_htlcs(id) ON DELETE SET NULL, in_channel_scid BIGINT, out_channel_scid BIGINT, in_msatoshi BIGINT, out_msatoshi BIGINT, state INTEGER, UNIQUE(in_htlc_id, out_htlc_id));" msgstr "" -#: wallet/db.c:468 +#: wallet/db.c:472 msgid "ALTER TABLE payments ADD faildirection INTEGER;" msgstr "" -#: wallet/db.c:473 +#: wallet/db.c:477 msgid "ALTER TABLE outputs ADD scriptpubkey BLOB;" msgstr "" -#: wallet/db.c:475 +#: wallet/db.c:479 msgid "ALTER TABLE payments ADD bolt11 TEXT;" msgstr "" -#: wallet/db.c:477 +#: wallet/db.c:481 msgid "ALTER TABLE channels ADD feerate_base INTEGER;" msgstr "" -#: wallet/db.c:478 +#: wallet/db.c:482 msgid "ALTER TABLE channels ADD feerate_ppm INTEGER;" msgstr "" -#: wallet/db.c:480 +#: wallet/db.c:484 msgid "ALTER TABLE channel_htlcs ADD received_time BIGINT" msgstr "" -#: wallet/db.c:481 +#: wallet/db.c:485 msgid "ALTER TABLE forwarded_payments ADD received_time BIGINT" msgstr "" -#: wallet/db.c:482 +#: wallet/db.c:486 msgid "ALTER TABLE forwarded_payments ADD resolved_time BIGINT" msgstr "" -#: wallet/db.c:483 +#: wallet/db.c:487 msgid "ALTER TABLE channels ADD remote_upfront_shutdown_script BLOB;" msgstr "" -#: wallet/db.c:486 +#: wallet/db.c:490 msgid "ALTER TABLE forwarded_payments ADD failcode INTEGER;" msgstr "" -#: wallet/db.c:488 +#: wallet/db.c:492 msgid "ALTER TABLE channels ADD remote_ann_node_sig BLOB;" msgstr "" -#: wallet/db.c:489 +#: wallet/db.c:493 msgid "ALTER TABLE channels ADD remote_ann_bitcoin_sig BLOB;" msgstr "" -#: wallet/db.c:491 +#: wallet/db.c:495 msgid "ALTER TABLE transactions ADD type BIGINT;" msgstr "" -#: wallet/db.c:496 +#: wallet/db.c:500 msgid "ALTER TABLE transactions ADD channel_id BIGINT;" msgstr "" -#: wallet/db.c:498 +#: wallet/db.c:502 msgid "UPDATE channels SET short_channel_id = REPLACE(short_channel_id, ':', 'x') WHERE short_channel_id IS NOT NULL;" msgstr "" -#: wallet/db.c:501 +#: wallet/db.c:505 msgid "UPDATE payments SET failchannel = REPLACE(failchannel, ':', 'x') WHERE failchannel IS NOT NULL;" msgstr "" -#: wallet/db.c:504 +#: wallet/db.c:508 msgid "ALTER TABLE channels ADD COLUMN option_static_remotekey INTEGER DEFAULT 0;" msgstr "" -#: wallet/db.c:506 +#: wallet/db.c:510 msgid "ALTER TABLE vars ADD COLUMN intval INTEGER" msgstr "" -#: wallet/db.c:507 +#: wallet/db.c:511 msgid "ALTER TABLE vars ADD COLUMN blobval BLOB" msgstr "" -#: wallet/db.c:508 +#: wallet/db.c:512 msgid "UPDATE vars SET intval = CAST(val AS INTEGER) WHERE name IN ('bip32_max_index', 'last_processed_block', 'next_pay_index')" msgstr "" -#: wallet/db.c:509 +#: wallet/db.c:513 msgid "UPDATE vars SET blobval = CAST(val AS BLOB) WHERE name = 'genesis_hash'" msgstr "" -#: wallet/db.c:510 +#: wallet/db.c:514 msgid "CREATE TABLE transaction_annotations ( txid BLOB, idx INTEGER, location INTEGER, type INTEGER, channel BIGINT REFERENCES channels(id), UNIQUE(txid, idx));" msgstr "" -#: wallet/db.c:522 +#: wallet/db.c:526 msgid "ALTER TABLE channels ADD shutdown_scriptpubkey_local BLOB;" msgstr "" -#: wallet/db.c:525 +#: wallet/db.c:529 msgid "UPDATE forwarded_payments SET received_time=0 WHERE received_time IS NULL;" msgstr "" -#: wallet/db.c:527 +#: wallet/db.c:531 msgid "ALTER TABLE invoices ADD COLUMN features BLOB DEFAULT '';" msgstr "" -#: wallet/db.c:531 +#: wallet/db.c:535 msgid "CREATE TABLE payments ( id BIGSERIAL, timestamp INTEGER, status INTEGER, payment_hash BLOB, destination BLOB, msatoshi BIGINT, payment_preimage BLOB, path_secrets BLOB, route_nodes BLOB, route_channels BLOB, failonionreply BLOB, faildestperm INTEGER, failindex INTEGER, failcode INTEGER, failnode BLOB, failchannel TEXT, failupdate BLOB, msatoshi_sent BIGINT, faildetail TEXT, description TEXT, faildirection INTEGER, bolt11 TEXT, total_msat BIGINT, partid BIGINT, PRIMARY KEY (id), UNIQUE (payment_hash, partid))" msgstr "" -#: wallet/db.c:558 +#: wallet/db.c:562 msgid "INSERT INTO payments (id, timestamp, status, payment_hash, destination, msatoshi, payment_preimage, path_secrets, route_nodes, route_channels, failonionreply, faildestperm, failindex, failcode, failnode, failchannel, failupdate, msatoshi_sent, faildetail, description, faildirection, bolt11)SELECT id, timestamp, status, payment_hash, destination, msatoshi, payment_preimage, path_secrets, route_nodes, route_channels, failonionreply, faildestperm, failindex, failcode, failnode, failchannel, failupdate, msatoshi_sent, faildetail, description, faildirection, bolt11 FROM temp_payments;" msgstr "" -#: wallet/db.c:603 +#: wallet/db.c:607 msgid "UPDATE payments SET total_msat = msatoshi;" msgstr "" -#: wallet/db.c:604 +#: wallet/db.c:608 msgid "UPDATE payments SET partid = 0;" msgstr "" -#: wallet/db.c:606 +#: wallet/db.c:610 msgid "ALTER TABLE channel_htlcs ADD partid BIGINT;" msgstr "" -#: wallet/db.c:607 +#: wallet/db.c:611 msgid "UPDATE channel_htlcs SET partid = 0;" msgstr "" -#: wallet/db.c:608 +#: wallet/db.c:612 msgid "CREATE TABLE channel_feerates ( channel_id BIGINT REFERENCES channels(id) ON DELETE CASCADE, hstate INTEGER, feerate_per_kw INTEGER, UNIQUE (channel_id, hstate));" msgstr "" -#: wallet/db.c:619 +#: wallet/db.c:623 msgid "INSERT INTO channel_feerates(channel_id, hstate, feerate_per_kw) SELECT id, 4, local_feerate_per_kw FROM channels WHERE funder = 0;" msgstr "" -#: wallet/db.c:623 +#: wallet/db.c:627 msgid "INSERT INTO channel_feerates(channel_id, hstate, feerate_per_kw) SELECT id, 1, remote_feerate_per_kw FROM channels WHERE funder = 0 and local_feerate_per_kw != remote_feerate_per_kw;" msgstr "" -#: wallet/db.c:628 +#: wallet/db.c:632 msgid "INSERT INTO channel_feerates(channel_id, hstate, feerate_per_kw) SELECT id, 14, remote_feerate_per_kw FROM channels WHERE funder = 1;" msgstr "" -#: wallet/db.c:632 +#: wallet/db.c:636 msgid "INSERT INTO channel_feerates(channel_id, hstate, feerate_per_kw) SELECT id, 11, local_feerate_per_kw FROM channels WHERE funder = 1 and local_feerate_per_kw != remote_feerate_per_kw;" msgstr "" -#: wallet/db.c:636 +#: wallet/db.c:640 msgid "INSERT INTO vars (name, intval) VALUES ('data_version', 0);" msgstr "" -#: wallet/db.c:639 +#: wallet/db.c:643 msgid "ALTER TABLE channel_htlcs ADD localfailmsg BLOB;" msgstr "" -#: wallet/db.c:640 +#: wallet/db.c:644 msgid "UPDATE channel_htlcs SET localfailmsg=decode('2002', 'hex') WHERE malformed_onion != 0 AND direction = 1;" msgstr "" -#: wallet/db.c:641 +#: wallet/db.c:645 msgid "ALTER TABLE channels ADD our_funding_satoshi BIGINT DEFAULT 0;" msgstr "" -#: wallet/db.c:642 +#: wallet/db.c:646 msgid "CREATE TABLE penalty_bases ( channel_id BIGINT REFERENCES channels(id) ON DELETE CASCADE, commitnum BIGINT, txid BLOB, outnum INTEGER, amount BIGINT, PRIMARY KEY (channel_id, commitnum));" msgstr "" -#: wallet/db.c:652 +#: wallet/db.c:656 msgid "ALTER TABLE channel_htlcs ADD we_filled INTEGER;" msgstr "" -#: wallet/db.c:654 +#: wallet/db.c:658 msgid "INSERT INTO vars (name, intval) VALUES ('coin_moves_count', 0);" msgstr "" -#: wallet/db.c:656 +#: wallet/db.c:660 msgid "ALTER TABLE outputs ADD reserved_til INTEGER DEFAULT NULL;" msgstr "" -#: wallet/db.c:659 +#: wallet/db.c:663 msgid "ALTER TABLE channels ADD COLUMN option_anchor_outputs INTEGER DEFAULT 0;" msgstr "" -#: wallet/db.c:662 +#: wallet/db.c:666 msgid "ALTER TABLE outputs ADD option_anchor_outputs INTEGER DEFAULT 0;" msgstr "" -#: wallet/db.c:664 +#: wallet/db.c:668 msgid "ALTER TABLE channels ADD full_channel_id BLOB DEFAULT NULL;" msgstr "" -#: wallet/db.c:665 +#: wallet/db.c:669 msgid "ALTER TABLE channels ADD funding_psbt BLOB DEFAULT NULL;" msgstr "" -#: wallet/db.c:667 +#: wallet/db.c:671 msgid "ALTER TABLE channels ADD closer INTEGER DEFAULT 2;" msgstr "" -#: wallet/db.c:668 +#: wallet/db.c:672 msgid "ALTER TABLE channels ADD state_change_reason INTEGER DEFAULT 0;" msgstr "" -#: wallet/db.c:669 +#: wallet/db.c:673 msgid "CREATE TABLE channel_state_changes ( channel_id BIGINT REFERENCES channels(id) ON DELETE CASCADE, timestamp BIGINT, old_state INTEGER, new_state INTEGER, cause INTEGER, message TEXT);" msgstr "" -#: wallet/db.c:677 +#: wallet/db.c:681 msgid "CREATE TABLE offers ( offer_id BLOB, bolt12 TEXT, label TEXT, status INTEGER, PRIMARY KEY (offer_id));" msgstr "" -#: wallet/db.c:685 +#: wallet/db.c:689 msgid "ALTER TABLE invoices ADD COLUMN local_offer_id BLOB DEFAULT NULL REFERENCES offers(offer_id);" msgstr "" -#: wallet/db.c:687 +#: wallet/db.c:691 msgid "ALTER TABLE payments ADD COLUMN local_offer_id BLOB DEFAULT NULL REFERENCES offers(offer_id);" msgstr "" -#: wallet/db.c:688 +#: wallet/db.c:692 msgid "ALTER TABLE channels ADD funding_tx_remote_sigs_received INTEGER DEFAULT 0;" msgstr "" -#: wallet/db.c:691 +#: wallet/db.c:695 msgid "CREATE INDEX forwarded_payments_out_htlc_id ON forwarded_payments (out_htlc_id);" msgstr "" -#: wallet/db.c:693 +#: wallet/db.c:697 msgid "UPDATE channel_htlcs SET malformed_onion = 0 WHERE malformed_onion IS NULL" msgstr "" -#: wallet/db.c:695 +#: wallet/db.c:699 msgid "CREATE INDEX forwarded_payments_state ON forwarded_payments (state)" msgstr "" -#: wallet/db.c:696 +#: wallet/db.c:700 msgid "CREATE TABLE channel_funding_inflights ( channel_id BIGSERIAL REFERENCES channels(id) ON DELETE CASCADE, funding_tx_id BLOB, funding_tx_outnum INTEGER, funding_feerate INTEGER, funding_satoshi BIGINT, our_funding_satoshi BIGINT, funding_psbt BLOB, last_tx BLOB, last_sig BLOB, funding_tx_remote_sigs_received INTEGER, PRIMARY KEY (channel_id, funding_tx_id));" msgstr "" -#: wallet/db.c:710 +#: wallet/db.c:714 msgid "ALTER TABLE channels ADD revocation_basepoint_local BLOB" msgstr "" -#: wallet/db.c:711 +#: wallet/db.c:715 msgid "ALTER TABLE channels ADD payment_basepoint_local BLOB" msgstr "" -#: wallet/db.c:712 +#: wallet/db.c:716 msgid "ALTER TABLE channels ADD htlc_basepoint_local BLOB" msgstr "" -#: wallet/db.c:713 +#: wallet/db.c:717 msgid "ALTER TABLE channels ADD delayed_payment_basepoint_local BLOB" msgstr "" -#: wallet/db.c:714 +#: wallet/db.c:718 msgid "ALTER TABLE channels ADD funding_pubkey_local BLOB" msgstr "" -#: wallet/db.c:717 +#: wallet/db.c:721 msgid "ALTER TABLE channels ADD shutdown_wrong_txid BLOB DEFAULT NULL" msgstr "" -#: wallet/db.c:718 +#: wallet/db.c:722 msgid "ALTER TABLE channels ADD shutdown_wrong_outnum INTEGER DEFAULT NULL" msgstr "" -#: wallet/db.c:721 +#: wallet/db.c:725 msgid "ALTER TABLE channels ADD local_static_remotekey_start BIGINT DEFAULT 0" msgstr "" -#: wallet/db.c:723 +#: wallet/db.c:727 msgid "ALTER TABLE channels ADD remote_static_remotekey_start BIGINT DEFAULT 0" msgstr "" -#: wallet/db.c:726 +#: wallet/db.c:730 msgid "UPDATE channels SET remote_static_remotekey_start = 9223372036854775807, local_static_remotekey_start = 9223372036854775807 WHERE option_static_remotekey = 0" msgstr "" -#: wallet/db.c:731 +#: wallet/db.c:735 msgid "ALTER TABLE channel_funding_inflights ADD lease_commit_sig BLOB DEFAULT NULL" msgstr "" -#: wallet/db.c:732 +#: wallet/db.c:736 msgid "ALTER TABLE channel_funding_inflights ADD lease_chan_max_msat BIGINT DEFAULT NULL" msgstr "" -#: wallet/db.c:733 +#: wallet/db.c:737 msgid "ALTER TABLE channel_funding_inflights ADD lease_chan_max_ppt INTEGER DEFAULT NULL" msgstr "" -#: wallet/db.c:734 +#: wallet/db.c:738 msgid "ALTER TABLE channel_funding_inflights ADD lease_expiry INTEGER DEFAULT 0" msgstr "" -#: wallet/db.c:735 +#: wallet/db.c:739 +msgid "ALTER TABLE channel_funding_inflights ADD lease_blockheight_start INTEGER DEFAULT 0" +msgstr "" + +#: wallet/db.c:740 msgid "ALTER TABLE channels ADD lease_commit_sig BLOB DEFAULT NULL" msgstr "" -#: wallet/db.c:736 +#: wallet/db.c:741 msgid "ALTER TABLE channels ADD lease_chan_max_msat INTEGER DEFAULT NULL" msgstr "" -#: wallet/db.c:737 +#: wallet/db.c:742 msgid "ALTER TABLE channels ADD lease_chan_max_ppt INTEGER DEFAULT NULL" msgstr "" -#: wallet/db.c:738 +#: wallet/db.c:743 msgid "ALTER TABLE channels ADD lease_expiry INTEGER DEFAULT 0" msgstr "" -#: wallet/db.c:965 +#: wallet/db.c:744 +msgid "CREATE TABLE channel_blockheights ( channel_id BIGINT REFERENCES channels(id) ON DELETE CASCADE, hstate INTEGER, blockheight INTEGER, UNIQUE (channel_id, hstate));" +msgstr "" + +#: wallet/db.c:977 msgid "UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = ?" msgstr "" -#: wallet/db.c:1065 +#: wallet/db.c:1077 msgid "SELECT version FROM version LIMIT 1" msgstr "" -#: wallet/db.c:1127 +#: wallet/db.c:1139 msgid "UPDATE version SET version=?;" msgstr "" -#: wallet/db.c:1135 +#: wallet/db.c:1147 msgid "INSERT INTO db_upgrades VALUES (?, ?);" msgstr "" -#: wallet/db.c:1147 +#: wallet/db.c:1159 msgid "SELECT intval FROM vars WHERE name = 'data_version'" msgstr "" -#: wallet/db.c:1174 +#: wallet/db.c:1186 msgid "SELECT intval FROM vars WHERE name= ? LIMIT 1" msgstr "" -#: wallet/db.c:1190 +#: wallet/db.c:1202 msgid "UPDATE vars SET intval=? WHERE name=?;" msgstr "" -#: wallet/db.c:1199 +#: wallet/db.c:1211 msgid "INSERT INTO vars (name, intval) VALUES (?, ?);" msgstr "" -#: wallet/db.c:1213 +#: wallet/db.c:1225 msgid "UPDATE channels SET feerate_base = ?, feerate_ppm = ?;" msgstr "" -#: wallet/db.c:1234 +#: wallet/db.c:1246 msgid "UPDATE channels SET our_funding_satoshi = funding_satoshi WHERE funder = 0;" msgstr "" -#: wallet/db.c:1250 +#: wallet/db.c:1262 msgid "SELECT type, keyindex, prev_out_tx, prev_out_index, channel_id, peer_id, commitment_point FROM outputs WHERE scriptpubkey IS NULL;" msgstr "" -#: wallet/db.c:1312 +#: wallet/db.c:1324 msgid "UPDATE outputs SET scriptpubkey = ? WHERE prev_out_tx = ? AND prev_out_index = ?" msgstr "" -#: wallet/db.c:1337 +#: wallet/db.c:1349 msgid "SELECT id, funding_tx_id, funding_tx_outnum FROM channels;" msgstr "" -#: wallet/db.c:1356 +#: wallet/db.c:1368 msgid "UPDATE channels SET full_channel_id = ? WHERE id = ?;" msgstr "" -#: wallet/db.c:1377 +#: wallet/db.c:1389 msgid "SELECT channels.id, peers.node_id FROM channels JOIN peers ON (peers.id = channels.peer_id)" msgstr "" -#: wallet/db.c:1410 +#: wallet/db.c:1422 msgid "UPDATE channels SET revocation_basepoint_local = ?, payment_basepoint_local = ?, htlc_basepoint_local = ?, delayed_payment_basepoint_local = ?, funding_pubkey_local = ? WHERE id = ?;" msgstr "" -#: wallet/db.c:1436 +#: wallet/db.c:1455 +msgid "INSERT INTO channel_blockheights (channel_id, hstate, blockheight) SELECT id, 4, 0 FROM channels WHERE funder = 0;" +msgstr "" + +#: wallet/db.c:1463 +msgid "INSERT INTO channel_blockheights (channel_id, hstate, blockheight) SELECT id, 14, 0 FROM channels WHERE funder = 1;" +msgstr "" + +#: wallet/db.c:1475 msgid "SELECT c.id, p.node_id, c.fundingkey_remote, inflight.last_tx, inflight.last_sig, inflight.funding_satoshi, inflight.funding_tx_id FROM channels c LEFT OUTER JOIN peers p ON p.id = c.peer_id LEFT OUTER JOIN channel_funding_inflights inflight ON c.id = inflight.channel_id WHERE inflight.last_tx IS NOT NULL;" msgstr "" -#: wallet/db.c:1503 +#: wallet/db.c:1542 msgid "UPDATE channel_funding_inflights SET last_tx = ? WHERE channel_id = ? AND funding_tx_id = ?;" msgstr "" -#: wallet/db.c:1527 +#: wallet/db.c:1566 msgid "SELECT c.id, p.node_id, c.last_tx, c.funding_satoshi, c.fundingkey_remote, c.last_sig FROM channels c LEFT OUTER JOIN peers p ON p.id = c.peer_id;" msgstr "" -#: wallet/db.c:1594 +#: wallet/db.c:1633 msgid "UPDATE channels SET last_tx = ? WHERE id = ?;" msgstr "" @@ -802,487 +818,499 @@ msgstr "" msgid "SELECT state, payment_key, payment_hash, label, msatoshi, expiry_time, pay_index, msatoshi_received, paid_timestamp, bolt11, description, features, local_offer_id FROM invoices WHERE id = ?;" msgstr "" -#: wallet/wallet.c:65 +#: wallet/wallet.c:66 msgid "SELECT txid, outnum FROM utxoset WHERE spendheight is NULL" msgstr "" -#: wallet/wallet.c:106 wallet/wallet.c:588 +#: wallet/wallet.c:107 wallet/wallet.c:589 msgid "SELECT * from outputs WHERE prev_out_tx=? AND prev_out_index=?" msgstr "" -#: wallet/wallet.c:120 wallet/wallet.c:602 +#: wallet/wallet.c:121 wallet/wallet.c:603 msgid "INSERT INTO outputs ( prev_out_tx, prev_out_index, value, type, status, keyindex, channel_id, peer_id, commitment_point, option_anchor_outputs, confirmation_height, spend_height, scriptpubkey) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:237 +#: wallet/wallet.c:238 msgid "UPDATE outputs SET status=? WHERE status=? AND prev_out_tx=? AND prev_out_index=?" msgstr "" -#: wallet/wallet.c:245 +#: wallet/wallet.c:246 msgid "UPDATE outputs SET status=? WHERE prev_out_tx=? AND prev_out_index=?" msgstr "" -#: wallet/wallet.c:264 +#: wallet/wallet.c:265 msgid "SELECT prev_out_tx, prev_out_index, value, type, status, keyindex, channel_id, peer_id, commitment_point, option_anchor_outputs, confirmation_height, spend_height, scriptpubkey , reserved_til FROM outputs" msgstr "" -#: wallet/wallet.c:281 +#: wallet/wallet.c:282 msgid "SELECT prev_out_tx, prev_out_index, value, type, status, keyindex, channel_id, peer_id, commitment_point, option_anchor_outputs, confirmation_height, spend_height, scriptpubkey , reserved_til FROM outputs WHERE status= ? " msgstr "" -#: wallet/wallet.c:319 +#: wallet/wallet.c:320 msgid "SELECT prev_out_tx, prev_out_index, value, type, status, keyindex, channel_id, peer_id, commitment_point, option_anchor_outputs, confirmation_height, spend_height, scriptpubkey, reserved_til FROM outputs WHERE channel_id IS NOT NULL AND confirmation_height IS NULL" msgstr "" -#: wallet/wallet.c:356 +#: wallet/wallet.c:357 msgid "SELECT prev_out_tx, prev_out_index, value, type, status, keyindex, channel_id, peer_id, commitment_point, option_anchor_outputs, confirmation_height, spend_height, scriptpubkey, reserved_til FROM outputs WHERE prev_out_tx = ? AND prev_out_index = ?" msgstr "" -#: wallet/wallet.c:448 +#: wallet/wallet.c:449 msgid "UPDATE outputs SET status=?, reserved_til=? WHERE prev_out_tx=? AND prev_out_index=?" msgstr "" -#: wallet/wallet.c:537 +#: wallet/wallet.c:538 msgid "SELECT prev_out_tx, prev_out_index, value, type, status, keyindex, channel_id, peer_id, commitment_point, option_anchor_outputs, confirmation_height, spend_height, scriptpubkey , reserved_til FROM outputs WHERE status = ? OR (status = ? AND reserved_til <= ?)ORDER BY RANDOM();" msgstr "" -#: wallet/wallet.c:706 +#: wallet/wallet.c:707 msgid "INSERT INTO shachains (min_index, num_valid) VALUES (?, 0);" msgstr "" -#: wallet/wallet.c:750 +#: wallet/wallet.c:751 msgid "UPDATE shachains SET num_valid=?, min_index=? WHERE id=?" msgstr "" -#: wallet/wallet.c:757 +#: wallet/wallet.c:758 msgid "UPDATE shachain_known SET idx=?, hash=? WHERE shachain_id=? AND pos=?" msgstr "" -#: wallet/wallet.c:769 +#: wallet/wallet.c:770 msgid "INSERT INTO shachain_known (shachain_id, pos, idx, hash) VALUES (?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:791 +#: wallet/wallet.c:792 msgid "SELECT min_index, num_valid FROM shachains WHERE id=?" msgstr "" -#: wallet/wallet.c:806 +#: wallet/wallet.c:807 msgid "SELECT idx, hash, pos FROM shachain_known WHERE shachain_id=?" msgstr "" -#: wallet/wallet.c:829 +#: wallet/wallet.c:830 msgid "SELECT id, node_id, address FROM peers WHERE id=?;" msgstr "" -#: wallet/wallet.c:862 +#: wallet/wallet.c:863 msgid "SELECT signature FROM htlc_sigs WHERE channelid = ?" msgstr "" -#: wallet/wallet.c:896 +#: wallet/wallet.c:897 msgid "SELECT remote_ann_node_sig, remote_ann_bitcoin_sig FROM channels WHERE id = ?" msgstr "" -#: wallet/wallet.c:940 +#: wallet/wallet.c:941 msgid "SELECT hstate, feerate_per_kw FROM channel_feerates WHERE channel_id = ?" msgstr "" -#: wallet/wallet.c:973 -msgid "INSERT INTO channel_funding_inflights ( channel_id, funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);" +#: wallet/wallet.c:977 +msgid "SELECT hstate, blockheight FROM channel_blockheights WHERE channel_id = ?" msgstr "" -#: wallet/wallet.c:1008 +#: wallet/wallet.c:1010 +msgid "INSERT INTO channel_funding_inflights ( channel_id, funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig, lease_commit_sig, lease_chan_max_msat, lease_chan_max_ppt, lease_expiry, lease_blockheight_start) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" +msgstr "" + +#: wallet/wallet.c:1066 msgid "UPDATE channel_funding_inflights SET funding_psbt=?, funding_tx_remote_sigs_received=? WHERE channel_id=? AND funding_tx_id=? AND funding_tx_outnum=?" msgstr "" -#: wallet/wallet.c:1031 +#: wallet/wallet.c:1089 msgid "DELETE FROM channel_funding_inflights WHERE channel_id = ?" msgstr "" -#: wallet/wallet.c:1098 -msgid "SELECT funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig, funding_tx_remote_sigs_received, lease_expiry, lease_commit_sig, lease_chan_max_msat, lease_chan_max_ppt FROM channel_funding_inflights WHERE channel_id = ? ORDER BY funding_feerate" +#: wallet/wallet.c:1159 +msgid "SELECT funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig, funding_tx_remote_sigs_received, lease_expiry, lease_commit_sig, lease_chan_max_msat, lease_chan_max_ppt, lease_blockheight_start FROM channel_funding_inflights WHERE channel_id = ? ORDER BY funding_feerate" msgstr "" -#: wallet/wallet.c:1350 +#: wallet/wallet.c:1427 msgid "SELECT id FROM channels ORDER BY id DESC LIMIT 1;" msgstr "" -#: wallet/wallet.c:1367 +#: wallet/wallet.c:1444 msgid "SELECT id, peer_id, short_channel_id, full_channel_id, channel_config_local, channel_config_remote, state, funder, channel_flags, minimum_depth, next_index_local, next_index_remote, next_htlc_id, funding_tx_id, funding_tx_outnum, funding_satoshi, our_funding_satoshi, funding_locked_remote, push_msatoshi, msatoshi_local, fundingkey_remote, revocation_basepoint_remote, payment_basepoint_remote, htlc_basepoint_remote, delayed_payment_basepoint_remote, per_commit_remote, old_per_commit_remote, local_feerate_per_kw, remote_feerate_per_kw, shachain_remote_id, shutdown_scriptpubkey_remote, shutdown_keyidx_local, last_sent_commit_state, last_sent_commit_id, last_tx, last_sig, last_was_revoke, first_blocknum, min_possible_feerate, max_possible_feerate, msatoshi_to_us_min, msatoshi_to_us_max, future_per_commitment_point, last_sent_commit, feerate_base, feerate_ppm, remote_upfront_shutdown_script, local_static_remotekey_start, remote_static_remotekey_start, option_anchor_outputs, shutdown_scriptpubkey_local, closer, state_change_reason, revocation_basepoint_local, payment_basepoint_local, htlc_basepoint_local, delayed_payment_basepoint_local, funding_pubkey_local, shutdown_wrong_txid, shutdown_wrong_outnum, lease_expiry, lease_commit_sig, lease_chan_max_msat, lease_chan_max_ppt FROM channels WHERE state != ?;" msgstr "" -#: wallet/wallet.c:1479 +#: wallet/wallet.c:1556 msgid "UPDATE channels SET in_payments_offered = COALESCE(in_payments_offered, 0) + 1 , in_msatoshi_offered = COALESCE(in_msatoshi_offered, 0) + ? WHERE id = ?;" msgstr "" -#: wallet/wallet.c:1485 +#: wallet/wallet.c:1562 msgid "UPDATE channels SET in_payments_fulfilled = COALESCE(in_payments_fulfilled, 0) + 1 , in_msatoshi_fulfilled = COALESCE(in_msatoshi_fulfilled, 0) + ? WHERE id = ?;" msgstr "" -#: wallet/wallet.c:1491 +#: wallet/wallet.c:1568 msgid "UPDATE channels SET out_payments_offered = COALESCE(out_payments_offered, 0) + 1 , out_msatoshi_offered = COALESCE(out_msatoshi_offered, 0) + ? WHERE id = ?;" msgstr "" -#: wallet/wallet.c:1497 +#: wallet/wallet.c:1574 msgid "UPDATE channels SET out_payments_fulfilled = COALESCE(out_payments_fulfilled, 0) + 1 , out_msatoshi_fulfilled = COALESCE(out_msatoshi_fulfilled, 0) + ? WHERE id = ?;" msgstr "" -#: wallet/wallet.c:1542 +#: wallet/wallet.c:1619 msgid "SELECT in_payments_offered, in_payments_fulfilled, in_msatoshi_offered, in_msatoshi_fulfilled, out_payments_offered, out_payments_fulfilled, out_msatoshi_offered, out_msatoshi_fulfilled FROM channels WHERE id = ?" msgstr "" -#: wallet/wallet.c:1571 +#: wallet/wallet.c:1648 msgid "SELECT MIN(height), MAX(height) FROM blocks;" msgstr "" -#: wallet/wallet.c:1593 +#: wallet/wallet.c:1670 msgid "INSERT INTO channel_configs DEFAULT VALUES;" msgstr "" -#: wallet/wallet.c:1605 +#: wallet/wallet.c:1682 msgid "UPDATE channel_configs SET dust_limit_satoshis=?, max_htlc_value_in_flight_msat=?, channel_reserve_satoshis=?, htlc_minimum_msat=?, to_self_delay=?, max_accepted_htlcs=? WHERE id=?;" msgstr "" -#: wallet/wallet.c:1629 +#: wallet/wallet.c:1706 msgid "SELECT id, dust_limit_satoshis, max_htlc_value_in_flight_msat, channel_reserve_satoshis, htlc_minimum_msat, to_self_delay, max_accepted_htlcs FROM channel_configs WHERE id= ? ;" msgstr "" -#: wallet/wallet.c:1663 +#: wallet/wallet.c:1740 msgid "UPDATE channels SET remote_ann_node_sig=?, remote_ann_bitcoin_sig=? WHERE id=?" msgstr "" -#: wallet/wallet.c:1682 +#: wallet/wallet.c:1759 msgid "UPDATE channels SET shachain_remote_id=?, short_channel_id=?, full_channel_id=?, state=?, funder=?, channel_flags=?, minimum_depth=?, next_index_local=?, next_index_remote=?, next_htlc_id=?, funding_tx_id=?, funding_tx_outnum=?, funding_satoshi=?, our_funding_satoshi=?, funding_locked_remote=?, push_msatoshi=?, msatoshi_local=?, shutdown_scriptpubkey_remote=?, shutdown_keyidx_local=?, channel_config_local=?, last_tx=?, last_sig=?, last_was_revoke=?, min_possible_feerate=?, max_possible_feerate=?, msatoshi_to_us_min=?, msatoshi_to_us_max=?, feerate_base=?, feerate_ppm=?, remote_upfront_shutdown_script=?, local_static_remotekey_start=?, remote_static_remotekey_start=?, option_anchor_outputs=?, shutdown_scriptpubkey_local=?, closer=?, state_change_reason=?, shutdown_wrong_txid=?, shutdown_wrong_outnum=?, lease_expiry=?, lease_commit_sig=?, lease_chan_max_msat=?, lease_chan_max_ppt=? WHERE id=?" msgstr "" -#: wallet/wallet.c:1791 +#: wallet/wallet.c:1868 msgid "UPDATE channels SET fundingkey_remote=?, revocation_basepoint_remote=?, payment_basepoint_remote=?, htlc_basepoint_remote=?, delayed_payment_basepoint_remote=?, per_commit_remote=?, old_per_commit_remote=?, channel_config_remote=?, future_per_commitment_point=? WHERE id=?" msgstr "" -#: wallet/wallet.c:1818 +#: wallet/wallet.c:1895 msgid "DELETE FROM channel_feerates WHERE channel_id=?" msgstr "" -#: wallet/wallet.c:1828 +#: wallet/wallet.c:1905 msgid "INSERT INTO channel_feerates VALUES(?, ?, ?)" msgstr "" -#: wallet/wallet.c:1845 +#: wallet/wallet.c:1914 +msgid "DELETE FROM channel_blockheights WHERE channel_id=?" +msgstr "" + +#: wallet/wallet.c:1924 +msgid "INSERT INTO channel_blockheights VALUES(?, ?, ?)" +msgstr "" + +#: wallet/wallet.c:1941 msgid "UPDATE channels SET last_sent_commit=? WHERE id=?" msgstr "" -#: wallet/wallet.c:1868 +#: wallet/wallet.c:1964 msgid "INSERT INTO channel_state_changes ( channel_id, timestamp, old_state, new_state, cause, message) VALUES (?, ?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:1896 +#: wallet/wallet.c:1992 msgid "SELECT timestamp, old_state, new_state, cause, message FROM channel_state_changes WHERE channel_id = ? ORDER BY timestamp ASC;" msgstr "" -#: wallet/wallet.c:1925 +#: wallet/wallet.c:2021 msgid "SELECT id FROM peers WHERE node_id = ?" msgstr "" -#: wallet/wallet.c:1937 +#: wallet/wallet.c:2033 msgid "UPDATE peers SET address = ? WHERE id = ?" msgstr "" -#: wallet/wallet.c:1946 +#: wallet/wallet.c:2042 msgid "INSERT INTO peers (node_id, address) VALUES (?, ?);" msgstr "" -#: wallet/wallet.c:1967 +#: wallet/wallet.c:2063 msgid "INSERT INTO channels ( peer_id, first_blocknum, id, revocation_basepoint_local, payment_basepoint_local, htlc_basepoint_local, delayed_payment_basepoint_local, funding_pubkey_local) VALUES (?, ?, ?, ?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:2008 +#: wallet/wallet.c:2104 msgid "DELETE FROM channel_htlcs WHERE channel_id=?" msgstr "" -#: wallet/wallet.c:2014 +#: wallet/wallet.c:2110 msgid "DELETE FROM htlc_sigs WHERE channelid=?" msgstr "" -#: wallet/wallet.c:2020 +#: wallet/wallet.c:2116 msgid "DELETE FROM channeltxs WHERE channel_id=?" msgstr "" -#: wallet/wallet.c:2027 +#: wallet/wallet.c:2123 msgid "DELETE FROM channel_funding_inflights WHERE channel_id=?" msgstr "" -#: wallet/wallet.c:2033 +#: wallet/wallet.c:2129 msgid "DELETE FROM shachains WHERE id IN ( SELECT shachain_remote_id FROM channels WHERE channels.id=?)" msgstr "" -#: wallet/wallet.c:2043 +#: wallet/wallet.c:2139 msgid "UPDATE channels SET state=?, peer_id=? WHERE channels.id=?" msgstr "" -#: wallet/wallet.c:2057 +#: wallet/wallet.c:2153 msgid "SELECT * FROM channels WHERE peer_id = ?;" msgstr "" -#: wallet/wallet.c:2065 +#: wallet/wallet.c:2161 msgid "DELETE FROM peers WHERE id=?" msgstr "" -#: wallet/wallet.c:2076 +#: wallet/wallet.c:2172 msgid "UPDATE outputs SET confirmation_height = ? WHERE prev_out_tx = ?" msgstr "" -#: wallet/wallet.c:2179 +#: wallet/wallet.c:2275 msgid "INSERT INTO channel_htlcs ( channel_id, channel_htlc_id, direction, msatoshi, cltv_expiry, payment_hash, payment_key, hstate, shared_secret, routing_onion, received_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:2232 +#: wallet/wallet.c:2328 msgid "INSERT INTO channel_htlcs ( channel_id, channel_htlc_id, direction, origin_htlc, msatoshi, cltv_expiry, payment_hash, payment_key, hstate, routing_onion, malformed_onion, partid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?);" msgstr "" -#: wallet/wallet.c:2293 +#: wallet/wallet.c:2389 msgid "UPDATE channel_htlcs SET hstate=?, payment_key=?, malformed_onion=?, failuremsg=?, localfailmsg=?, we_filled=? WHERE id=?" msgstr "" -#: wallet/wallet.c:2510 +#: wallet/wallet.c:2606 msgid "SELECT id, channel_htlc_id, msatoshi, cltv_expiry, hstate, payment_hash, payment_key, routing_onion, failuremsg, malformed_onion, origin_htlc, shared_secret, received_time, we_filled FROM channel_htlcs WHERE direction= ? AND channel_id= ? AND hstate != ?" msgstr "" -#: wallet/wallet.c:2557 +#: wallet/wallet.c:2653 msgid "SELECT id, channel_htlc_id, msatoshi, cltv_expiry, hstate, payment_hash, payment_key, routing_onion, failuremsg, malformed_onion, origin_htlc, shared_secret, received_time, partid, localfailmsg FROM channel_htlcs WHERE direction = ? AND channel_id = ? AND hstate != ?" msgstr "" -#: wallet/wallet.c:2688 +#: wallet/wallet.c:2784 msgid "SELECT channel_id, direction, cltv_expiry, channel_htlc_id, payment_hash FROM channel_htlcs WHERE channel_id = ?;" msgstr "" -#: wallet/wallet.c:2722 +#: wallet/wallet.c:2818 msgid "DELETE FROM channel_htlcs WHERE direction = ? AND origin_htlc = ? AND payment_hash = ? AND partid = ?;" msgstr "" -#: wallet/wallet.c:2775 +#: wallet/wallet.c:2871 msgid "SELECT status FROM payments WHERE payment_hash=? AND partid = ?;" msgstr "" -#: wallet/wallet.c:2793 +#: wallet/wallet.c:2889 msgid "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid, local_offer_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:2882 +#: wallet/wallet.c:2978 msgid "DELETE FROM payments WHERE payment_hash = ? AND partid = ?" msgstr "" -#: wallet/wallet.c:2896 +#: wallet/wallet.c:2992 msgid "DELETE FROM payments WHERE payment_hash = ?" msgstr "" -#: wallet/wallet.c:2997 +#: wallet/wallet.c:3093 msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ? AND partid = ?" msgstr "" -#: wallet/wallet.c:3047 +#: wallet/wallet.c:3143 msgid "UPDATE payments SET status=? WHERE payment_hash=? AND partid=?" msgstr "" -#: wallet/wallet.c:3057 +#: wallet/wallet.c:3153 msgid "UPDATE payments SET payment_preimage=? WHERE payment_hash=? AND partid=?" msgstr "" -#: wallet/wallet.c:3067 +#: wallet/wallet.c:3163 msgid "UPDATE payments SET path_secrets = NULL , route_nodes = NULL , route_channels = NULL WHERE payment_hash = ? AND partid = ?;" msgstr "" -#: wallet/wallet.c:3099 +#: wallet/wallet.c:3195 msgid "SELECT failonionreply, faildestperm, failindex, failcode, failnode, failchannel, failupdate, faildetail, faildirection FROM payments WHERE payment_hash=? AND partid=?;" msgstr "" -#: wallet/wallet.c:3166 +#: wallet/wallet.c:3262 msgid "UPDATE payments SET failonionreply=? , faildestperm=? , failindex=? , failcode=? , failnode=? , failchannel=? , failupdate=? , faildetail=? , faildirection=? WHERE payment_hash=? AND partid=?;" msgstr "" -#: wallet/wallet.c:3225 +#: wallet/wallet.c:3321 msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ? ORDER BY id;" msgstr "" -#: wallet/wallet.c:3248 +#: wallet/wallet.c:3344 msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments ORDER BY id;" msgstr "" -#: wallet/wallet.c:3299 +#: wallet/wallet.c:3395 msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE local_offer_id = ?;" msgstr "" -#: wallet/wallet.c:3344 +#: wallet/wallet.c:3440 msgid "DELETE FROM htlc_sigs WHERE channelid = ?" msgstr "" -#: wallet/wallet.c:3351 +#: wallet/wallet.c:3447 msgid "INSERT INTO htlc_sigs (channelid, signature) VALUES (?, ?)" msgstr "" -#: wallet/wallet.c:3363 +#: wallet/wallet.c:3459 msgid "SELECT blobval FROM vars WHERE name='genesis_hash'" msgstr "" -#: wallet/wallet.c:3387 +#: wallet/wallet.c:3483 msgid "INSERT INTO vars (name, blobval) VALUES ('genesis_hash', ?);" msgstr "" -#: wallet/wallet.c:3405 +#: wallet/wallet.c:3501 msgid "SELECT txid, outnum FROM utxoset WHERE spendheight < ?" msgstr "" -#: wallet/wallet.c:3417 +#: wallet/wallet.c:3513 msgid "DELETE FROM utxoset WHERE spendheight < ?" msgstr "" -#: wallet/wallet.c:3425 wallet/wallet.c:3539 +#: wallet/wallet.c:3521 wallet/wallet.c:3635 msgid "INSERT INTO blocks (height, hash, prev_hash) VALUES (?, ?, ?);" msgstr "" -#: wallet/wallet.c:3444 +#: wallet/wallet.c:3540 msgid "DELETE FROM blocks WHERE hash = ?" msgstr "" -#: wallet/wallet.c:3450 +#: wallet/wallet.c:3546 msgid "SELECT * FROM blocks WHERE height >= ?;" msgstr "" -#: wallet/wallet.c:3459 +#: wallet/wallet.c:3555 msgid "DELETE FROM blocks WHERE height > ?" msgstr "" -#: wallet/wallet.c:3471 +#: wallet/wallet.c:3567 msgid "UPDATE outputs SET spend_height = ?, status = ? WHERE prev_out_tx = ? AND prev_out_index = ?" msgstr "" -#: wallet/wallet.c:3489 +#: wallet/wallet.c:3585 msgid "UPDATE utxoset SET spendheight = ? WHERE txid = ? AND outnum = ?" msgstr "" -#: wallet/wallet.c:3512 wallet/wallet.c:3550 +#: wallet/wallet.c:3608 wallet/wallet.c:3646 msgid "INSERT INTO utxoset ( txid, outnum, blockheight, spendheight, txindex, scriptpubkey, satoshis) VALUES(?, ?, ?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:3576 +#: wallet/wallet.c:3672 msgid "SELECT height FROM blocks WHERE height = ?" msgstr "" -#: wallet/wallet.c:3589 +#: wallet/wallet.c:3685 msgid "SELECT txid, spendheight, scriptpubkey, satoshis FROM utxoset WHERE blockheight = ? AND txindex = ? AND outnum = ? AND spendheight IS NULL" msgstr "" -#: wallet/wallet.c:3631 +#: wallet/wallet.c:3727 msgid "SELECT blockheight, txindex, outnum FROM utxoset WHERE spendheight = ?" msgstr "" -#: wallet/wallet.c:3662 wallet/wallet.c:3822 +#: wallet/wallet.c:3758 wallet/wallet.c:3918 msgid "SELECT blockheight FROM transactions WHERE id=?" msgstr "" -#: wallet/wallet.c:3672 +#: wallet/wallet.c:3768 msgid "INSERT INTO transactions ( id, blockheight, txindex, rawtx) VALUES (?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:3693 +#: wallet/wallet.c:3789 msgid "UPDATE transactions SET blockheight = ?, txindex = ? WHERE id = ?" msgstr "" -#: wallet/wallet.c:3710 +#: wallet/wallet.c:3806 msgid "INSERT INTO transaction_annotations (txid, idx, location, type, channel) VALUES (?, ?, ?, ?, ?) ON CONFLICT(txid,idx) DO NOTHING;" msgstr "" -#: wallet/wallet.c:3742 +#: wallet/wallet.c:3838 msgid "SELECT type, channel_id FROM transactions WHERE id=?" msgstr "" -#: wallet/wallet.c:3758 +#: wallet/wallet.c:3854 msgid "UPDATE transactions SET type = ?, channel_id = ? WHERE id = ?" msgstr "" -#: wallet/wallet.c:3777 +#: wallet/wallet.c:3873 msgid "SELECT type FROM transactions WHERE id=?" msgstr "" -#: wallet/wallet.c:3800 +#: wallet/wallet.c:3896 msgid "SELECT rawtx FROM transactions WHERE id=?" msgstr "" -#: wallet/wallet.c:3846 +#: wallet/wallet.c:3942 msgid "SELECT blockheight, txindex FROM transactions WHERE id=?" msgstr "" -#: wallet/wallet.c:3874 +#: wallet/wallet.c:3970 msgid "SELECT id FROM transactions WHERE blockheight=?" msgstr "" -#: wallet/wallet.c:3893 +#: wallet/wallet.c:3989 msgid "INSERT INTO channeltxs ( channel_id, type, transaction_id, input_num, blockheight) VALUES (?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:3917 +#: wallet/wallet.c:4013 msgid "SELECT DISTINCT(channel_id) FROM channeltxs WHERE type = ?;" msgstr "" -#: wallet/wallet.c:3938 +#: wallet/wallet.c:4034 msgid "SELECT c.type, c.blockheight, t.rawtx, c.input_num, c.blockheight - t.blockheight + 1 AS depth, t.id as txid FROM channeltxs c JOIN transactions t ON t.id = c.transaction_id WHERE c.channel_id = ? ORDER BY c.id ASC;" msgstr "" -#: wallet/wallet.c:3983 +#: wallet/wallet.c:4079 msgid "UPDATE forwarded_payments SET in_msatoshi=?, out_msatoshi=?, state=?, resolved_time=?, failcode=? WHERE in_htlc_id=?" msgstr "" -#: wallet/wallet.c:4041 +#: wallet/wallet.c:4137 msgid "INSERT INTO forwarded_payments ( in_htlc_id, out_htlc_id, in_channel_scid, out_channel_scid, in_msatoshi, out_msatoshi, state, received_time, resolved_time, failcode) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:4100 +#: wallet/wallet.c:4196 msgid "SELECT CAST(COALESCE(SUM(in_msatoshi - out_msatoshi), 0) AS BIGINT)FROM forwarded_payments WHERE state = ?;" msgstr "" -#: wallet/wallet.c:4149 +#: wallet/wallet.c:4245 msgid "SELECT f.state, in_msatoshi, out_msatoshi, hin.payment_hash as payment_hash, in_channel_scid, out_channel_scid, f.received_time, f.resolved_time, f.failcode FROM forwarded_payments f LEFT JOIN channel_htlcs hin ON (f.in_htlc_id = hin.id) WHERE (1 = ? OR f.state = ?) AND (1 = ? OR f.in_channel_scid = ?) AND (1 = ? OR f.out_channel_scid = ?)" msgstr "" -#: wallet/wallet.c:4271 +#: wallet/wallet.c:4367 msgid "SELECT t.id, t.rawtx, t.blockheight, t.txindex, t.type as txtype, c2.short_channel_id as txchan, a.location, a.idx as ann_idx, a.type as annotation_type, c.short_channel_id FROM transactions t LEFT JOIN transaction_annotations a ON (a.txid = t.id) LEFT JOIN channels c ON (a.channel = c.id) LEFT JOIN channels c2 ON (t.channel_id = c2.id) ORDER BY t.blockheight, t.txindex ASC" msgstr "" -#: wallet/wallet.c:4365 +#: wallet/wallet.c:4461 msgid "INSERT INTO penalty_bases ( channel_id, commitnum, txid, outnum, amount) VALUES (?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:4390 +#: wallet/wallet.c:4486 msgid "SELECT commitnum, txid, outnum, amount FROM penalty_bases WHERE channel_id = ?" msgstr "" -#: wallet/wallet.c:4414 +#: wallet/wallet.c:4510 msgid "DELETE FROM penalty_bases WHERE channel_id = ? AND commitnum = ?" msgstr "" -#: wallet/wallet.c:4432 +#: wallet/wallet.c:4528 msgid "SELECT 1 FROM offers WHERE offer_id = ?;" msgstr "" -#: wallet/wallet.c:4445 +#: wallet/wallet.c:4541 msgid "INSERT INTO offers ( offer_id, bolt12, label, status) VALUES (?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:4472 +#: wallet/wallet.c:4568 msgid "SELECT bolt12, label, status FROM offers WHERE offer_id = ?;" msgstr "" -#: wallet/wallet.c:4500 +#: wallet/wallet.c:4596 msgid "SELECT offer_id FROM offers;" msgstr "" -#: wallet/wallet.c:4526 +#: wallet/wallet.c:4622 msgid "UPDATE offers SET status=? WHERE offer_id = ?;" msgstr "" -#: wallet/wallet.c:4537 +#: wallet/wallet.c:4633 msgid "UPDATE invoices SET state=? WHERE state=? AND local_offer_id = ?;" msgstr "" -#: wallet/wallet.c:4565 +#: wallet/wallet.c:4661 msgid "SELECT status FROM offers WHERE offer_id = ?;" msgstr "" @@ -1294,11 +1322,11 @@ msgstr "" msgid "not a valid SQL statement" msgstr "" -#: wallet/test/run-wallet.c:1451 +#: wallet/test/run-wallet.c:1483 msgid "SELECT COUNT(1) FROM channel_funding_inflights WHERE channel_id = ?;" msgstr "" -#: wallet/test/run-wallet.c:1653 +#: wallet/test/run-wallet.c:1696 msgid "INSERT INTO channels (id) VALUES (1);" msgstr "" -# SHA256STAMP:c11c71bfdabd0f5e28d6d8b7539e2a1b7315206fb4df5c2870a658ea9c66c1c6 +# SHA256STAMP:03557959b260db89fed45406e7fae168e0ce9810b47351f22bbd8741a2910898 diff --git a/wallet/test/Makefile b/wallet/test/Makefile index 8c60d6c8e..7526ec232 100644 --- a/wallet/test/Makefile +++ b/wallet/test/Makefile @@ -8,6 +8,7 @@ ALL_TEST_PROGRAMS += $(WALLET_TEST_PROGRAMS) WALLET_TEST_COMMON_OBJS := \ common/amount.o \ common/base32.o \ + common/blockheight_states.o \ common/derive_basepoints.o \ common/htlc_state.o \ common/htlc_wire.o \ diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 38794dc81..7bd924ea5 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -1184,6 +1184,15 @@ static bool channel_inflightseq(struct channel_inflight *i1, &i2->last_sig, sizeof(i2->last_sig))); CHECK(bitcoin_tx_eq(i1->last_tx, i2->last_tx)); + CHECK(!i1->lease_commit_sig == !i2->lease_commit_sig); + if (i1->lease_commit_sig) + CHECK(memeq(i1->lease_commit_sig, sizeof(*i1->lease_commit_sig), + i2->lease_commit_sig, sizeof(*i2->lease_commit_sig))); + CHECK(i1->lease_expiry == i2->lease_expiry); + CHECK(i1->lease_chan_max_msat == i2->lease_chan_max_msat); + CHECK(i1->lease_chan_max_ppt == i2->lease_chan_max_ppt); + CHECK(i1->lease_blockheight_start == i2->lease_blockheight_start); + return true; } @@ -1254,6 +1263,27 @@ static bool channelseq(struct channel *c1, struct channel *c2) CHECK(c1->last_was_revoke == c2->last_was_revoke); + CHECK(!c1->lease_commit_sig == !c2->lease_commit_sig); + if (c1->lease_commit_sig) + CHECK(memeq(c1->lease_commit_sig, sizeof(*c1->lease_commit_sig), + c2->lease_commit_sig, sizeof(*c2->lease_commit_sig))); + + CHECK(c1->lease_chan_max_msat == c2->lease_chan_max_msat); + CHECK(c1->lease_chan_max_ppt == c2->lease_chan_max_ppt); + CHECK(c1->lease_expiry == c2->lease_expiry); + + CHECK(height_states_valid(c1->blockheight_states, c1->opener)); + CHECK(height_states_valid(c2->blockheight_states, c2->opener)); + for (enum htlc_state i = 0; i < ARRAY_SIZE(c1->blockheight_states->height); + i++) { + if (c1->blockheight_states->height[i] == NULL) { + CHECK(c2->blockheight_states->height[i] == NULL); + } else { + CHECK(*c1->blockheight_states->height[i] + == *c2->blockheight_states->height[i]); + } + } + i1 = list_top(&c1->inflights, struct channel_inflight, list); i2 = list_top(&c2->inflights, struct channel_inflight, list); CHECK((i1 != NULL) == (i2 != NULL)); @@ -1304,7 +1334,7 @@ static bool test_channel_crud(struct lightningd *ld, const tal_t *ctx) secp256k1_ecdsa_signature *node_sig1 = tal(w, secp256k1_ecdsa_signature); secp256k1_ecdsa_signature *bitcoin_sig1 = tal(w, secp256k1_ecdsa_signature); secp256k1_ecdsa_signature *node_sig2, *bitcoin_sig2; - u32 feerate; + u32 feerate, blockheight; bool load; memset(&c1, 0, sizeof(c1)); @@ -1320,6 +1350,8 @@ static bool test_channel_crud(struct lightningd *ld, const tal_t *ctx) node_id_from_pubkey(&id, &pk); feerate = 31337; c1.fee_states = new_fee_states(w, c1.opener, &feerate); + blockheight = 10010; + c1.blockheight_states = new_height_states(w, c1.opener, &blockheight); mempat(scriptpubkey, tal_count(scriptpubkey)); c1.first_blocknum = 1; parse_wireaddr_internal("localhost:1234", &addr, 0, false, false, false, @@ -1478,7 +1510,8 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx) struct wally_psbt *funding_psbt; struct channel_info *channel_info = tal(w, struct channel_info); struct basepoints basepoints; - u32 feerate; + secp256k1_ecdsa_signature *lease_commit_sig; + u32 feerate, lease_blockheight_start; u64 dbid; pubkey_from_der(tal_hexdata(w, "02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc", 66), 33, &pk); @@ -1493,12 +1526,17 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx) our_sats = AMOUNT_SAT(3333333); mempat(&sig.s, sizeof(sig.s)); mempat(&cid, sizeof(struct channel_id)); + + lease_commit_sig = tal(w, secp256k1_ecdsa_signature); + mempat(lease_commit_sig, sizeof(*lease_commit_sig)); + sig.sighash_type = SIGHASH_ALL; /* last_tx taken from BOLT #3 */ last_tx = bitcoin_tx_from_hex(w, "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110ae8f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe260147304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", strlen("02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110ae8f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe260147304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220")); funding_psbt = psbt_from_b64(w, "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEHakcwRAIgR1lmF5fAGwNrJZKJSGhiGDR9iYZLcZ4ff89X0eURZYcCIFMJ6r9Wqk2Ikf/REf3xM286KdqGbX+EhtdVRs7tr5MZASEDXNxh/HupccC1AaZGoqg7ECy0OIEhfKaC3Ibi1z+ogpIAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIAAAA", strlen("cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEHakcwRAIgR1lmF5fAGwNrJZKJSGhiGDR9iYZLcZ4ff89X0eURZYcCIFMJ6r9Wqk2Ikf/REf3xM286KdqGbX+EhtdVRs7tr5MZASEDXNxh/HupccC1AaZGoqg7ECy0OIEhfKaC3Ibi1z+ogpIAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIAAAA")); feerate = 192838; + lease_blockheight_start = 101010; memset(&our_config, 1, sizeof(struct channel_config)); our_config.id = 0; memset(&txid, 1, sizeof(txid)); @@ -1541,8 +1579,12 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx) &pk, NULL, 1000, 100, NULL, 0, 0, true, - LOCAL, REASON_UNKNOWN, NULL, - 100, NULL, + LOCAL, REASON_UNKNOWN, + NULL, + new_height_states(w, LOCAL, + &lease_blockheight_start), + 100, + lease_commit_sig, 7777, 22); db_begin_transaction(w->db); CHECK(!wallet_err); @@ -1560,7 +1602,7 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx) funding_psbt, last_tx, sig, - 1, NULL, 2, 4); + 1, lease_commit_sig, 2, 4, 22); /* do inflights get correctly added to the channel? */ wallet_inflight_add(w, inflight); @@ -1582,12 +1624,13 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx) funding_psbt, last_tx, sig, - 1, NULL, 2, 4); + 0, NULL, 0, 0, 0); wallet_inflight_add(w, inflight); CHECK_MSG(c2 = wallet_channel_load(w, chan->dbid), tal_fmt(w, "Load from DB")); CHECK_MSG(channelseq(chan, c2), "Compare loaded with saved (v2)"); CHECK_MSG(count_inflights(w, chan->dbid) == 2, "inflights exist"); + tal_free(c2); /* Update the PSBT for both inflights, check that are updated diff --git a/wallet/wallet.c b/wallet/wallet.c index 7be2547f2..4c96ee382 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -966,21 +967,63 @@ static struct fee_states *wallet_channel_fee_states_load(struct wallet *w, return fee_states; } +static struct height_states *wallet_channel_height_states_load(struct wallet *w, + const u64 id, + enum side opener) +{ + struct height_states *states; + struct db_stmt *stmt; + + stmt = db_prepare_v2(w->db, SQL("SELECT hstate, blockheight FROM channel_blockheights WHERE channel_id = ?")); + db_bind_u64(stmt, 0, id); + db_query_prepared(stmt); + + /* Start with blank slate. */ + states = new_height_states(w, opener, NULL); + while (db_step(stmt)) { + enum htlc_state hstate = db_column_int(stmt, 0); + u32 blockheight = db_column_int(stmt, 1); + + if (states->height[hstate] != NULL) { + log_broken(w->log, + "duplicate channel_blockheights for %s id %"PRIu64, + htlc_state_name(hstate), id); + states = tal_free(states); + break; + } + states->height[hstate] = tal_dup(states, u32, &blockheight); + } + tal_free(stmt); + + if (states && !height_states_valid(states, opener)) { + log_broken(w->log, + "invalid channel_blockheight for id %"PRIu64, id); + states = tal_free(states); + } + return states; +} + void wallet_inflight_add(struct wallet *w, struct channel_inflight *inflight) { struct db_stmt *stmt; stmt = db_prepare_v2(w->db, SQL("INSERT INTO channel_funding_inflights (" - " channel_id" - ", funding_tx_id" - ", funding_tx_outnum" - ", funding_feerate" - ", funding_satoshi" - ", our_funding_satoshi" - ", funding_psbt" - ", last_tx" - ", last_sig" - ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);")); + " channel_id" // 0 + ", funding_tx_id" // 1 + ", funding_tx_outnum" // 2 + ", funding_feerate" // 3 + ", funding_satoshi" // 4 + ", our_funding_satoshi" // 5 + ", funding_psbt" // 6 + ", last_tx" // 7 + ", last_sig" // 8 + ", lease_commit_sig" // 9 + ", lease_chan_max_msat" // 10 + ", lease_chan_max_ppt" // 11 + ", lease_expiry" // 12 + ", lease_blockheight_start" // 13 + ") VALUES (" + "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")); db_bind_u64(stmt, 0, inflight->channel->dbid); db_bind_txid(stmt, 1, &inflight->funding->txid); @@ -991,6 +1034,21 @@ void wallet_inflight_add(struct wallet *w, struct channel_inflight *inflight) db_bind_psbt(stmt, 6, inflight->funding_psbt); db_bind_psbt(stmt, 7, inflight->last_tx->psbt); db_bind_signature(stmt, 8, &inflight->last_sig.s); + + if (inflight->lease_expiry != 0) { + db_bind_signature(stmt, 9, inflight->lease_commit_sig); + db_bind_int(stmt, 10, inflight->lease_chan_max_msat); + db_bind_int(stmt, 11, inflight->lease_chan_max_ppt); + db_bind_int(stmt, 12, inflight->lease_expiry); + db_bind_int(stmt, 13, inflight->lease_blockheight_start); + } else { + db_bind_null(stmt, 9); + db_bind_null(stmt, 10); + db_bind_null(stmt, 11); + db_bind_int(stmt, 12, 0); + db_bind_null(stmt, 13); + } + db_exec_prepared_v2(stmt); assert(!stmt->error); tal_free(stmt); @@ -1049,7 +1107,7 @@ wallet_stmt2inflight(struct wallet *w, struct db_stmt *stmt, struct channel_inflight *inflight; secp256k1_ecdsa_signature *lease_commit_sig; - u32 lease_chan_max_msat; + u32 lease_chan_max_msat, lease_blockheight_start; u16 lease_chan_max_ppt; db_column_txid(stmt, 0, &funding_txid); @@ -1065,10 +1123,12 @@ wallet_stmt2inflight(struct wallet *w, struct db_stmt *stmt, db_column_signature(stmt, 10, lease_commit_sig); lease_chan_max_msat = db_column_int(stmt, 11); lease_chan_max_ppt = db_column_int(stmt, 12); + lease_blockheight_start = db_column_int(stmt, 13); } else { lease_commit_sig = NULL; lease_chan_max_msat = 0; lease_chan_max_ppt = 0; + lease_blockheight_start = 0; } inflight = new_inflight(chan, funding_txid, @@ -1082,7 +1142,8 @@ wallet_stmt2inflight(struct wallet *w, struct db_stmt *stmt, db_column_int(stmt, 9), lease_commit_sig, lease_chan_max_msat, - lease_chan_max_ppt); + lease_chan_max_ppt, + lease_blockheight_start); /* Pull out the serialized tx-sigs-received-ness */ inflight->remote_tx_sigs = db_column_int(stmt, 8); @@ -1109,6 +1170,7 @@ static bool wallet_channel_load_inflights(struct wallet *w, ", lease_commit_sig" // 10 ", lease_chan_max_msat" // 11 ", lease_chan_max_ppt" // 12 + ", lease_blockheight_start" // 13 " FROM channel_funding_inflights" " WHERE channel_id = ?" // ?0 " ORDER BY funding_feerate")); @@ -1137,6 +1199,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm bool ok = true; struct channel_info channel_info; struct fee_states *fee_states; + struct height_states *height_states; struct short_channel_id *scid; struct channel_id cid; struct channel *chan; @@ -1241,6 +1304,19 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm return NULL; } + /* Blockheight states for the channel! */ + height_states + = wallet_channel_height_states_load(w, + db_column_u64(stmt, 0), + db_column_int(stmt, 7)); + if (!height_states) + ok = false; + + if (!ok) { + tal_free(height_states); + return NULL; + } + final_key_idx = db_column_u64(stmt, 31); if (final_key_idx < 0) { tal_free(fee_states); @@ -1330,6 +1406,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm db_column_int(stmt, 51), db_column_int(stmt, 52), shutdown_wrong_funding, + take(height_states), db_column_int(stmt, 60), lease_commit_sig, lease_chan_max_msat, @@ -1833,6 +1910,25 @@ void wallet_channel_save(struct wallet *w, struct channel *chan) db_exec_prepared_v2(take(stmt)); } + /* FIXME: Updates channel_blockheights by discarding and rewriting. */ + stmt = db_prepare_v2(w->db, SQL("DELETE FROM channel_blockheights " + "WHERE channel_id=?")); + db_bind_u64(stmt, 0, chan->dbid); + db_exec_prepared_v2(take(stmt)); + + for (enum htlc_state i = 0; + i < ARRAY_SIZE(chan->blockheight_states->height); + i++) { + if (!chan->blockheight_states->height[i]) + continue; + 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, 2, *chan->blockheight_states->height[i]); + db_exec_prepared_v2(take(stmt)); + } + /* If we have a last_sent_commit, store it */ last_sent_commit = tal_arr(tmpctx, u8, 0); for (size_t i = 0; i < tal_count(chan->last_sent_commit); i++) diff --git a/wire/bolt12_wiregen.c b/wire/bolt12_wiregen.c index 58b02e5d2..a5d1792a2 100644 --- a/wire/bolt12_wiregen.c +++ b/wire/bolt12_wiregen.c @@ -1684,4 +1684,4 @@ bool invoice_error_is_valid(const struct tlv_invoice_error *record, size_t *err_ return tlv_fields_valid(record->fields, NULL, err_index); } -// SHA256STAMP:95d5be81bb0846cff337017b812800a19bf176d3182dd605bfe03086c14ef1f4 +// SHA256STAMP:27ffc38bc2be76e159508470734655f35e59d82927beb8c1f62917e592d76d10 diff --git a/wire/bolt12_wiregen.h b/wire/bolt12_wiregen.h index 162cc6aa4..0f331da8a 100644 --- a/wire/bolt12_wiregen.h +++ b/wire/bolt12_wiregen.h @@ -323,4 +323,4 @@ struct fallback_address *fromwire_fallback_address(const tal_t *ctx, const u8 ** #endif /* LIGHTNING_WIRE_BOLT12_WIREGEN_H */ -// SHA256STAMP:95d5be81bb0846cff337017b812800a19bf176d3182dd605bfe03086c14ef1f4 +// SHA256STAMP:27ffc38bc2be76e159508470734655f35e59d82927beb8c1f62917e592d76d10 diff --git a/wire/common_wiregen.c b/wire/common_wiregen.c index ef9627078..d61d6405e 100644 --- a/wire/common_wiregen.c +++ b/wire/common_wiregen.c @@ -100,4 +100,4 @@ bool fromwire_custommsg_out(const tal_t *ctx, const void *p, u8 **msg) fromwire_u8_array(&cursor, &plen, *msg, msg_len); return cursor != NULL; } -// SHA256STAMP:20f78b01d36c7db37e7316d8ab52740dd5f39011ea306f0e8b6a5a4a6bbc7c9e +// SHA256STAMP:959a0af7e5dc054bc1bd313dee486b3c2040853b8f3772d889e51048e14ac2b5 diff --git a/wire/common_wiregen.h b/wire/common_wiregen.h index d837aee8c..ad19ec882 100644 --- a/wire/common_wiregen.h +++ b/wire/common_wiregen.h @@ -41,4 +41,4 @@ bool fromwire_custommsg_out(const tal_t *ctx, const void *p, u8 **msg); #endif /* LIGHTNING_WIRE_COMMON_WIREGEN_H */ -// SHA256STAMP:20f78b01d36c7db37e7316d8ab52740dd5f39011ea306f0e8b6a5a4a6bbc7c9e +// SHA256STAMP:959a0af7e5dc054bc1bd313dee486b3c2040853b8f3772d889e51048e14ac2b5 diff --git a/wire/onion_printgen.c b/wire/onion_printgen.c index 7ae73827a..d4d237fb4 100644 --- a/wire/onion_printgen.c +++ b/wire/onion_printgen.c @@ -859,4 +859,4 @@ void printonion_wire_tlv_message(const char *tlv_name, const u8 *msg) { printwire_tlvs(tlv_name, &msg, &plen, print_tlvs_encmsg_tlvs, ARRAY_SIZE(print_tlvs_encmsg_tlvs)); } } -// SHA256STAMP:aeab913b5da11a9166e167e47d60cd748aa35a8c6c9adc2a7c1f791bed70797f +// SHA256STAMP:fcaea2b057478205299b8935161c994fece0e410e6942503943747625ddcfc8a diff --git a/wire/onion_printgen.h b/wire/onion_printgen.h index 6b85f97d4..fa2e5b1e4 100644 --- a/wire/onion_printgen.h +++ b/wire/onion_printgen.h @@ -58,4 +58,4 @@ void printwire_mpp_timeout(const char *fieldname, const u8 *cursor); void printwire_onionmsg_path(const char *fieldname, const u8 **cursor, size_t *plen); #endif /* LIGHTNING_WIRE_ONION_PRINTGEN_H */ -// SHA256STAMP:aeab913b5da11a9166e167e47d60cd748aa35a8c6c9adc2a7c1f791bed70797f +// SHA256STAMP:fcaea2b057478205299b8935161c994fece0e410e6942503943747625ddcfc8a diff --git a/wire/onion_wiregen.c b/wire/onion_wiregen.c index 8a25fa28d..c6b47b052 100644 --- a/wire/onion_wiregen.c +++ b/wire/onion_wiregen.c @@ -1026,4 +1026,4 @@ bool fromwire_mpp_timeout(const void *p) return false; return cursor != NULL; } -// SHA256STAMP:aeab913b5da11a9166e167e47d60cd748aa35a8c6c9adc2a7c1f791bed70797f +// SHA256STAMP:fcaea2b057478205299b8935161c994fece0e410e6942503943747625ddcfc8a diff --git a/wire/onion_wiregen.h b/wire/onion_wiregen.h index 6107b844e..479c89b61 100644 --- a/wire/onion_wiregen.h +++ b/wire/onion_wiregen.h @@ -317,4 +317,4 @@ bool fromwire_mpp_timeout(const void *p); #endif /* LIGHTNING_WIRE_ONION_WIREGEN_H */ -// SHA256STAMP:aeab913b5da11a9166e167e47d60cd748aa35a8c6c9adc2a7c1f791bed70797f +// SHA256STAMP:fcaea2b057478205299b8935161c994fece0e410e6942503943747625ddcfc8a diff --git a/wire/peer_printgen.c b/wire/peer_printgen.c index e2685809e..6b40e3a0e 100644 --- a/wire/peer_printgen.c +++ b/wire/peer_printgen.c @@ -3079,4 +3079,4 @@ void printpeer_wire_tlv_message(const char *tlv_name, const u8 *msg) { printwire_tlvs(tlv_name, &msg, &plen, print_tlvs_onion_message_tlvs, ARRAY_SIZE(print_tlvs_onion_message_tlvs)); } } -// SHA256STAMP:4751c4834d5db7d170f8e1ee40ea8b5e12b5552780d37b099fe5fae6f0342c9e +// SHA256STAMP:7c9612ec7cc62b3a44ae65d19b855b521e96796940b4c3d50977d768ace8712e diff --git a/wire/peer_printgen.h b/wire/peer_printgen.h index a3bd3d333..997adc7fc 100644 --- a/wire/peer_printgen.h +++ b/wire/peer_printgen.h @@ -99,4 +99,4 @@ void printwire_channel_update_checksums(const char *fieldname, const u8 **cursor void printwire_channel_update_timestamps(const char *fieldname, const u8 **cursor, size_t *plen); void printwire_witness_stack(const char *fieldname, const u8 **cursor, size_t *plen); #endif /* LIGHTNING_WIRE_PEER_PRINTGEN_H */ -// SHA256STAMP:4751c4834d5db7d170f8e1ee40ea8b5e12b5552780d37b099fe5fae6f0342c9e +// SHA256STAMP:7c9612ec7cc62b3a44ae65d19b855b521e96796940b4c3d50977d768ace8712e diff --git a/wire/peer_wiregen.c b/wire/peer_wiregen.c index 92c206e9b..5c706df2f 100644 --- a/wire/peer_wiregen.c +++ b/wire/peer_wiregen.c @@ -2484,4 +2484,4 @@ bool fromwire_channel_update_option_channel_htlc_max(const void *p, secp256k1_ec *htlc_maximum_msat = fromwire_amount_msat(&cursor, &plen); return cursor != NULL; } -// SHA256STAMP:4751c4834d5db7d170f8e1ee40ea8b5e12b5552780d37b099fe5fae6f0342c9e +// SHA256STAMP:7c9612ec7cc62b3a44ae65d19b855b521e96796940b4c3d50977d768ace8712e diff --git a/wire/peer_wiregen.h b/wire/peer_wiregen.h index e063cfb84..dc1b44de2 100644 --- a/wire/peer_wiregen.h +++ b/wire/peer_wiregen.h @@ -930,4 +930,4 @@ bool fromwire_channel_update_option_channel_htlc_max(const void *p, secp256k1_ec #endif /* LIGHTNING_WIRE_PEER_WIREGEN_H */ -// SHA256STAMP:4751c4834d5db7d170f8e1ee40ea8b5e12b5552780d37b099fe5fae6f0342c9e +// SHA256STAMP:7c9612ec7cc62b3a44ae65d19b855b521e96796940b4c3d50977d768ace8712e