diff --git a/lightningd/channel.c b/lightningd/channel.c index d5045af36..71c413628 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -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; diff --git a/lightningd/channel.h b/lightningd/channel.h index 273d6062a..12acf0527 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -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); diff --git a/wallet/db.c b/wallet/db.c index fa513eb1b..23bb46df1 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -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. */ diff --git a/wallet/db_postgres_sqlgen.c b/wallet/db_postgres_sqlgen.c index 00ec570d9..6a8a611a1 100644 --- a/wallet/db_postgres_sqlgen.c +++ b/wallet/db_postgres_sqlgen.c @@ -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 diff --git a/wallet/db_sqlite3_sqlgen.c b/wallet/db_sqlite3_sqlgen.c index 64dcd03d0..c4efce576 100644 --- a/wallet/db_sqlite3_sqlgen.c +++ b/wallet/db_sqlite3_sqlgen.c @@ -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 diff --git a/wallet/statements.po b/wallet/statements.po new file mode 100644 index 000000000..c124b231a --- /dev/null +++ b/wallet/statements.po @@ -0,0 +1,1039 @@ +#: wallet/db.c:29 +msgid "CREATE TABLE version (version INTEGER)" +msgstr "" + +#: wallet/db.c:30 +msgid "INSERT INTO version VALUES (1)" +msgstr "" + +#: wallet/db.c:31 +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:40 +msgid "CREATE TABLE vars ( name VARCHAR(32), val VARCHAR(255), PRIMARY KEY (name));" +msgstr "" + +#: wallet/db.c:46 +msgid "CREATE TABLE shachains ( id BIGSERIAL, min_index BIGINT, num_valid BIGINT, PRIMARY KEY (id));" +msgstr "" + +#: wallet/db.c:53 +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:61 +msgid "CREATE TABLE peers ( id BIGSERIAL, node_id BLOB UNIQUE, address TEXT, PRIMARY KEY (id));" +msgstr "" + +#: wallet/db.c:68 +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:110 +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:121 +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:141 +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:153 +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:166 +msgid "ALTER TABLE invoices ADD expiry_time BIGINT;" +msgstr "" + +#: wallet/db.c:167 +msgid "UPDATE invoices SET expiry_time=9223372036854775807;" +msgstr "" + +#: wallet/db.c:169 +msgid "ALTER TABLE invoices ADD pay_index BIGINT;" +msgstr "" + +#: wallet/db.c:170 +msgid "CREATE UNIQUE INDEX invoices_pay_index ON invoices(pay_index);" +msgstr "" + +#: wallet/db.c:172 +msgid "UPDATE invoices SET pay_index=id WHERE state=1;" +msgstr "" + +#: wallet/db.c:175 +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:184 +msgid "ALTER TABLE channels ADD first_blocknum BIGINT;" +msgstr "" + +#: wallet/db.c:185 +msgid "UPDATE channels SET first_blocknum=1 WHERE short_channel_id IS NOT NULL;" +msgstr "" + +#: wallet/db.c:187 +msgid "ALTER TABLE outputs ADD COLUMN channel_id BIGINT;" +msgstr "" + +#: wallet/db.c:188 +msgid "ALTER TABLE outputs ADD COLUMN peer_id BLOB;" +msgstr "" + +#: wallet/db.c:189 +msgid "ALTER TABLE outputs ADD COLUMN commitment_point BLOB;" +msgstr "" + +#: wallet/db.c:190 +msgid "ALTER TABLE invoices ADD COLUMN msatoshi_received BIGINT;" +msgstr "" + +#: wallet/db.c:192 +msgid "UPDATE invoices SET msatoshi_received=0 WHERE state=1;" +msgstr "" + +#: wallet/db.c:193 +msgid "ALTER TABLE channels ADD COLUMN last_was_revoke INTEGER;" +msgstr "" + +#: wallet/db.c:197 wallet/db.c:490 +msgid "ALTER TABLE payments RENAME TO temp_payments;" +msgstr "" + +#: wallet/db.c:198 +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:209 +msgid "INSERT INTO payments SELECT id, timestamp, status, payment_hash, destination, msatoshi FROM temp_payments WHERE direction=1;" +msgstr "" + +#: wallet/db.c:212 wallet/db.c:565 +msgid "DROP TABLE temp_payments;" +msgstr "" + +#: wallet/db.c:214 +msgid "ALTER TABLE payments ADD COLUMN payment_preimage BLOB;" +msgstr "" + +#: wallet/db.c:216 +msgid "ALTER TABLE payments ADD COLUMN path_secrets BLOB;" +msgstr "" + +#: wallet/db.c:219 +msgid "ALTER TABLE invoices ADD paid_timestamp BIGINT;" +msgstr "" + +#: wallet/db.c:220 +msgid "UPDATE invoices SET paid_timestamp = CURRENT_TIMESTAMP() WHERE state = 1;" +msgstr "" + +#: wallet/db.c:228 +msgid "ALTER TABLE payments ADD COLUMN route_nodes BLOB;" +msgstr "" + +#: wallet/db.c:229 +msgid "ALTER TABLE payments ADD COLUMN route_channels BLOB;" +msgstr "" + +#: wallet/db.c:230 +msgid "CREATE TABLE htlc_sigs (channelid INTEGER REFERENCES channels(id) ON DELETE CASCADE, signature BLOB);" +msgstr "" + +#: wallet/db.c:233 +msgid "CREATE INDEX channel_idx ON htlc_sigs (channelid)" +msgstr "" + +#: wallet/db.c:235 +msgid "DELETE FROM channels WHERE state=1" +msgstr "" + +#: wallet/db.c:237 +msgid "CREATE TABLE db_upgrades (upgrade_from INTEGER, lightning_version TEXT);" +msgstr "" + +#: wallet/db.c:241 wallet/db.c:431 +msgid "DELETE FROM peers WHERE id NOT IN (SELECT peer_id FROM channels);" +msgstr "" + +#: wallet/db.c:245 +msgid "UPDATE channels SET STATE = 8 WHERE state > 8;" +msgstr "" + +#: wallet/db.c:247 +msgid "ALTER TABLE invoices ADD bolt11 TEXT;" +msgstr "" + +#: wallet/db.c:251 +msgid "CREATE TABLE blocks (height INT, hash BLOB, prev_hash BLOB, UNIQUE(height));" +msgstr "" + +#: wallet/db.c:261 +msgid "ALTER TABLE outputs ADD COLUMN confirmation_height INTEGER REFERENCES blocks(height) ON DELETE SET NULL;" +msgstr "" + +#: wallet/db.c:264 +msgid "ALTER TABLE outputs ADD COLUMN spend_height INTEGER REFERENCES blocks(height) ON DELETE SET NULL;" +msgstr "" + +#: wallet/db.c:268 +msgid "CREATE INDEX output_height_idx ON outputs (confirmation_height, spend_height);" +msgstr "" + +#: wallet/db.c:271 +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:281 +msgid "CREATE INDEX short_channel_id ON utxoset (blockheight, txindex, outnum)" +msgstr "" + +#: wallet/db.c:286 +msgid "CREATE INDEX utxoset_spend ON utxoset (spendheight)" +msgstr "" + +#: wallet/db.c:288 +msgid "UPDATE channels SET shutdown_keyidx_local=0 WHERE shutdown_keyidx_local = -1;" +msgstr "" + +#: wallet/db.c:294 +msgid "ALTER TABLE payments ADD failonionreply BLOB;" +msgstr "" + +#: wallet/db.c:296 +msgid "ALTER TABLE payments ADD faildestperm INTEGER;" +msgstr "" + +#: wallet/db.c:298 +msgid "ALTER TABLE payments ADD failindex INTEGER;" +msgstr "" + +#: wallet/db.c:300 +msgid "ALTER TABLE payments ADD failcode INTEGER;" +msgstr "" + +#: wallet/db.c:301 +msgid "ALTER TABLE payments ADD failnode BLOB;" +msgstr "" + +#: wallet/db.c:302 +msgid "ALTER TABLE payments ADD failchannel TEXT;" +msgstr "" + +#: wallet/db.c:304 +msgid "ALTER TABLE payments ADD failupdate BLOB;" +msgstr "" + +#: wallet/db.c:308 +msgid "UPDATE payments SET path_secrets = NULL , route_nodes = NULL , route_channels = NULL WHERE status <> 0;" +msgstr "" + +#: wallet/db.c:315 +msgid "ALTER TABLE channels ADD in_payments_offered INTEGER DEFAULT 0;" +msgstr "" + +#: wallet/db.c:316 +msgid "ALTER TABLE channels ADD in_payments_fulfilled INTEGER DEFAULT 0;" +msgstr "" + +#: wallet/db.c:317 +msgid "ALTER TABLE channels ADD in_msatoshi_offered BIGINT DEFAULT 0;" +msgstr "" + +#: wallet/db.c:318 +msgid "ALTER TABLE channels ADD in_msatoshi_fulfilled BIGINT DEFAULT 0;" +msgstr "" + +#: wallet/db.c:319 +msgid "ALTER TABLE channels ADD out_payments_offered INTEGER DEFAULT 0;" +msgstr "" + +#: wallet/db.c:320 +msgid "ALTER TABLE channels ADD out_payments_fulfilled INTEGER DEFAULT 0;" +msgstr "" + +#: wallet/db.c:321 +msgid "ALTER TABLE channels ADD out_msatoshi_offered BIGINT DEFAULT 0;" +msgstr "" + +#: wallet/db.c:322 +msgid "ALTER TABLE channels ADD out_msatoshi_fulfilled BIGINT DEFAULT 0;" +msgstr "" + +#: wallet/db.c:323 +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:332 +msgid "ALTER TABLE payments ADD msatoshi_sent BIGINT;" +msgstr "" + +#: wallet/db.c:333 +msgid "UPDATE payments SET msatoshi_sent = msatoshi;" +msgstr "" + +#: wallet/db.c:335 +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:343 +msgid "ALTER TABLE channels ADD min_possible_feerate INTEGER;" +msgstr "" + +#: wallet/db.c:344 +msgid "ALTER TABLE channels ADD max_possible_feerate INTEGER;" +msgstr "" + +#: wallet/db.c:347 +msgid "UPDATE channels SET min_possible_feerate=0, max_possible_feerate=250000;" +msgstr "" + +#: wallet/db.c:351 +msgid "ALTER TABLE channels ADD msatoshi_to_us_min BIGINT;" +msgstr "" + +#: wallet/db.c:352 +msgid "ALTER TABLE channels ADD msatoshi_to_us_max BIGINT;" +msgstr "" + +#: wallet/db.c:353 +msgid "UPDATE channels SET msatoshi_to_us_min = msatoshi_local , msatoshi_to_us_max = msatoshi_local ;" +msgstr "" + +#: wallet/db.c:362 +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:371 +msgid "ALTER TABLE payments ADD faildetail TEXT;" +msgstr "" + +#: wallet/db.c:372 +msgid "UPDATE payments SET faildetail = 'unspecified payment failure reason' WHERE status = 2;" +msgstr "" + +#: wallet/db.c:377 +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:393 +msgid "DELETE FROM blocks WHERE height > (SELECT MIN(first_blocknum) FROM channels);" +msgstr "" + +#: wallet/db.c:399 +msgid "INSERT INTO blocks (height) VALUES ((SELECT MIN(first_blocknum) FROM channels)) ON CONFLICT(height) DO NOTHING;" +msgstr "" + +#: wallet/db.c:403 +msgid "DELETE FROM blocks WHERE height IS NULL;" +msgstr "" + +#: wallet/db.c:405 +msgid "ALTER TABLE invoices ADD description TEXT;" +msgstr "" + +#: wallet/db.c:407 +msgid "ALTER TABLE payments ADD description TEXT;" +msgstr "" + +#: wallet/db.c:409 +msgid "ALTER TABLE channels ADD future_per_commitment_point BLOB;" +msgstr "" + +#: wallet/db.c:411 +msgid "ALTER TABLE channels ADD last_sent_commit BLOB;" +msgstr "" + +#: wallet/db.c:416 +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:428 +msgid "ALTER TABLE payments ADD faildirection INTEGER;" +msgstr "" + +#: wallet/db.c:433 +msgid "ALTER TABLE outputs ADD scriptpubkey BLOB;" +msgstr "" + +#: wallet/db.c:435 +msgid "ALTER TABLE payments ADD bolt11 TEXT;" +msgstr "" + +#: wallet/db.c:437 +msgid "ALTER TABLE channels ADD feerate_base INTEGER;" +msgstr "" + +#: wallet/db.c:438 +msgid "ALTER TABLE channels ADD feerate_ppm INTEGER;" +msgstr "" + +#: wallet/db.c:440 +msgid "ALTER TABLE channel_htlcs ADD received_time BIGINT" +msgstr "" + +#: wallet/db.c:441 +msgid "ALTER TABLE forwarded_payments ADD received_time BIGINT" +msgstr "" + +#: wallet/db.c:442 +msgid "ALTER TABLE forwarded_payments ADD resolved_time BIGINT" +msgstr "" + +#: wallet/db.c:443 +msgid "ALTER TABLE channels ADD remote_upfront_shutdown_script BLOB;" +msgstr "" + +#: wallet/db.c:446 +msgid "ALTER TABLE forwarded_payments ADD failcode INTEGER;" +msgstr "" + +#: wallet/db.c:448 +msgid "ALTER TABLE channels ADD remote_ann_node_sig BLOB;" +msgstr "" + +#: wallet/db.c:449 +msgid "ALTER TABLE channels ADD remote_ann_bitcoin_sig BLOB;" +msgstr "" + +#: wallet/db.c:451 +msgid "ALTER TABLE transactions ADD type BIGINT;" +msgstr "" + +#: wallet/db.c:456 +msgid "ALTER TABLE transactions ADD channel_id BIGINT;" +msgstr "" + +#: wallet/db.c:458 +msgid "UPDATE channels SET short_channel_id = REPLACE(short_channel_id, ':', 'x') WHERE short_channel_id IS NOT NULL;" +msgstr "" + +#: wallet/db.c:461 +msgid "UPDATE payments SET failchannel = REPLACE(failchannel, ':', 'x') WHERE failchannel IS NOT NULL;" +msgstr "" + +#: wallet/db.c:464 +msgid "ALTER TABLE channels ADD COLUMN option_static_remotekey INTEGER DEFAULT 0;" +msgstr "" + +#: wallet/db.c:466 +msgid "ALTER TABLE vars ADD COLUMN intval INTEGER" +msgstr "" + +#: wallet/db.c:467 +msgid "ALTER TABLE vars ADD COLUMN blobval BLOB" +msgstr "" + +#: wallet/db.c:468 +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:469 +msgid "UPDATE vars SET blobval = CAST(val AS BLOB) WHERE name = 'genesis_hash'" +msgstr "" + +#: wallet/db.c:470 +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:482 +msgid "ALTER TABLE channels ADD shutdown_scriptpubkey_local BLOB;" +msgstr "" + +#: wallet/db.c:485 +msgid "UPDATE forwarded_payments SET received_time=0 WHERE received_time IS NULL;" +msgstr "" + +#: wallet/db.c:487 +msgid "ALTER TABLE invoices ADD COLUMN features BLOB DEFAULT '';" +msgstr "" + +#: wallet/db.c:491 +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:518 +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:563 +msgid "UPDATE payments SET total_msat = msatoshi;" +msgstr "" + +#: wallet/db.c:564 +msgid "UPDATE payments SET partid = 0;" +msgstr "" + +#: wallet/db.c:566 +msgid "ALTER TABLE channel_htlcs ADD partid BIGINT;" +msgstr "" + +#: wallet/db.c:567 +msgid "UPDATE channel_htlcs SET partid = 0;" +msgstr "" + +#: wallet/db.c:568 +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:579 +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:583 +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:588 +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:592 +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:596 +msgid "INSERT INTO vars (name, intval) VALUES ('data_version', 0);" +msgstr "" + +#: wallet/db.c:599 +msgid "ALTER TABLE channel_htlcs ADD localfailmsg BLOB;" +msgstr "" + +#: wallet/db.c:600 +msgid "UPDATE channel_htlcs SET localfailmsg=decode('2002', 'hex') WHERE malformed_onion != 0 AND direction = 1;" +msgstr "" + +#: wallet/db.c:601 +msgid "ALTER TABLE channels ADD our_funding_satoshi BIGINT DEFAULT 0;" +msgstr "" + +#: wallet/db.c:602 +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:612 +msgid "ALTER TABLE channel_htlcs ADD we_filled INTEGER;" +msgstr "" + +#: wallet/db.c:614 +msgid "INSERT INTO vars (name, intval) VALUES ('coin_moves_count', 0);" +msgstr "" + +#: wallet/db.c:841 +msgid "UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = ?" +msgstr "" + +#: wallet/db.c:941 +msgid "SELECT version FROM version LIMIT 1" +msgstr "" + +#: wallet/db.c:998 +msgid "UPDATE version SET version=?;" +msgstr "" + +#: wallet/db.c:1006 +msgid "INSERT INTO db_upgrades VALUES (?, ?);" +msgstr "" + +#: wallet/db.c:1018 +msgid "SELECT intval FROM vars WHERE name = 'data_version'" +msgstr "" + +#: wallet/db.c:1044 +msgid "SELECT intval FROM vars WHERE name= ? LIMIT 1" +msgstr "" + +#: wallet/db.c:1060 +msgid "UPDATE vars SET intval=? WHERE name=?;" +msgstr "" + +#: wallet/db.c:1069 +msgid "INSERT INTO vars (name, intval) VALUES (?, ?);" +msgstr "" + +#: wallet/db.c:1082 +msgid "UPDATE channels SET feerate_base = ?, feerate_ppm = ?;" +msgstr "" + +#: wallet/db.c:1102 +msgid "UPDATE channels SET our_funding_satoshi = funding_satoshi WHERE funder = 0;" +msgstr "" + +#: wallet/invoices.c:129 +msgid "UPDATE invoices SET state = ? WHERE state = ? AND expiry_time <= ?;" +msgstr "" + +#: wallet/invoices.c:177 +msgid "SELECT id FROM invoices WHERE state = ? AND expiry_time <= ?" +msgstr "" + +#: wallet/invoices.c:216 +msgid "SELECT MIN(expiry_time) FROM invoices WHERE state = ?;" +msgstr "" + +#: wallet/invoices.c:282 +msgid "INSERT INTO invoices ( payment_hash, payment_key, state , msatoshi, label, expiry_time , pay_index, msatoshi_received , paid_timestamp, bolt11, description, features) VALUES ( ?, ?, ? , ?, ?, ? , NULL, NULL , NULL, ?, ?, ?);" +msgstr "" + +#: wallet/invoices.c:330 +msgid "SELECT id FROM invoices WHERE label = ?;" +msgstr "" + +#: wallet/invoices.c:352 +msgid "SELECT id FROM invoices WHERE payment_hash = ?;" +msgstr "" + +#: wallet/invoices.c:373 +msgid "SELECT id FROM invoices WHERE payment_hash = ? AND state = ?;" +msgstr "" + +#: wallet/invoices.c:397 +msgid "DELETE FROM invoices WHERE id=?;" +msgstr "" + +#: wallet/invoices.c:417 +msgid "DELETE FROM invoices WHERE state = ? AND expiry_time <= ?;" +msgstr "" + +#: wallet/invoices.c:431 +msgid "SELECT state, payment_key, payment_hash, label, msatoshi, expiry_time, pay_index, msatoshi_received, paid_timestamp, bolt11, description, features FROM invoices;" +msgstr "" + +#: wallet/invoices.c:487 +msgid "SELECT state FROM invoices WHERE id = ?;" +msgstr "" + +#: wallet/invoices.c:514 +msgid "UPDATE invoices SET state=? , pay_index=? , msatoshi_received=? , paid_timestamp=? WHERE id=?;" +msgstr "" + +#: wallet/invoices.c:570 +msgid "SELECT id FROM invoices WHERE pay_index IS NOT NULL AND pay_index > ? ORDER BY pay_index ASC LIMIT 1;" +msgstr "" + +#: wallet/invoices.c:619 +msgid "SELECT state, payment_key, payment_hash, label, msatoshi, expiry_time, pay_index, msatoshi_received, paid_timestamp, bolt11, description, features FROM invoices WHERE id = ?;" +msgstr "" + +#: wallet/wallet.c:46 +msgid "SELECT txid, outnum FROM utxoset WHERE spendheight is NULL" +msgstr "" + +#: wallet/wallet.c:81 +msgid "SELECT * from outputs WHERE prev_out_tx=? AND prev_out_index=?" +msgstr "" + +#: wallet/wallet.c:95 +msgid "INSERT INTO outputs ( prev_out_tx, prev_out_index, value, type, status, keyindex, channel_id, peer_id, commitment_point, confirmation_height, spend_height, scriptpubkey) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" +msgstr "" + +#: wallet/wallet.c:211 +msgid "UPDATE outputs SET status=? WHERE status=? AND prev_out_tx=? AND prev_out_index=?" +msgstr "" + +#: wallet/wallet.c:219 +msgid "UPDATE outputs SET status=? WHERE prev_out_tx=? AND prev_out_index=?" +msgstr "" + +#: wallet/wallet.c:238 +msgid "SELECT prev_out_tx, prev_out_index, value, type, status, keyindex, channel_id, peer_id, commitment_point, confirmation_height, spend_height, scriptpubkey FROM outputs" +msgstr "" + +#: wallet/wallet.c:253 +msgid "SELECT prev_out_tx, prev_out_index, value, type, status, keyindex, channel_id, peer_id, commitment_point, confirmation_height, spend_height, scriptpubkey FROM outputs WHERE status= ? " +msgstr "" + +#: wallet/wallet.c:289 +msgid "SELECT prev_out_tx, prev_out_index, value, type, status, keyindex, channel_id, peer_id, commitment_point, confirmation_height, spend_height, scriptpubkey FROM outputs WHERE channel_id IS NOT NULL AND confirmation_height IS NULL" +msgstr "" + +#: wallet/wallet.c:324 +msgid "SELECT prev_out_tx, prev_out_index, value, type, status, keyindex, channel_id, peer_id, commitment_point, confirmation_height, spend_height, scriptpubkey FROM outputs WHERE prev_out_tx = ? AND prev_out_index = ?" +msgstr "" + +#: wallet/wallet.c:663 +msgid "INSERT INTO shachains (min_index, num_valid) VALUES (?, 0);" +msgstr "" + +#: wallet/wallet.c:707 +msgid "UPDATE shachains SET num_valid=?, min_index=? WHERE id=?" +msgstr "" + +#: wallet/wallet.c:714 +msgid "UPDATE shachain_known SET idx=?, hash=? WHERE shachain_id=? AND pos=?" +msgstr "" + +#: wallet/wallet.c:726 +msgid "INSERT INTO shachain_known (shachain_id, pos, idx, hash) VALUES (?, ?, ?, ?);" +msgstr "" + +#: wallet/wallet.c:748 +msgid "SELECT min_index, num_valid FROM shachains WHERE id=?" +msgstr "" + +#: wallet/wallet.c:763 +msgid "SELECT idx, hash, pos FROM shachain_known WHERE shachain_id=?" +msgstr "" + +#: wallet/wallet.c:786 +msgid "SELECT id, node_id, address FROM peers WHERE id=?;" +msgstr "" + +#: wallet/wallet.c:815 +msgid "SELECT signature FROM htlc_sigs WHERE channelid = ?" +msgstr "" + +#: wallet/wallet.c:839 +msgid "SELECT remote_ann_node_sig, remote_ann_bitcoin_sig FROM channels WHERE id = ?" +msgstr "" + +#: wallet/wallet.c:883 +msgid "SELECT hstate, feerate_per_kw FROM channel_feerates WHERE channel_id = ?" +msgstr "" + +#: wallet/wallet.c:1085 +msgid "SELECT id FROM channels ORDER BY id DESC LIMIT 1;" +msgstr "" + +#: wallet/wallet.c:1102 +msgid "SELECT id, peer_id, short_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, option_static_remotekey, shutdown_scriptpubkey_local FROM channels WHERE state < ?;" +msgstr "" + +#: wallet/wallet.c:1189 +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:1194 +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:1199 +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:1204 +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:1246 +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:1275 +msgid "SELECT MIN(height), MAX(height) FROM blocks;" +msgstr "" + +#: wallet/wallet.c:1297 +msgid "INSERT INTO channel_configs DEFAULT VALUES;" +msgstr "" + +#: wallet/wallet.c:1309 +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:1333 +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:1367 +msgid "UPDATE channels SET remote_ann_node_sig=?, remote_ann_bitcoin_sig=? WHERE id=?" +msgstr "" + +#: wallet/wallet.c:1386 +msgid "UPDATE channels SET shachain_remote_id=?, short_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=?, option_static_remotekey=?, shutdown_scriptpubkey_local=? WHERE id=?" +msgstr "" + +#: wallet/wallet.c:1472 +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:1499 +msgid "DELETE FROM channel_feerates WHERE channel_id=?" +msgstr "" + +#: wallet/wallet.c:1509 +msgid "INSERT INTO channel_feerates VALUES(?, ?, ?)" +msgstr "" + +#: wallet/wallet.c:1523 +msgid "UPDATE channels SET last_sent_commit=? WHERE id=?" +msgstr "" + +#: wallet/wallet.c:1543 +msgid "INSERT INTO peers (node_id, address) VALUES (?, ?);" +msgstr "" + +#: wallet/wallet.c:1555 +msgid "INSERT INTO channels (peer_id, first_blocknum, id) VALUES (?, ?, ?);" +msgstr "" + +#: wallet/wallet.c:1581 +msgid "DELETE FROM channel_htlcs WHERE channel_id=?" +msgstr "" + +#: wallet/wallet.c:1587 +msgid "DELETE FROM htlc_sigs WHERE channelid=?" +msgstr "" + +#: wallet/wallet.c:1593 +msgid "DELETE FROM channeltxs WHERE channel_id=?" +msgstr "" + +#: wallet/wallet.c:1599 +msgid "DELETE FROM shachains WHERE id IN ( SELECT shachain_remote_id FROM channels WHERE channels.id=?)" +msgstr "" + +#: wallet/wallet.c:1609 +msgid "UPDATE channels SET state=?, peer_id=?WHERE channels.id=?" +msgstr "" + +#: wallet/wallet.c:1623 +msgid "SELECT * FROM channels WHERE peer_id = ?;" +msgstr "" + +#: wallet/wallet.c:1631 +msgid "DELETE FROM peers WHERE id=?" +msgstr "" + +#: wallet/wallet.c:1642 +msgid "UPDATE outputs SET confirmation_height = ? WHERE prev_out_tx = ?" +msgstr "" + +#: wallet/wallet.c:1743 +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:1796 +msgid "INSERT INTO channel_htlcs ( channel_id, channel_htlc_id, direction, origin_htlc, msatoshi, cltv_expiry, payment_hash, payment_key, hstate, routing_onion, partid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" +msgstr "" + +#: wallet/wallet.c:1856 +msgid "UPDATE channel_htlcs SET hstate=?, payment_key=?, malformed_onion=?, failuremsg=?, localfailmsg=?, we_filled=? WHERE id=?" +msgstr "" + +#: wallet/wallet.c:2075 +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:2122 +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:2252 +msgid "SELECT channel_id, direction, cltv_expiry, channel_htlc_id, payment_hash FROM channel_htlcs WHERE channel_id = ?;" +msgstr "" + +#: wallet/wallet.c:2286 +msgid "DELETE FROM channel_htlcs WHERE direction = ? AND origin_htlc = ? AND payment_hash = ? AND partid = ?;" +msgstr "" + +#: wallet/wallet.c:2339 +msgid "SELECT status FROM payments WHERE payment_hash=? AND partid = ?;" +msgstr "" + +#: wallet/wallet.c:2357 +msgid "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" +msgstr "" + +#: wallet/wallet.c:2440 +msgid "DELETE FROM payments WHERE payment_hash = ? AND partid = ?" +msgstr "" + +#: wallet/wallet.c:2530 +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 FROM payments WHERE payment_hash = ? AND partid = ?" +msgstr "" + +#: wallet/wallet.c:2579 +msgid "UPDATE payments SET status=? WHERE payment_hash=? AND partid=?" +msgstr "" + +#: wallet/wallet.c:2589 +msgid "UPDATE payments SET payment_preimage=? WHERE payment_hash=? AND partid=?" +msgstr "" + +#: wallet/wallet.c:2599 +msgid "UPDATE payments SET path_secrets = NULL , route_nodes = NULL , route_channels = NULL WHERE payment_hash = ? AND partid = ?;" +msgstr "" + +#: wallet/wallet.c:2631 +msgid "SELECT failonionreply, faildestperm, failindex, failcode, failnode, failchannel, failupdate, faildetail, faildirection FROM payments WHERE payment_hash=? AND partid=?;" +msgstr "" + +#: wallet/wallet.c:2698 +msgid "UPDATE payments SET failonionreply=? , faildestperm=? , failindex=? , failcode=? , failnode=? , failchannel=? , failupdate=? , faildetail=? , faildirection=? WHERE payment_hash=? AND partid=?;" +msgstr "" + +#: wallet/wallet.c:2762 +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 FROM payments WHERE payment_hash = ?;" +msgstr "" + +#: wallet/wallet.c:2783 +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 FROM payments;" +msgstr "" + +#: wallet/wallet.c:2826 +msgid "DELETE FROM htlc_sigs WHERE channelid = ?" +msgstr "" + +#: wallet/wallet.c:2833 +msgid "INSERT INTO htlc_sigs (channelid, signature) VALUES (?, ?)" +msgstr "" + +#: wallet/wallet.c:2845 +msgid "SELECT blobval FROM vars WHERE name='genesis_hash'" +msgstr "" + +#: wallet/wallet.c:2869 +msgid "INSERT INTO vars (name, blobval) VALUES ('genesis_hash', ?);" +msgstr "" + +#: wallet/wallet.c:2887 +msgid "SELECT txid, outnum FROM utxoset WHERE spendheight < ?" +msgstr "" + +#: wallet/wallet.c:2899 +msgid "DELETE FROM utxoset WHERE spendheight < ?" +msgstr "" + +#: wallet/wallet.c:2907 wallet/wallet.c:3051 +msgid "INSERT INTO blocks (height, hash, prev_hash) VALUES (?, ?, ?);" +msgstr "" + +#: wallet/wallet.c:2926 +msgid "DELETE FROM blocks WHERE hash = ?" +msgstr "" + +#: wallet/wallet.c:2932 +msgid "SELECT * FROM blocks WHERE height >= ?;" +msgstr "" + +#: wallet/wallet.c:2941 +msgid "DELETE FROM blocks WHERE height > ?" +msgstr "" + +#: wallet/wallet.c:2957 +msgid "UPDATE outputs SET spend_height = ? WHERE prev_out_tx = ? AND prev_out_index = ?" +msgstr "" + +#: wallet/wallet.c:2973 +msgid "UPDATE utxoset SET spendheight = ? WHERE txid = ? AND outnum = ?" +msgstr "" + +#: wallet/wallet.c:2992 +msgid "SELECT blockheight, txindex FROM utxoset WHERE txid = ? AND outnum = ?" +msgstr "" + +#: wallet/wallet.c:3024 wallet/wallet.c:3062 +msgid "INSERT INTO utxoset ( txid, outnum, blockheight, spendheight, txindex, scriptpubkey, satoshis) VALUES(?, ?, ?, ?, ?, ?, ?);" +msgstr "" + +#: wallet/wallet.c:3089 +msgid "SELECT height FROM blocks WHERE height = ?" +msgstr "" + +#: wallet/wallet.c:3102 +msgid "SELECT txid, spendheight, scriptpubkey, satoshis FROM utxoset WHERE blockheight = ? AND txindex = ? AND outnum = ? AND spendheight IS NULL" +msgstr "" + +#: wallet/wallet.c:3144 wallet/wallet.c:3304 +msgid "SELECT blockheight FROM transactions WHERE id=?" +msgstr "" + +#: wallet/wallet.c:3154 +msgid "INSERT INTO transactions ( id, blockheight, txindex, rawtx) VALUES (?, ?, ?, ?);" +msgstr "" + +#: wallet/wallet.c:3175 +msgid "UPDATE transactions SET blockheight = ?, txindex = ? WHERE id = ?" +msgstr "" + +#: wallet/wallet.c:3192 +msgid "INSERT INTO transaction_annotations (txid, idx, location, type, channel) VALUES (?, ?, ?, ?, ?) ON CONFLICT(txid,idx) DO NOTHING;" +msgstr "" + +#: wallet/wallet.c:3224 +msgid "SELECT type, channel_id FROM transactions WHERE id=?" +msgstr "" + +#: wallet/wallet.c:3240 +msgid "UPDATE transactions SET type = ?, channel_id = ? WHERE id = ?" +msgstr "" + +#: wallet/wallet.c:3259 +msgid "SELECT type FROM transactions WHERE id=?" +msgstr "" + +#: wallet/wallet.c:3282 +msgid "SELECT rawtx FROM transactions WHERE id=?" +msgstr "" + +#: wallet/wallet.c:3328 +msgid "SELECT blockheight, txindex FROM transactions WHERE id=?" +msgstr "" + +#: wallet/wallet.c:3356 +msgid "SELECT id FROM transactions WHERE blockheight=?" +msgstr "" + +#: wallet/wallet.c:3375 +msgid "INSERT INTO channeltxs ( channel_id, type, transaction_id, input_num, blockheight) VALUES (?, ?, ?, ?, ?);" +msgstr "" + +#: wallet/wallet.c:3399 +msgid "SELECT DISTINCT(channel_id) FROM channeltxs WHERE type = ?;" +msgstr "" + +#: wallet/wallet.c:3420 +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:3465 +msgid "UPDATE forwarded_payments SET in_msatoshi=?, out_msatoshi=?, state=?, resolved_time=?, failcode=? WHERE in_htlc_id=?" +msgstr "" + +#: wallet/wallet.c:3523 +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:3582 +msgid "SELECT CAST(COALESCE(SUM(in_msatoshi - out_msatoshi), 0) AS BIGINT)FROM forwarded_payments WHERE state = ?;" +msgstr "" + +#: wallet/wallet.c:3606 +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)" +msgstr "" + +#: wallet/wallet.c:3769 +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:3863 +msgid "INSERT INTO penalty_bases ( channel_id, commitnum, txid, outnum, amount) VALUES (?, ?, ?, ?, ?);" +msgstr "" + +#: wallet/wallet.c:3888 +msgid "SELECT commitnum, txid, outnum, amount FROM penalty_bases WHERE channel_id = ?" +msgstr "" + +#: wallet/wallet.c:3912 +msgid "DELETE FROM penalty_bases WHERE channel_id = ? AND commitnum = ?" +msgstr "" + +#: wallet/test/run-db.c:101 +msgid "SELECT name FROM sqlite_master WHERE type='table';" +msgstr "" + +#: wallet/test/run-db.c:106 +msgid "not a valid SQL statement" +msgstr "" + +#: wallet/test/run-wallet.c:1315 +msgid "INSERT INTO channels (id) VALUES (1);" +msgstr "" diff --git a/wallet/statements_gettextgen.po b/wallet/statements_gettextgen.po index d8f70759f..349590e17 100644 --- a/wallet/statements_gettextgen.po +++ b/wallet/statements_gettextgen.po @@ -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 diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 6a1520573..62e195b2f 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -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(); diff --git a/wallet/wallet.c b/wallet/wallet.c index ba5761e25..4d014e771 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -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 (" diff --git a/wallet/wallet.h b/wallet/wallet.h index eaff0adce..8a7e28ff4 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -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 */