inflight: add a 'channel-inflight' concept, in-progress channel stuffs

"inflights" are all potential channel funding transactions that we
currently have commitment transactions for.
This commit is contained in:
niftynei 2021-02-04 15:14:44 -06:00 committed by Rusty Russell
parent b8183f2eeb
commit 36f3b13279
10 changed files with 1694 additions and 116 deletions

View file

@ -1,3 +1,4 @@
#include <bitcoin/psbt.h>
#include <bitcoin/script.h>
#include <ccan/crypto/hkdf_sha256/hkdf_sha256.h>
#include <ccan/tal/str/str.h>
@ -143,6 +144,46 @@ void get_channel_basepoints(struct lightningd *ld,
tal_hex(msg, msg));
}
static void destroy_inflight(struct channel_inflight *inflight)
{
list_del_from(&inflight->channel->inflights, &inflight->list);
}
struct channel_inflight *
new_inflight(struct channel *channel,
const struct bitcoin_txid funding_txid,
u16 funding_outnum,
u32 funding_feerate,
struct amount_sat total_funds,
struct amount_sat our_funds,
struct wally_psbt *psbt STEALS,
struct bitcoin_tx *last_tx STEALS,
const struct bitcoin_signature last_sig)
{
struct channel_inflight *inflight
= tal(channel, struct channel_inflight);
struct funding_info *funding
= tal(inflight, struct funding_info);
funding->txid = funding_txid;
funding->total_funds = total_funds;
funding->outnum = funding_outnum;
funding->feerate = funding_feerate;
funding->our_funds = our_funds;
inflight->funding = funding;
inflight->channel = channel,
inflight->remote_tx_sigs = false,
inflight->funding_psbt = tal_steal(inflight, psbt);
inflight->last_tx = tal_steal(inflight, last_tx);
inflight->last_sig = last_sig;
list_add_tail(&channel->inflights, &inflight->list);
tal_add_destructor(inflight, destroy_inflight);
return inflight;
}
struct channel *new_channel(struct peer *peer, u64 dbid,
/* NULL or stolen */
struct wallet_shachain *their_shachain,
@ -294,6 +335,8 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
channel->rr_number = peer->ld->rr_counter++;
tal_add_destructor(channel, destroy_channel);
list_head_init(&channel->inflights);
channel->closer = closer;
channel->state_change_cause = reason;

View file

@ -18,6 +18,33 @@ struct billboard {
const char *transient;
};
struct funding_info {
struct bitcoin_txid txid;
u16 outnum;
u32 feerate;
struct amount_sat total_funds;
/* Our original funds, in funding amount */
struct amount_sat our_funds;
};
struct channel_inflight {
/* Inside channel->inflights. */
struct list_node list;
/* Channel context */
struct channel *channel;
/* Funding info */
const struct funding_info *funding;
struct wally_psbt *funding_psbt;
bool remote_tx_sigs;
/* Commitment tx and sigs */
struct bitcoin_tx *last_tx;
struct bitcoin_signature last_sig;
};
struct channel {
/* Inside peer->channels. */
struct list_node list;
@ -25,6 +52,9 @@ struct channel {
/* Peer context */
struct peer *peer;
/* Inflight channel opens */
struct list_head inflights;
/* Database ID: 0 == not in db yet */
u64 dbid;
@ -220,6 +250,18 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
enum side closer,
enum state_change reason);
/* new_inflight - Create a new channel_inflight for a channel */
struct channel_inflight *
new_inflight(struct channel *channel,
const struct bitcoin_txid funding_txid,
u16 funding_outnum,
u32 funding_feerate,
struct amount_sat funding,
struct amount_sat our_funds,
struct wally_psbt *funding_psbt STEALS,
struct bitcoin_tx *last_tx STEALS,
const struct bitcoin_signature last_sig);
void delete_channel(struct channel *channel STEALS);
const char *channel_state_name(const struct channel *channel);

View file

@ -676,6 +676,20 @@ static struct migration dbmigrations[] = {
{SQL("UPDATE channel_htlcs SET malformed_onion = 0 WHERE malformed_onion IS NULL"), NULL},
/* Speed up forwarded_payments lookup based on state */
{SQL("CREATE INDEX forwarded_payments_state ON forwarded_payments (state)"), NULL},
{SQL("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)"
");"),
NULL},
};
/* Leak tracking. */

View file

@ -890,6 +890,12 @@ struct db_query db_postgres_queries[] = {
.placeholders = 0,
.readonly = false,
},
{
.name = "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));",
.query = "CREATE TABLE channel_funding_inflights ( channel_id BIGSERIAL REFERENCES channels(id) ON DELETE CASCADE, funding_tx_id BYTEA, funding_tx_outnum INTEGER, funding_feerate INTEGER, funding_satoshi BIGINT, our_funding_satoshi BIGINT, funding_psbt BYTEA, last_tx BYTEA, last_sig BYTEA, funding_tx_remote_sigs_received INTEGER, PRIMARY KEY (channel_id, funding_tx_id));",
.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",
@ -1202,6 +1208,24 @@ struct db_query db_postgres_queries[] = {
.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) 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,
.readonly = false,
},
{
.name = "UPDATE channel_funding_inflights SET funding_psbt=? WHERE channel_id=? AND funding_tx_id=? AND funding_tx_outnum=?",
.query = "UPDATE channel_funding_inflights SET funding_psbt=$1 WHERE channel_id=$2 AND funding_tx_id=$3 AND funding_tx_outnum=$4",
.placeholders = 4,
.readonly = false,
},
{
.name = "SELECT funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig FROM channel_funding_inflights WHERE channel_id = ?",
.query = "SELECT funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig FROM channel_funding_inflights WHERE channel_id = $1",
.placeholders = 1,
.readonly = true,
},
{
.name = "SELECT id FROM channels ORDER BY id DESC LIMIT 1;",
.query = "SELECT id FROM channels ORDER BY id DESC LIMIT 1;",
@ -1358,6 +1382,12 @@ struct db_query db_postgres_queries[] = {
.placeholders = 1,
.readonly = false,
},
{
.name = "DELETE FROM channel_funding_inflights WHERE channel_id=?",
.query = "DELETE FROM channel_funding_inflights WHERE channel_id=$1",
.placeholders = 1,
.readonly = false,
},
{
.name = "DELETE FROM shachains WHERE id IN ( SELECT shachain_remote_id FROM channels WHERE channels.id=?)",
.query = "DELETE FROM shachains WHERE id IN ( SELECT shachain_remote_id FROM channels WHERE channels.id=$1)",
@ -1784,6 +1814,12 @@ struct db_query db_postgres_queries[] = {
.placeholders = 0,
.readonly = false,
},
{
.name = "SELECT COUNT(1) FROM channel_funding_inflights WHERE channel_id = ?;",
.query = "SELECT COUNT(1) FROM channel_funding_inflights WHERE channel_id = $1;",
.placeholders = 1,
.readonly = true,
},
{
.name = "INSERT INTO channels (id) VALUES (1);",
.query = "INSERT INTO channels (id) VALUES (1);",
@ -1792,10 +1828,10 @@ struct db_query db_postgres_queries[] = {
},
};
#define DB_POSTGRES_QUERY_COUNT 297
#define DB_POSTGRES_QUERY_COUNT 303
#endif /* HAVE_POSTGRES */
#endif /* LIGHTNINGD_WALLET_GEN_DB_POSTGRES */
// SHA256STAMP:bbe38ba26543917c2c8be0eeba93c2d0345b51f7f29803e30cc3f03aaf077798
// SHA256STAMP:044504d8dccba17231afc233809d113884b6e73ef6a3b414d061df94982755a5

View file

@ -890,6 +890,12 @@ struct db_query db_sqlite3_queries[] = {
.placeholders = 0,
.readonly = false,
},
{
.name = "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));",
.query = "CREATE TABLE channel_funding_inflights ( channel_id INTEGER REFERENCES channels(id) ON DELETE CASCADE, funding_tx_id BLOB, funding_tx_outnum INTEGER, funding_feerate INTEGER, funding_satoshi INTEGER, our_funding_satoshi INTEGER, funding_psbt BLOB, last_tx BLOB, last_sig BLOB, funding_tx_remote_sigs_received INTEGER, PRIMARY KEY (channel_id, funding_tx_id));",
.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 = ?",
@ -1202,6 +1208,24 @@ struct db_query db_sqlite3_queries[] = {
.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) 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,
.readonly = false,
},
{
.name = "UPDATE channel_funding_inflights SET funding_psbt=? WHERE channel_id=? AND funding_tx_id=? AND funding_tx_outnum=?",
.query = "UPDATE channel_funding_inflights SET funding_psbt=? WHERE channel_id=? AND funding_tx_id=? AND funding_tx_outnum=?",
.placeholders = 4,
.readonly = false,
},
{
.name = "SELECT funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig FROM channel_funding_inflights WHERE channel_id = ?",
.query = "SELECT funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig FROM channel_funding_inflights WHERE channel_id = ?",
.placeholders = 1,
.readonly = true,
},
{
.name = "SELECT id FROM channels ORDER BY id DESC LIMIT 1;",
.query = "SELECT id FROM channels ORDER BY id DESC LIMIT 1;",
@ -1358,6 +1382,12 @@ struct db_query db_sqlite3_queries[] = {
.placeholders = 1,
.readonly = false,
},
{
.name = "DELETE FROM channel_funding_inflights WHERE channel_id=?",
.query = "DELETE FROM channel_funding_inflights WHERE channel_id=?",
.placeholders = 1,
.readonly = false,
},
{
.name = "DELETE FROM shachains WHERE id IN ( SELECT shachain_remote_id FROM channels WHERE channels.id=?)",
.query = "DELETE FROM shachains WHERE id IN ( SELECT shachain_remote_id FROM channels WHERE channels.id=?)",
@ -1784,6 +1814,12 @@ struct db_query db_sqlite3_queries[] = {
.placeholders = 0,
.readonly = false,
},
{
.name = "SELECT COUNT(1) FROM channel_funding_inflights WHERE channel_id = ?;",
.query = "SELECT COUNT(1) FROM channel_funding_inflights WHERE channel_id = ?;",
.placeholders = 1,
.readonly = true,
},
{
.name = "INSERT INTO channels (id) VALUES (1);",
.query = "INSERT INTO channels (id) VALUES (1);",
@ -1792,10 +1828,10 @@ struct db_query db_sqlite3_queries[] = {
},
};
#define DB_SQLITE3_QUERY_COUNT 297
#define DB_SQLITE3_QUERY_COUNT 303
#endif /* HAVE_SQLITE3 */
#endif /* LIGHTNINGD_WALLET_GEN_DB_SQLITE3 */
// SHA256STAMP:bbe38ba26543917c2c8be0eeba93c2d0345b51f7f29803e30cc3f03aaf077798
// SHA256STAMP:044504d8dccba17231afc233809d113884b6e73ef6a3b414d061df94982755a5

1039
wallet/statements.po Normal file

File diff suppressed because it is too large Load diff

View file

@ -586,67 +586,71 @@ msgstr ""
msgid "CREATE INDEX forwarded_payments_state ON forwarded_payments (state)"
msgstr ""
#: wallet/db.c:905
#: wallet/db.c:679
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:919
msgid "UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = ?"
msgstr ""
#: wallet/db.c:1005
#: wallet/db.c:1019
msgid "SELECT version FROM version LIMIT 1"
msgstr ""
#: wallet/db.c:1063
#: wallet/db.c:1077
msgid "UPDATE version SET version=?;"
msgstr ""
#: wallet/db.c:1071
#: wallet/db.c:1085
msgid "INSERT INTO db_upgrades VALUES (?, ?);"
msgstr ""
#: wallet/db.c:1083
#: wallet/db.c:1097
msgid "SELECT intval FROM vars WHERE name = 'data_version'"
msgstr ""
#: wallet/db.c:1110
#: wallet/db.c:1124
msgid "SELECT intval FROM vars WHERE name= ? LIMIT 1"
msgstr ""
#: wallet/db.c:1126
#: wallet/db.c:1140
msgid "UPDATE vars SET intval=? WHERE name=?;"
msgstr ""
#: wallet/db.c:1135
#: wallet/db.c:1149
msgid "INSERT INTO vars (name, intval) VALUES (?, ?);"
msgstr ""
#: wallet/db.c:1149
#: wallet/db.c:1163
msgid "UPDATE channels SET feerate_base = ?, feerate_ppm = ?;"
msgstr ""
#: wallet/db.c:1170
#: wallet/db.c:1184
msgid "UPDATE channels SET our_funding_satoshi = funding_satoshi WHERE funder = 0;"
msgstr ""
#: wallet/db.c:1186
#: wallet/db.c:1200
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:1248
#: wallet/db.c:1262
msgid "UPDATE outputs SET scriptpubkey = ? WHERE prev_out_tx = ? AND prev_out_index = ?"
msgstr ""
#: wallet/db.c:1273
#: wallet/db.c:1287
msgid "SELECT id, funding_tx_id, funding_tx_outnum FROM channels;"
msgstr ""
#: wallet/db.c:1292
#: wallet/db.c:1306
msgid "UPDATE channels SET full_channel_id = ? WHERE id = ?;"
msgstr ""
#: wallet/db.c:1315
#: wallet/db.c:1329
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:1382
#: wallet/db.c:1396
msgid "UPDATE channels SET last_tx = ? WHERE id = ?;"
msgstr ""
@ -794,383 +798,399 @@ msgstr ""
msgid "SELECT hstate, feerate_per_kw FROM channel_feerates WHERE channel_id = ?"
msgstr ""
#: wallet/wallet.c:1138
#: wallet/wallet.c:952
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 (?, ?, ?, ?, ?, ?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:987
msgid "UPDATE channel_funding_inflights SET funding_psbt=? WHERE channel_id=? AND funding_tx_id=? AND funding_tx_outnum=?"
msgstr ""
#: wallet/wallet.c:1033
msgid "SELECT funding_tx_id, funding_tx_outnum, funding_feerate, funding_satoshi, our_funding_satoshi, funding_psbt, last_tx, last_sig FROM channel_funding_inflights WHERE channel_id = ?"
msgstr ""
#: wallet/wallet.c:1256
msgid "SELECT id FROM channels ORDER BY id DESC LIMIT 1;"
msgstr ""
#: wallet/wallet.c:1155
#: wallet/wallet.c:1273
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, funding_tx_remote_sigs_received, 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, option_static_remotekey, option_anchor_outputs, shutdown_scriptpubkey_local, funding_psbt, closer, state_change_reason FROM channels WHERE state != ?;"
msgstr ""
#: wallet/wallet.c:1248
#: wallet/wallet.c:1366
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:1253
#: wallet/wallet.c:1371
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:1258
#: wallet/wallet.c:1376
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:1263
#: wallet/wallet.c:1381
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:1305
#: wallet/wallet.c:1423
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:1334
#: wallet/wallet.c:1452
msgid "SELECT MIN(height), MAX(height) FROM blocks;"
msgstr ""
#: wallet/wallet.c:1356
#: wallet/wallet.c:1474
msgid "INSERT INTO channel_configs DEFAULT VALUES;"
msgstr ""
#: wallet/wallet.c:1368
#: wallet/wallet.c:1486
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:1392
#: wallet/wallet.c:1510
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:1426
#: wallet/wallet.c:1544
msgid "UPDATE channels SET remote_ann_node_sig=?, remote_ann_bitcoin_sig=? WHERE id=?"
msgstr ""
#: wallet/wallet.c:1445
#: wallet/wallet.c:1563
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=?, funding_tx_remote_sigs_received=?, 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=?, option_static_remotekey=?, option_anchor_outputs=?, shutdown_scriptpubkey_local=?, funding_psbt=?, closer=?, state_change_reason=? WHERE id=?"
msgstr ""
#: wallet/wallet.c:1535
#: wallet/wallet.c:1653
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:1562
#: wallet/wallet.c:1680
msgid "DELETE FROM channel_feerates WHERE channel_id=?"
msgstr ""
#: wallet/wallet.c:1572
#: wallet/wallet.c:1690
msgid "INSERT INTO channel_feerates VALUES(?, ?, ?)"
msgstr ""
#: wallet/wallet.c:1589
#: wallet/wallet.c:1707
msgid "UPDATE channels SET last_sent_commit=? WHERE id=?"
msgstr ""
#: wallet/wallet.c:1607
#: wallet/wallet.c:1730
msgid "INSERT INTO channel_state_changes ( channel_id, timestamp, old_state, new_state, cause, message) VALUES (?, ?, ?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:1635
#: wallet/wallet.c:1758
msgid "SELECT timestamp, old_state, new_state, cause, message FROM channel_state_changes WHERE channel_id = ? ORDER BY timestamp ASC;"
msgstr ""
#: wallet/wallet.c:1664
#: wallet/wallet.c:1787
msgid "SELECT id FROM peers WHERE node_id = ?"
msgstr ""
#: wallet/wallet.c:1676
#: wallet/wallet.c:1799
msgid "UPDATE peers SET address = ? WHERE id = ?"
msgstr ""
#: wallet/wallet.c:1685
#: wallet/wallet.c:1808
msgid "INSERT INTO peers (node_id, address) VALUES (?, ?);"
msgstr ""
#: wallet/wallet.c:1703
#: wallet/wallet.c:1826
msgid "INSERT INTO channels (peer_id, first_blocknum, id) VALUES (?, ?, ?);"
msgstr ""
#: wallet/wallet.c:1729
#: wallet/wallet.c:1852
msgid "DELETE FROM channel_htlcs WHERE channel_id=?"
msgstr ""
#: wallet/wallet.c:1735
#: wallet/wallet.c:1858
msgid "DELETE FROM htlc_sigs WHERE channelid=?"
msgstr ""
#: wallet/wallet.c:1741
#: wallet/wallet.c:1864
msgid "DELETE FROM channeltxs WHERE channel_id=?"
msgstr ""
#: wallet/wallet.c:1747
#: wallet/wallet.c:1871
msgid "DELETE FROM channel_funding_inflights WHERE channel_id=?"
msgstr ""
#: wallet/wallet.c:1877
msgid "DELETE FROM shachains WHERE id IN ( SELECT shachain_remote_id FROM channels WHERE channels.id=?)"
msgstr ""
#: wallet/wallet.c:1757
#: wallet/wallet.c:1887
msgid "UPDATE channels SET state=?, peer_id=? WHERE channels.id=?"
msgstr ""
#: wallet/wallet.c:1771
#: wallet/wallet.c:1901
msgid "SELECT * FROM channels WHERE peer_id = ?;"
msgstr ""
#: wallet/wallet.c:1779
#: wallet/wallet.c:1909
msgid "DELETE FROM peers WHERE id=?"
msgstr ""
#: wallet/wallet.c:1790
#: wallet/wallet.c:1920
msgid "UPDATE outputs SET confirmation_height = ? WHERE prev_out_tx = ?"
msgstr ""
#: wallet/wallet.c:1893
#: wallet/wallet.c:2023
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:1946
#: wallet/wallet.c:2076
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:2007
#: wallet/wallet.c:2137
msgid "UPDATE channel_htlcs SET hstate=?, payment_key=?, malformed_onion=?, failuremsg=?, localfailmsg=?, we_filled=? WHERE id=?"
msgstr ""
#: wallet/wallet.c:2223
#: wallet/wallet.c:2353
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:2270
#: wallet/wallet.c:2400
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:2401
#: wallet/wallet.c:2531
msgid "SELECT channel_id, direction, cltv_expiry, channel_htlc_id, payment_hash FROM channel_htlcs WHERE channel_id = ?;"
msgstr ""
#: wallet/wallet.c:2435
#: wallet/wallet.c:2565
msgid "DELETE FROM channel_htlcs WHERE direction = ? AND origin_htlc = ? AND payment_hash = ? AND partid = ?;"
msgstr ""
#: wallet/wallet.c:2488
#: wallet/wallet.c:2618
msgid "SELECT status FROM payments WHERE payment_hash=? AND partid = ?;"
msgstr ""
#: wallet/wallet.c:2506
#: wallet/wallet.c:2636
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:2595
#: wallet/wallet.c:2725
msgid "DELETE FROM payments WHERE payment_hash = ? AND partid = ?"
msgstr ""
#: wallet/wallet.c:2609
#: wallet/wallet.c:2739
msgid "DELETE FROM payments WHERE payment_hash = ?"
msgstr ""
#: wallet/wallet.c:2710
#: wallet/wallet.c:2840
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:2760
#: wallet/wallet.c:2890
msgid "UPDATE payments SET status=? WHERE payment_hash=? AND partid=?"
msgstr ""
#: wallet/wallet.c:2770
#: wallet/wallet.c:2900
msgid "UPDATE payments SET payment_preimage=? WHERE payment_hash=? AND partid=?"
msgstr ""
#: wallet/wallet.c:2780
#: wallet/wallet.c:2910
msgid "UPDATE payments SET path_secrets = NULL , route_nodes = NULL , route_channels = NULL WHERE payment_hash = ? AND partid = ?;"
msgstr ""
#: wallet/wallet.c:2812
#: wallet/wallet.c:2942
msgid "SELECT failonionreply, faildestperm, failindex, failcode, failnode, failchannel, failupdate, faildetail, faildirection FROM payments WHERE payment_hash=? AND partid=?;"
msgstr ""
#: wallet/wallet.c:2879
#: wallet/wallet.c:3009
msgid "UPDATE payments SET failonionreply=? , faildestperm=? , failindex=? , failcode=? , failnode=? , failchannel=? , failupdate=? , faildetail=? , faildirection=? WHERE payment_hash=? AND partid=?;"
msgstr ""
#: wallet/wallet.c:2938
#: wallet/wallet.c:3068
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 = ?;"
msgstr ""
#: wallet/wallet.c:2960
#: wallet/wallet.c:3090
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:3011
#: wallet/wallet.c:3141
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:3056
#: wallet/wallet.c:3186
msgid "DELETE FROM htlc_sigs WHERE channelid = ?"
msgstr ""
#: wallet/wallet.c:3063
#: wallet/wallet.c:3193
msgid "INSERT INTO htlc_sigs (channelid, signature) VALUES (?, ?)"
msgstr ""
#: wallet/wallet.c:3075
#: wallet/wallet.c:3205
msgid "SELECT blobval FROM vars WHERE name='genesis_hash'"
msgstr ""
#: wallet/wallet.c:3099
#: wallet/wallet.c:3229
msgid "INSERT INTO vars (name, blobval) VALUES ('genesis_hash', ?);"
msgstr ""
#: wallet/wallet.c:3117
#: wallet/wallet.c:3247
msgid "SELECT txid, outnum FROM utxoset WHERE spendheight < ?"
msgstr ""
#: wallet/wallet.c:3129
#: wallet/wallet.c:3259
msgid "DELETE FROM utxoset WHERE spendheight < ?"
msgstr ""
#: wallet/wallet.c:3137 wallet/wallet.c:3251
#: wallet/wallet.c:3267 wallet/wallet.c:3381
msgid "INSERT INTO blocks (height, hash, prev_hash) VALUES (?, ?, ?);"
msgstr ""
#: wallet/wallet.c:3156
#: wallet/wallet.c:3286
msgid "DELETE FROM blocks WHERE hash = ?"
msgstr ""
#: wallet/wallet.c:3162
#: wallet/wallet.c:3292
msgid "SELECT * FROM blocks WHERE height >= ?;"
msgstr ""
#: wallet/wallet.c:3171
#: wallet/wallet.c:3301
msgid "DELETE FROM blocks WHERE height > ?"
msgstr ""
#: wallet/wallet.c:3183
#: wallet/wallet.c:3313
msgid "UPDATE outputs SET spend_height = ?, status = ? WHERE prev_out_tx = ? AND prev_out_index = ?"
msgstr ""
#: wallet/wallet.c:3201
#: wallet/wallet.c:3331
msgid "UPDATE utxoset SET spendheight = ? WHERE txid = ? AND outnum = ?"
msgstr ""
#: wallet/wallet.c:3224 wallet/wallet.c:3262
#: wallet/wallet.c:3354 wallet/wallet.c:3392
msgid "INSERT INTO utxoset ( txid, outnum, blockheight, spendheight, txindex, scriptpubkey, satoshis) VALUES(?, ?, ?, ?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:3288
#: wallet/wallet.c:3418
msgid "SELECT height FROM blocks WHERE height = ?"
msgstr ""
#: wallet/wallet.c:3301
#: wallet/wallet.c:3431
msgid "SELECT txid, spendheight, scriptpubkey, satoshis FROM utxoset WHERE blockheight = ? AND txindex = ? AND outnum = ? AND spendheight IS NULL"
msgstr ""
#: wallet/wallet.c:3343
#: wallet/wallet.c:3473
msgid "SELECT blockheight, txindex, outnum FROM utxoset WHERE spendheight = ?"
msgstr ""
#: wallet/wallet.c:3374 wallet/wallet.c:3534
#: wallet/wallet.c:3504 wallet/wallet.c:3664
msgid "SELECT blockheight FROM transactions WHERE id=?"
msgstr ""
#: wallet/wallet.c:3384
#: wallet/wallet.c:3514
msgid "INSERT INTO transactions ( id, blockheight, txindex, rawtx) VALUES (?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:3405
#: wallet/wallet.c:3535
msgid "UPDATE transactions SET blockheight = ?, txindex = ? WHERE id = ?"
msgstr ""
#: wallet/wallet.c:3422
#: wallet/wallet.c:3552
msgid "INSERT INTO transaction_annotations (txid, idx, location, type, channel) VALUES (?, ?, ?, ?, ?) ON CONFLICT(txid,idx) DO NOTHING;"
msgstr ""
#: wallet/wallet.c:3454
#: wallet/wallet.c:3584
msgid "SELECT type, channel_id FROM transactions WHERE id=?"
msgstr ""
#: wallet/wallet.c:3470
#: wallet/wallet.c:3600
msgid "UPDATE transactions SET type = ?, channel_id = ? WHERE id = ?"
msgstr ""
#: wallet/wallet.c:3489
#: wallet/wallet.c:3619
msgid "SELECT type FROM transactions WHERE id=?"
msgstr ""
#: wallet/wallet.c:3512
#: wallet/wallet.c:3642
msgid "SELECT rawtx FROM transactions WHERE id=?"
msgstr ""
#: wallet/wallet.c:3558
#: wallet/wallet.c:3688
msgid "SELECT blockheight, txindex FROM transactions WHERE id=?"
msgstr ""
#: wallet/wallet.c:3586
#: wallet/wallet.c:3716
msgid "SELECT id FROM transactions WHERE blockheight=?"
msgstr ""
#: wallet/wallet.c:3605
#: wallet/wallet.c:3735
msgid "INSERT INTO channeltxs ( channel_id, type, transaction_id, input_num, blockheight) VALUES (?, ?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:3629
#: wallet/wallet.c:3759
msgid "SELECT DISTINCT(channel_id) FROM channeltxs WHERE type = ?;"
msgstr ""
#: wallet/wallet.c:3650
#: wallet/wallet.c:3780
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:3695
#: wallet/wallet.c:3825
msgid "UPDATE forwarded_payments SET in_msatoshi=?, out_msatoshi=?, state=?, resolved_time=?, failcode=? WHERE in_htlc_id=?"
msgstr ""
#: wallet/wallet.c:3753
#: wallet/wallet.c:3883
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:3812
#: wallet/wallet.c:3942
msgid "SELECT CAST(COALESCE(SUM(in_msatoshi - out_msatoshi), 0) AS BIGINT)FROM forwarded_payments WHERE state = ?;"
msgstr ""
#: wallet/wallet.c:3861
#: wallet/wallet.c:3991
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:3983
#: wallet/wallet.c:4113
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:4077
#: wallet/wallet.c:4207
msgid "INSERT INTO penalty_bases ( channel_id, commitnum, txid, outnum, amount) VALUES (?, ?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:4102
#: wallet/wallet.c:4232
msgid "SELECT commitnum, txid, outnum, amount FROM penalty_bases WHERE channel_id = ?"
msgstr ""
#: wallet/wallet.c:4126
#: wallet/wallet.c:4256
msgid "DELETE FROM penalty_bases WHERE channel_id = ? AND commitnum = ?"
msgstr ""
#: wallet/wallet.c:4144
#: wallet/wallet.c:4274
msgid "SELECT 1 FROM offers WHERE offer_id = ?;"
msgstr ""
#: wallet/wallet.c:4157
#: wallet/wallet.c:4287
msgid "INSERT INTO offers ( offer_id, bolt12, label, status) VALUES (?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:4184
#: wallet/wallet.c:4314
msgid "SELECT bolt12, label, status FROM offers WHERE offer_id = ?;"
msgstr ""
#: wallet/wallet.c:4212
#: wallet/wallet.c:4342
msgid "SELECT offer_id FROM offers;"
msgstr ""
#: wallet/wallet.c:4238
#: wallet/wallet.c:4368
msgid "UPDATE offers SET status=? WHERE offer_id = ?;"
msgstr ""
#: wallet/wallet.c:4249
#: wallet/wallet.c:4379
msgid "UPDATE invoices SET state=? WHERE state=? AND local_offer_id = ?;"
msgstr ""
#: wallet/wallet.c:4277
#: wallet/wallet.c:4407
msgid "SELECT status FROM offers WHERE offer_id = ?;"
msgstr ""
@ -1183,6 +1203,10 @@ msgid "not a valid SQL statement"
msgstr ""
#: wallet/test/run-wallet.c:1399
msgid "SELECT COUNT(1) FROM channel_funding_inflights WHERE channel_id = ?;"
msgstr ""
#: wallet/test/run-wallet.c:1599
msgid "INSERT INTO channels (id) VALUES (1);"
msgstr ""
# SHA256STAMP:9cbdc346b00eec65089e37237361242a6c3afa2c50d2e4ae0210060a08f1a738
# SHA256STAMP:c2d1cde87b8704ec22eefc11c71500fc0e69897f36404be9ac2cc0b5d8312279

View file

@ -1124,11 +1124,31 @@ static bool bitcoin_tx_eq(const struct bitcoin_tx *tx1,
return eq;
}
static bool channel_inflightseq(struct channel_inflight *i1,
struct channel_inflight *i2)
{
CHECK(memeq(&i1->funding->txid,
sizeof(struct sha256_double),
&i2->funding->txid,
sizeof(struct sha256_double)));
CHECK(i1->funding->outnum == i2->funding->outnum);
CHECK(i1->funding->feerate == i2->funding->feerate);
CHECK(amount_sat_eq(i1->funding->total_funds,
i2->funding->total_funds));
CHECK(amount_sat_eq(i1->funding->our_funds, i2->funding->our_funds));
CHECK(memeq(&i1->last_sig, sizeof(i1->last_sig),
&i2->last_sig, sizeof(i2->last_sig)));
CHECK(bitcoin_tx_eq(i1->last_tx, i2->last_tx));
return true;
}
static bool channelseq(struct channel *c1, struct channel *c2)
{
struct peer *p1 = c1->peer, *p2 = c2->peer;
struct channel_info *ci1 = &c1->channel_info, *ci2 = &c2->channel_info;
struct changed_htlc *lc1 = c1->last_sent_commit, *lc2 = c2->last_sent_commit;
struct channel_inflight *i1, *i2;
CHECK(c1->dbid == c2->dbid);
CHECK(c1->first_blocknum == c2->first_blocknum);
CHECK(c1->peer->dbid == c2->peer->dbid);
@ -1190,6 +1210,20 @@ static bool channelseq(struct channel *c1, struct channel *c2)
CHECK(c1->last_was_revoke == c2->last_was_revoke);
i1 = list_top(&c1->inflights, struct channel_inflight, list);
i2 = list_top(&c2->inflights, struct channel_inflight, list);
CHECK((i1 != NULL) == (i2 != NULL));
if (!i1 && !i2)
return true;
while ((i1 = list_next(&c1->inflights, i1, list))) {
i2 = list_next(&c2->inflights, i2, list);
CHECK(i2 != NULL);
CHECK(channel_inflightseq(i1, i2));
}
/* c2 should also be out of inflights */
CHECK(list_next(&c2->inflights, i2, list) == NULL);
return true;
}
@ -1264,6 +1298,8 @@ static bool test_channel_crud(struct lightningd *ld, const tal_t *ctx)
c1.last_sig.s = *sig;
c1.last_sig.sighash_type = SIGHASH_ALL;
c1.last_tx->chainparams = chainparams_for_network("bitcoin");
/* Init channel inflights */
list_head_init(&c1.inflights);
db_begin_transaction(w->db);
CHECK(!wallet_err);
@ -1356,6 +1392,170 @@ static bool test_channel_crud(struct lightningd *ld, const tal_t *ctx)
return true;
}
static int count_inflights(struct wallet *w, u64 channel_dbid)
{
struct db_stmt *stmt;
int count;
stmt = db_prepare_v2(w->db, SQL("SELECT COUNT(1)"
" FROM channel_funding_inflights"
" WHERE channel_id = ?;"));
db_bind_u64(stmt, 0, channel_dbid);
db_query_prepared(stmt);
if (!db_step(stmt))
abort();
count = db_column_int(stmt, 0);
tal_free(stmt);
return count;
}
static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx)
{
struct wallet *w = create_test_wallet(ld, ctx);
struct channel *chan, *c2;
struct channel_inflight *inflight;
struct bitcoin_txid txid;
struct bitcoin_signature sig;
struct amount_sat funding_sats, our_sats;
struct node_id id;
struct pubkey pk;
struct wireaddr_internal addr;
struct peer *p;
struct channel_config our_config;
struct channel_id cid;
struct bitcoin_tx *last_tx;
struct wally_psbt *funding_psbt;
struct channel_info *channel_info = tal(w, struct channel_info);
struct basepoints basepoints;
u32 feerate;
u64 dbid;
pubkey_from_der(tal_hexdata(w, "02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc", 66), 33, &pk);
node_id_from_pubkey(&id, &pk);
parse_wireaddr_internal("localhost:1234", &addr, 0, false, false, false,
NULL);
/* new channel! */
p = new_peer(ld, 0, &id, &addr);
funding_sats = AMOUNT_SAT(4444444);
our_sats = AMOUNT_SAT(3333333);
mempat(&sig.s, sizeof(sig.s));
mempat(&cid, sizeof(struct channel_id));
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;
memset(&our_config, 1, sizeof(struct channel_config));
our_config.id = 0;
memset(&txid, 1, sizeof(txid));
basepoints.revocation = pk;
basepoints.payment = pk;
basepoints.htlc = pk;
basepoints.delayed_payment = pk;
memset(channel_info, 3, sizeof(*channel_info));
channel_info->their_config.id = 0;
channel_info->remote_fundingkey = pk;
channel_info->theirbase = basepoints;
channel_info->remote_per_commit = pk;
channel_info->old_remote_per_commit = pk;
chan = new_channel(p, wallet_get_channel_dbid(w),
NULL,
DUALOPEND_AWAITING_LOCKIN,
LOCAL, NULL, "billboard",
8, &our_config,
101, 1, 1, 1,
&txid, 1,
funding_sats, AMOUNT_MSAT(0),
our_sats,
false, false,
NULL,
&cid,
AMOUNT_MSAT(3333333000),
AMOUNT_MSAT(33333),
AMOUNT_MSAT(3333333333),
last_tx, &sig,
NULL,
channel_info,
new_fee_states(w, LOCAL, &feerate),
NULL, NULL,
1, false,
NULL,
100, /* first_blocknum */
100, /* min_possible_feerate */
10000, /* max_possible_feerate */
false,
&basepoints,
&pk, NULL,
1000, 100,
NULL, true, true,
NULL,
LOCAL, REASON_UNKNOWN);
db_begin_transaction(w->db);
CHECK(!wallet_err);
wallet_channel_insert(w, chan);
/* info for the inflight */
funding_sats = AMOUNT_SAT(222222);
our_sats = AMOUNT_SAT(111111);
memset(&txid, 1, sizeof(txid));
mempat(&sig.s, sizeof(sig.s));
inflight = new_inflight(chan, txid, 11, 253,
funding_sats,
our_sats,
funding_psbt,
last_tx,
sig);
/* do inflights get correctly added to the channel? */
wallet_inflight_add(w, inflight);
/* do inflights get correctly loaded from the database? */
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)");
tal_free(c2);
/* add another inflight, confirm existence */
funding_sats = AMOUNT_SAT(666666);
our_sats = AMOUNT_SAT(555555);
memset(&txid, 2, sizeof(txid));
mempat(&sig.s, sizeof(sig.s));
inflight = new_inflight(chan, txid, 111, 300,
funding_sats,
our_sats,
funding_psbt,
last_tx,
sig);
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
* correctly on save */
funding_psbt = psbt_from_b64(w, "cHNidP8BAD8CAAAAAf//////////////////////////////////////////AAAAAAD/////AQAAAAAAAAAAA2oBAAAAAAAACg8BAgMEBQYHCAkPAQIDBAUGBwgJCgsMDQ4PAAA=", strlen("cHNidP8BAD8CAAAAAf//////////////////////////////////////////AAAAAAD/////AQAAAAAAAAAAA2oBAAAAAAAACg8BAgMEBQYHCAkPAQIDBAUGBwgJCgsMDQ4PAAA="));
list_for_each(&chan->inflights, inflight, list)
inflight->funding_psbt = funding_psbt;
wallet_channel_save(w, chan);
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)");
tal_free(c2);
/* do inflights get cleared when the channel is closed?*/
dbid = chan->dbid;
delete_channel(chan); /* Also clears up peer! */
CHECK_MSG(count_inflights(w, dbid) == 0, "inflights cleaned up");
db_commit_transaction(w->db);
CHECK_MSG(!wallet_err, wallet_err);
return true;
}
static bool test_channel_config_crud(struct lightningd *ld, const tal_t *ctx)
{
struct channel_config *cc1 = talz(ctx, struct channel_config),
@ -1572,7 +1772,9 @@ int main(int argc, const char *argv[])
ok &= test_wallet_outputs(ld, tmpctx);
ok &= test_shachain_crud(ld, tmpctx);
ok &= test_channel_crud(ld, tmpctx);
ok &= test_channel_inflight_crud(ld, tmpctx);
ok &= test_channel_config_crud(ld, tmpctx);
ok &= test_channel_inflight_crud(ld, tmpctx);
ok &= test_htlc_crud(ld, tmpctx);
ok &= test_payment_crud(ld, tmpctx);
ok &= test_wallet_payment_status_enum();

View file

@ -945,6 +945,119 @@ static struct fee_states *wallet_channel_fee_states_load(struct wallet *w,
return fee_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 (?, ?, ?, ?, ?, ?, ?, ?, ?);"));
db_bind_u64(stmt, 0, inflight->channel->dbid);
db_bind_txid(stmt, 1, &inflight->funding->txid);
db_bind_int(stmt, 2, inflight->funding->outnum);
db_bind_int(stmt, 3, inflight->funding->feerate);
db_bind_amount_sat(stmt, 4, &inflight->funding->total_funds);
db_bind_amount_sat(stmt, 5, &inflight->funding->our_funds);
db_bind_psbt(stmt, 6, inflight->funding_psbt);
db_bind_tx(stmt, 7, inflight->last_tx->wtx);
db_bind_signature(stmt, 8, &inflight->last_sig.s);
db_exec_prepared_v2(stmt);
assert(!stmt->error);
tal_free(stmt);
}
void wallet_inflight_save(struct wallet *w,
struct channel_inflight *inflight)
{
struct db_stmt *stmt;
/* The *only* thing you can update on an
* inflight is the funding PSBT (to add sigs)
* ((and maybe later the last_tx/last_sig if this is for
* a splice */
stmt = db_prepare_v2(w->db,
SQL("UPDATE channel_funding_inflights SET"
" funding_psbt=?" // 0
" WHERE"
" channel_id=?" // 1
" AND funding_tx_id=?" // 2
" AND funding_tx_outnum=?")); // 3
db_bind_psbt(stmt, 0, inflight->funding_psbt);
db_bind_u64(stmt, 1, inflight->channel->dbid);
db_bind_txid(stmt, 2, &inflight->funding->txid);
db_bind_int(stmt, 3, inflight->funding->outnum);
db_exec_prepared_v2(take(stmt));
}
static struct channel_inflight *
wallet_stmt2inflight(struct wallet *w, struct db_stmt *stmt,
struct channel *chan)
{
struct amount_sat funding_sat, our_funding_sat;
struct bitcoin_txid funding_txid;
struct bitcoin_signature last_sig;
db_column_txid(stmt, 0, &funding_txid);
db_column_amount_sat(stmt, 3, &funding_sat);
db_column_amount_sat(stmt, 4, &our_funding_sat);
if (!db_column_signature(stmt, 7, &last_sig.s))
return NULL;
last_sig.sighash_type = SIGHASH_ALL;
return new_inflight(chan, funding_txid,
db_column_int(stmt, 1),
db_column_int(stmt, 2),
funding_sat,
our_funding_sat,
db_column_psbt(tmpctx, stmt, 5),
db_column_tx(tmpctx, stmt, 6),
last_sig);
}
static bool wallet_channel_load_inflights(struct wallet *w,
struct channel *chan)
{
bool ok = true;
struct db_stmt *stmt;
stmt = db_prepare_v2(w->db, SQL("SELECT"
" funding_tx_id" // 0
", funding_tx_outnum" // 1
", funding_feerate" // 2
", funding_satoshi" // 3
", our_funding_satoshi" // 4
", funding_psbt" // 5
", last_tx" // 6
", last_sig" // 7
" FROM channel_funding_inflights"
" WHERE channel_id = ?")); // ?0
db_bind_u64(stmt, 0, chan->dbid);
db_query_prepared(stmt);
while (db_step(stmt)) {
struct channel_inflight *inflight;
inflight = wallet_stmt2inflight(w, stmt, chan);
if (!inflight) {
ok = false;
break;
}
}
tal_free(stmt);
return ok;
}
/**
* wallet_stmt2channel - Helper to populate a wallet_channel from a `db_stmt`
*/
@ -1128,6 +1241,11 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
db_column_int(stmt, 52),
db_column_int(stmt, 53));
if (!wallet_channel_load_inflights(w, chan)) {
tal_free(chan);
return NULL;
}
return chan;
}
@ -1589,6 +1707,11 @@ void wallet_channel_save(struct wallet *w, struct channel *chan)
stmt = db_prepare_v2(w->db, SQL("UPDATE channels SET"
" last_sent_commit=?"
" WHERE id=?"));
/* Update the inflights also */
struct channel_inflight *inflight;
list_for_each(&chan->inflights, inflight, list)
wallet_inflight_save(w, inflight);
db_bind_talarr(stmt, 0, last_sent_commit);
db_bind_u64(stmt, 1, chan->dbid);
db_exec_prepared_v2(take(stmt));
@ -1743,6 +1866,13 @@ void wallet_channel_close(struct wallet *w, u64 wallet_id)
db_bind_u64(stmt, 0, wallet_id);
db_exec_prepared_v2(take(stmt));
/* Delete any entries from 'inflights' */
stmt = db_prepare_v2(w->db,
SQL("DELETE FROM channel_funding_inflights "
" WHERE channel_id=?"));
db_bind_u64(stmt, 0, wallet_id);
db_exec_prepared_v2(take(stmt));
/* Delete shachains */
stmt = db_prepare_v2(w->db, SQL("DELETE FROM shachains "
"WHERE id IN ("

View file

@ -26,6 +26,7 @@
struct amount_msat;
struct invoices;
struct channel;
struct channel_inflight;
struct lightningd;
struct node_id;
struct oneshot;
@ -508,6 +509,17 @@ void wallet_channel_save(struct wallet *w, struct channel *chan);
*/
void wallet_channel_insert(struct wallet *w, struct channel *chan);
/**
* Save an inflight transaction for a channel
*/
void wallet_inflight_add(struct wallet *w, struct channel_inflight *inflight);
/**
* Update an existing inflight channel transaction
*/
void wallet_inflight_save(struct wallet *w,
struct channel_inflight *inflight);
/**
* After fully resolving a channel, only keep a lightweight stub
*/