|
|
@ -29,30 +29,39 @@ void migrate_pr2342_feerate_per_channel(struct lightningd *ld, struct db *db); |
|
|
|
* migrate existing databases from a previous state, based on the |
|
|
|
* string indices */ |
|
|
|
static struct migration dbmigrations[] = { |
|
|
|
{ "CREATE TABLE version (version INTEGER)", NULL }, |
|
|
|
{ "INSERT INTO version VALUES (1)", NULL }, |
|
|
|
{ "CREATE TABLE outputs ( \
|
|
|
|
prev_out_tx CHAR(64), \ |
|
|
|
prev_out_index INTEGER, \ |
|
|
|
value INTEGER, \ |
|
|
|
type INTEGER, \ |
|
|
|
status INTEGER, \ |
|
|
|
keyindex INTEGER, \ |
|
|
|
PRIMARY KEY (prev_out_tx, prev_out_index) \ |
|
|
|
);", NULL }, |
|
|
|
{ "CREATE TABLE vars (name VARCHAR(32), val VARCHAR(255), PRIMARY KEY (name));", NULL }, |
|
|
|
{ "CREATE TABLE shachains ( \
|
|
|
|
id INTEGER, \ |
|
|
|
min_index INTEGER, \ |
|
|
|
num_valid INTEGER, \ |
|
|
|
PRIMARY KEY (id));", NULL }, |
|
|
|
{ "CREATE TABLE shachain_known ( \
|
|
|
|
shachain_id INTEGER REFERENCES shachains(id) ON DELETE CASCADE, \ |
|
|
|
pos INTEGER, \ |
|
|
|
idx INTEGER, \ |
|
|
|
hash BLOB, \ |
|
|
|
PRIMARY KEY (shachain_id, pos));", NULL }, |
|
|
|
{ "CREATE TABLE channels (" |
|
|
|
{SQL("CREATE TABLE version (version INTEGER)"), NULL}, |
|
|
|
{SQL("INSERT INTO version VALUES (1)"), NULL}, |
|
|
|
{SQL("CREATE TABLE outputs (" |
|
|
|
" prev_out_tx CHAR(64)" |
|
|
|
", prev_out_index INTEGER" |
|
|
|
", value INTEGER" |
|
|
|
", type INTEGER" |
|
|
|
", status INTEGER" |
|
|
|
", keyindex INTEGER" |
|
|
|
", PRIMARY KEY (prev_out_tx, prev_out_index));"), |
|
|
|
NULL}, |
|
|
|
{SQL("CREATE TABLE vars (" |
|
|
|
" name VARCHAR(32)" |
|
|
|
", val VARCHAR(255)" |
|
|
|
", PRIMARY KEY (name)" |
|
|
|
");"), |
|
|
|
NULL}, |
|
|
|
{SQL("CREATE TABLE shachains (" |
|
|
|
" id INTEGER" |
|
|
|
", min_index INTEGER" |
|
|
|
", num_valid INTEGER" |
|
|
|
", PRIMARY KEY (id)" |
|
|
|
");"), |
|
|
|
NULL}, |
|
|
|
{SQL("CREATE TABLE shachain_known (" |
|
|
|
" shachain_id INTEGER REFERENCES shachains(id) ON DELETE CASCADE" |
|
|
|
", pos INTEGER" |
|
|
|
", idx INTEGER" |
|
|
|
", hash BLOB" |
|
|
|
", PRIMARY KEY (shachain_id, pos)" |
|
|
|
");"), |
|
|
|
NULL}, |
|
|
|
{SQL("CREATE TABLE channels (" |
|
|
|
" id INTEGER," /* chan->id */ |
|
|
|
" peer_id INTEGER REFERENCES peers(id) ON DELETE CASCADE," |
|
|
|
" short_channel_id BLOB," |
|
|
@ -92,14 +101,16 @@ static struct migration dbmigrations[] = { |
|
|
|
" closing_fee_received INTEGER," |
|
|
|
" closing_sig_received BLOB," |
|
|
|
" PRIMARY KEY (id)" |
|
|
|
");", NULL }, |
|
|
|
{ "CREATE TABLE peers (" |
|
|
|
" id INTEGER," |
|
|
|
" node_id BLOB UNIQUE," /* pubkey */ |
|
|
|
" address TEXT," |
|
|
|
" PRIMARY KEY (id)" |
|
|
|
");", NULL }, |
|
|
|
{ "CREATE TABLE channel_configs (" |
|
|
|
");"), |
|
|
|
NULL}, |
|
|
|
{SQL("CREATE TABLE peers (" |
|
|
|
" id INTEGER" |
|
|
|
", node_id BLOB UNIQUE" /* pubkey */ |
|
|
|
", address TEXT" |
|
|
|
", PRIMARY KEY (id)" |
|
|
|
");"), |
|
|
|
NULL}, |
|
|
|
{SQL("CREATE TABLE channel_configs (" |
|
|
|
" id INTEGER," |
|
|
|
" dust_limit_satoshis INTEGER," |
|
|
|
" max_htlc_value_in_flight_msat INTEGER," |
|
|
@ -108,8 +119,9 @@ static struct migration dbmigrations[] = { |
|
|
|
" to_self_delay INTEGER," |
|
|
|
" max_accepted_htlcs INTEGER," |
|
|
|
" PRIMARY KEY (id)" |
|
|
|
");", NULL }, |
|
|
|
{ "CREATE TABLE channel_htlcs (" |
|
|
|
");"), |
|
|
|
NULL}, |
|
|
|
{SQL("CREATE TABLE channel_htlcs (" |
|
|
|
" id INTEGER," |
|
|
|
" channel_id INTEGER REFERENCES channels(id) ON DELETE CASCADE," |
|
|
|
" channel_htlc_id INTEGER," |
|
|
@ -126,8 +138,9 @@ static struct migration dbmigrations[] = { |
|
|
|
" shared_secret BLOB," |
|
|
|
" PRIMARY KEY (id)," |
|
|
|
" UNIQUE (channel_id, channel_htlc_id, direction)" |
|
|
|
");", NULL }, |
|
|
|
{ "CREATE TABLE invoices (" |
|
|
|
");"), |
|
|
|
NULL}, |
|
|
|
{SQL("CREATE TABLE invoices (" |
|
|
|
" id INTEGER," |
|
|
|
" state INTEGER," |
|
|
|
" msatoshi INTEGER," |
|
|
@ -137,8 +150,9 @@ static struct migration dbmigrations[] = { |
|
|
|
" PRIMARY KEY (id)," |
|
|
|
" UNIQUE (label)," |
|
|
|
" UNIQUE (payment_hash)" |
|
|
|
");", NULL }, |
|
|
|
{ "CREATE TABLE payments (" |
|
|
|
");"), |
|
|
|
NULL}, |
|
|
|
{SQL("CREATE TABLE payments (" |
|
|
|
" id INTEGER," |
|
|
|
" timestamp INTEGER," |
|
|
|
" status INTEGER," |
|
|
@ -148,37 +162,43 @@ static struct migration dbmigrations[] = { |
|
|
|
" msatoshi INTEGER," |
|
|
|
" PRIMARY KEY (id)," |
|
|
|
" UNIQUE (payment_hash)" |
|
|
|
");", NULL }, |
|
|
|
");"), |
|
|
|
NULL}, |
|
|
|
/* Add expiry field to invoices (effectively infinite). */ |
|
|
|
{ "ALTER TABLE invoices ADD expiry_time INTEGER;", NULL }, |
|
|
|
{ "UPDATE invoices SET expiry_time=9223372036854775807;", NULL }, |
|
|
|
{SQL("ALTER TABLE invoices ADD expiry_time INTEGER;"), NULL}, |
|
|
|
{SQL("UPDATE invoices SET expiry_time=9223372036854775807;"), NULL}, |
|
|
|
/* Add pay_index field to paid invoices (initially, same order as id). */ |
|
|
|
{ "ALTER TABLE invoices ADD pay_index INTEGER;", NULL }, |
|
|
|
{ "CREATE UNIQUE INDEX invoices_pay_index" |
|
|
|
" ON invoices(pay_index);", NULL }, |
|
|
|
{ "UPDATE invoices SET pay_index=id WHERE state=1;", NULL }, /* only paid invoice */ |
|
|
|
{SQL("ALTER TABLE invoices ADD pay_index INTEGER;"), NULL}, |
|
|
|
{SQL("CREATE UNIQUE INDEX invoices_pay_index ON invoices(pay_index);"), |
|
|
|
NULL}, |
|
|
|
{SQL("UPDATE invoices SET pay_index=id WHERE state=1;"), |
|
|
|
NULL}, /* only paid invoice */ |
|
|
|
/* Create next_pay_index variable (highest pay_index). */ |
|
|
|
{ "INSERT OR REPLACE INTO vars(name, val)" |
|
|
|
{SQL("INSERT OR REPLACE INTO vars(name, val)" |
|
|
|
" VALUES('next_pay_index', " |
|
|
|
" COALESCE((SELECT MAX(pay_index) FROM invoices WHERE state=1), 0) + 1" |
|
|
|
" );", NULL }, |
|
|
|
" COALESCE((SELECT MAX(pay_index) FROM invoices WHERE state=1), 0) " |
|
|
|
"+ 1" |
|
|
|
" );"), |
|
|
|
NULL}, |
|
|
|
/* Create first_block field; initialize from channel id if any.
|
|
|
|
* This fails for channels still awaiting lockin, but that only applies to |
|
|
|
* pre-release software, so it's forgivable. */ |
|
|
|
{ "ALTER TABLE channels ADD first_blocknum INTEGER;", NULL }, |
|
|
|
{ "UPDATE channels SET first_blocknum=CAST(short_channel_id AS INTEGER) WHERE short_channel_id IS NOT NULL;", NULL }, |
|
|
|
{ "ALTER TABLE outputs ADD COLUMN channel_id INTEGER;", NULL }, |
|
|
|
{ "ALTER TABLE outputs ADD COLUMN peer_id BLOB;", NULL }, |
|
|
|
{ "ALTER TABLE outputs ADD COLUMN commitment_point BLOB;", NULL }, |
|
|
|
{ "ALTER TABLE invoices ADD COLUMN msatoshi_received INTEGER;", NULL }, |
|
|
|
{SQL("ALTER TABLE channels ADD first_blocknum INTEGER;"), NULL}, |
|
|
|
{SQL("UPDATE channels SET first_blocknum=CAST(short_channel_id AS INTEGER) " |
|
|
|
"WHERE short_channel_id IS NOT NULL;"), |
|
|
|
NULL}, |
|
|
|
{SQL("ALTER TABLE outputs ADD COLUMN channel_id INTEGER;"), NULL}, |
|
|
|
{SQL("ALTER TABLE outputs ADD COLUMN peer_id BLOB;"), NULL}, |
|
|
|
{SQL("ALTER TABLE outputs ADD COLUMN commitment_point BLOB;"), NULL}, |
|
|
|
{SQL("ALTER TABLE invoices ADD COLUMN msatoshi_received INTEGER;"), NULL}, |
|
|
|
/* Normally impossible, so at least we'll know if databases are ancient. */ |
|
|
|
{ "UPDATE invoices SET msatoshi_received=0 WHERE state=1;", NULL }, |
|
|
|
{ "ALTER TABLE channels ADD COLUMN last_was_revoke INTEGER;", NULL }, |
|
|
|
{SQL("UPDATE invoices SET msatoshi_received=0 WHERE state=1;"), NULL}, |
|
|
|
{SQL("ALTER TABLE channels ADD COLUMN last_was_revoke INTEGER;"), NULL}, |
|
|
|
/* We no longer record incoming payments: invoices cover that.
|
|
|
|
* Without ALTER_TABLE DROP COLUMN support we need to do this by |
|
|
|
* rename & copy, which works because there are no triggers etc. */ |
|
|
|
{ "ALTER TABLE payments RENAME TO temp_payments;", NULL }, |
|
|
|
{ "CREATE TABLE payments (" |
|
|
|
{SQL("ALTER TABLE payments RENAME TO temp_payments;"), NULL}, |
|
|
|
{SQL("CREATE TABLE payments (" |
|
|
|
" id INTEGER," |
|
|
|
" timestamp INTEGER," |
|
|
|
" status INTEGER," |
|
|
@ -187,41 +207,53 @@ static struct migration dbmigrations[] = { |
|
|
|
" msatoshi INTEGER," |
|
|
|
" PRIMARY KEY (id)," |
|
|
|
" UNIQUE (payment_hash)" |
|
|
|
");", NULL }, |
|
|
|
{ "INSERT INTO payments SELECT id, timestamp, status, payment_hash, destination, msatoshi FROM temp_payments WHERE direction=1;", NULL }, |
|
|
|
{ "DROP TABLE temp_payments;", NULL }, |
|
|
|
");"), |
|
|
|
NULL}, |
|
|
|
{SQL("INSERT INTO payments SELECT id, timestamp, status, payment_hash, " |
|
|
|
"destination, msatoshi FROM temp_payments WHERE direction=1;"), |
|
|
|
NULL}, |
|
|
|
{SQL("DROP TABLE temp_payments;"), NULL}, |
|
|
|
/* We need to keep the preimage in case they ask to pay again. */ |
|
|
|
{ "ALTER TABLE payments ADD COLUMN payment_preimage BLOB;", NULL }, |
|
|
|
{SQL("ALTER TABLE payments ADD COLUMN payment_preimage BLOB;"), NULL}, |
|
|
|
/* We need to keep the shared secrets to decode error returns. */ |
|
|
|
{ "ALTER TABLE payments ADD COLUMN path_secrets BLOB;", NULL }, |
|
|
|
{SQL("ALTER TABLE payments ADD COLUMN path_secrets BLOB;"), NULL}, |
|
|
|
/* Create time-of-payment of invoice, default already-paid
|
|
|
|
* invoices to current time. */ |
|
|
|
{ "ALTER TABLE invoices ADD paid_timestamp INTEGER;", NULL }, |
|
|
|
{ "UPDATE invoices" |
|
|
|
{SQL("ALTER TABLE invoices ADD paid_timestamp INTEGER;"), NULL}, |
|
|
|
{SQL("UPDATE invoices" |
|
|
|
" SET paid_timestamp = strftime('%s', 'now')" |
|
|
|
" WHERE state = 1;", NULL }, |
|
|
|
" WHERE state = 1;"), |
|
|
|
NULL}, |
|
|
|
/* We need to keep the route node pubkeys and short channel ids to
|
|
|
|
* correctly mark routing failures. We separate short channel ids |
|
|
|
* because we cannot safely save them as blobs due to byteorder |
|
|
|
* concerns. */ |
|
|
|
{ "ALTER TABLE payments ADD COLUMN route_nodes BLOB;", NULL }, |
|
|
|
{ "ALTER TABLE payments ADD COLUMN route_channels TEXT;", NULL }, |
|
|
|
{ "CREATE TABLE htlc_sigs (channelid INTEGER REFERENCES channels(id) ON DELETE CASCADE, signature BLOB);", NULL }, |
|
|
|
{ "CREATE INDEX channel_idx ON htlc_sigs (channelid)", NULL }, |
|
|
|
{SQL("ALTER TABLE payments ADD COLUMN route_nodes BLOB;"), NULL}, |
|
|
|
{SQL("ALTER TABLE payments ADD COLUMN route_channels TEXT;"), NULL}, |
|
|
|
{SQL("CREATE TABLE htlc_sigs (channelid INTEGER REFERENCES channels(id) ON " |
|
|
|
"DELETE CASCADE, signature BLOB);"), |
|
|
|
NULL}, |
|
|
|
{SQL("CREATE INDEX channel_idx ON htlc_sigs (channelid)"), NULL}, |
|
|
|
/* Get rid of OPENINGD entries; we don't put them in db any more */ |
|
|
|
{ "DELETE FROM channels WHERE state=1", NULL }, |
|
|
|
{SQL("DELETE FROM channels WHERE state=1"), NULL}, |
|
|
|
/* Keep track of db upgrades, for debugging */ |
|
|
|
{ "CREATE TABLE db_upgrades (upgrade_from INTEGER, lightning_version TEXT);", NULL }, |
|
|
|
{SQL("CREATE TABLE db_upgrades (upgrade_from INTEGER, lightning_version " |
|
|
|
"TEXT);"), |
|
|
|
NULL}, |
|
|
|
/* We used not to clean up peers when their channels were gone. */ |
|
|
|
{ "DELETE FROM peers WHERE id NOT IN (SELECT peer_id FROM channels);", NULL }, |
|
|
|
/* The ONCHAIND_CHEATED/THEIR_UNILATERAL/OUR_UNILATERAL/MUTUAL are now one */ |
|
|
|
{ "UPDATE channels SET STATE = 8 WHERE state > 8;", NULL }, |
|
|
|
{SQL("DELETE FROM peers WHERE id NOT IN (SELECT peer_id FROM channels);"), |
|
|
|
NULL}, |
|
|
|
/* The ONCHAIND_CHEATED/THEIR_UNILATERAL/OUR_UNILATERAL/MUTUAL are now one
|
|
|
|
*/ |
|
|
|
{SQL("UPDATE channels SET STATE = 8 WHERE state > 8;"), NULL}, |
|
|
|
/* Add bolt11 to invoices table*/ |
|
|
|
{ "ALTER TABLE invoices ADD bolt11 TEXT;", NULL }, |
|
|
|
{SQL("ALTER TABLE invoices ADD bolt11 TEXT;"), NULL}, |
|
|
|
/* What do we think the head of the blockchain looks like? Used
|
|
|
|
* primarily to track confirmations across restarts and making |
|
|
|
* sure we handle reorgs correctly. */ |
|
|
|
{ "CREATE TABLE blocks (height INT, hash BLOB, prev_hash BLOB, UNIQUE(height));", NULL }, |
|
|
|
{SQL("CREATE TABLE blocks (height INT, hash BLOB, prev_hash BLOB, " |
|
|
|
"UNIQUE(height));"), |
|
|
|
NULL}, |
|
|
|
/* ON DELETE CASCADE would have been nice for confirmation_height,
|
|
|
|
* so that we automatically delete outputs that fall off the |
|
|
|
* blockchain and then we rediscover them if they are included |
|
|
@ -229,11 +261,17 @@ static struct migration dbmigrations[] = { |
|
|
|
* can't simply recognize from the chain without additional |
|
|
|
* hints. So we just mark them as unconfirmed should the block |
|
|
|
* die. */ |
|
|
|
{ "ALTER TABLE outputs ADD COLUMN confirmation_height INTEGER REFERENCES blocks(height) ON DELETE SET NULL;", NULL }, |
|
|
|
{ "ALTER TABLE outputs ADD COLUMN spend_height INTEGER REFERENCES blocks(height) ON DELETE SET NULL;", NULL }, |
|
|
|
{SQL("ALTER TABLE outputs ADD COLUMN confirmation_height INTEGER " |
|
|
|
"REFERENCES blocks(height) ON DELETE SET NULL;"), |
|
|
|
NULL}, |
|
|
|
{SQL("ALTER TABLE outputs ADD COLUMN spend_height INTEGER REFERENCES " |
|
|
|
"blocks(height) ON DELETE SET NULL;"), |
|
|
|
NULL}, |
|
|
|
/* Create a covering index that covers both fields */ |
|
|
|
{ "CREATE INDEX output_height_idx ON outputs (confirmation_height, spend_height);", NULL }, |
|
|
|
{ "CREATE TABLE utxoset (" |
|
|
|
{SQL("CREATE INDEX output_height_idx ON outputs (confirmation_height, " |
|
|
|
"spend_height);"), |
|
|
|
NULL}, |
|
|
|
{SQL("CREATE TABLE utxoset (" |
|
|
|
" txid BLOB," |
|
|
|
" outnum INT," |
|
|
|
" blockheight INT REFERENCES blocks(height) ON DELETE CASCADE," |
|
|
@ -241,88 +279,105 @@ static struct migration dbmigrations[] = { |
|
|
|
" txindex INT," |
|
|
|
" scriptpubkey BLOB," |
|
|
|
" satoshis BIGINT," |
|
|
|
" PRIMARY KEY(txid, outnum));", NULL }, |
|
|
|
{ "CREATE INDEX short_channel_id ON utxoset (blockheight, txindex, outnum)", NULL }, |
|
|
|
" PRIMARY KEY(txid, outnum));"), |
|
|
|
NULL}, |
|
|
|
{SQL("CREATE INDEX short_channel_id ON utxoset (blockheight, txindex, " |
|
|
|
"outnum)"), |
|
|
|
NULL}, |
|
|
|
/* Necessary index for long rollbacks of the blockchain, otherwise we're
|
|
|
|
* doing table scans for every block removed. */ |
|
|
|
{ "CREATE INDEX utxoset_spend ON utxoset (spendheight)", NULL }, |
|
|
|
{SQL("CREATE INDEX utxoset_spend ON utxoset (spendheight)"), NULL}, |
|
|
|
/* Assign key 0 to unassigned shutdown_keyidx_local. */ |
|
|
|
{ "UPDATE channels SET shutdown_keyidx_local=0 WHERE shutdown_keyidx_local = -1;", NULL }, |
|
|
|
{SQL("UPDATE channels SET shutdown_keyidx_local=0 WHERE " |
|
|
|
"shutdown_keyidx_local = -1;"), |
|
|
|
NULL}, |
|
|
|
/* FIXME: We should rename shutdown_keyidx_local to final_key_index */ |
|
|
|
/* -- Payment routing failure information -- */ |
|
|
|
/* BLOB if failure was due to unparseable onion, NULL otherwise */ |
|
|
|
{ "ALTER TABLE payments ADD failonionreply BLOB;", NULL }, |
|
|
|
{SQL("ALTER TABLE payments ADD failonionreply BLOB;"), NULL}, |
|
|
|
/* 0 if we could theoretically retry, 1 if PERM fail at payee */ |
|
|
|
{ "ALTER TABLE payments ADD faildestperm INTEGER;", NULL }, |
|
|
|
{SQL("ALTER TABLE payments ADD faildestperm INTEGER;"), NULL}, |
|
|
|
/* Contents of routing_failure (only if not unparseable onion) */ |
|
|
|
{ "ALTER TABLE payments ADD failindex INTEGER;", NULL }, /* erring_index */ |
|
|
|
{ "ALTER TABLE payments ADD failcode INTEGER;", NULL }, /* failcode */ |
|
|
|
{ "ALTER TABLE payments ADD failnode BLOB;", NULL }, /* erring_node */ |
|
|
|
{ "ALTER TABLE payments ADD failchannel BLOB;", NULL }, /* erring_channel */ |
|
|
|
{ "ALTER TABLE payments ADD failupdate BLOB;", NULL }, /* channel_update - can be NULL*/ |
|
|
|
{SQL("ALTER TABLE payments ADD failindex INTEGER;"), |
|
|
|
NULL}, /* erring_index */ |
|
|
|
{SQL("ALTER TABLE payments ADD failcode INTEGER;"), NULL}, /* failcode */ |
|
|
|
{SQL("ALTER TABLE payments ADD failnode BLOB;"), NULL}, /* erring_node */ |
|
|
|
{SQL("ALTER TABLE payments ADD failchannel BLOB;"), |
|
|
|
NULL}, /* erring_channel */ |
|
|
|
{SQL("ALTER TABLE payments ADD failupdate BLOB;"), |
|
|
|
NULL}, /* channel_update - can be NULL*/ |
|
|
|
/* -- Payment routing failure information ends -- */ |
|
|
|
/* Delete route data for already succeeded or failed payments */ |
|
|
|
{ "UPDATE payments" |
|
|
|
{SQL("UPDATE payments" |
|
|
|
" SET path_secrets = NULL" |
|
|
|
" , route_nodes = NULL" |
|
|
|
" , route_channels = NULL" |
|
|
|
" WHERE status <> 0;", NULL }, /* PAYMENT_PENDING */ |
|
|
|
" WHERE status <> 0;"), |
|
|
|
NULL}, /* PAYMENT_PENDING */ |
|
|
|
/* -- Routing statistics -- */ |
|
|
|
{ "ALTER TABLE channels ADD in_payments_offered INTEGER;", NULL }, |
|
|
|
{ "ALTER TABLE channels ADD in_payments_fulfilled INTEGER;", NULL }, |
|
|
|
{ "ALTER TABLE channels ADD in_msatoshi_offered INTEGER;", NULL }, |
|
|
|
{ "ALTER TABLE channels ADD in_msatoshi_fulfilled INTEGER;", NULL }, |
|
|
|
{ "ALTER TABLE channels ADD out_payments_offered INTEGER;", NULL }, |
|
|
|
{ "ALTER TABLE channels ADD out_payments_fulfilled INTEGER;", NULL }, |
|
|
|
{ "ALTER TABLE channels ADD out_msatoshi_offered INTEGER;", NULL }, |
|
|
|
{ "ALTER TABLE channels ADD out_msatoshi_fulfilled INTEGER;", NULL }, |
|
|
|
{ "UPDATE channels" |
|
|
|
{SQL("ALTER TABLE channels ADD in_payments_offered INTEGER;"), NULL}, |
|
|
|
{SQL("ALTER TABLE channels ADD in_payments_fulfilled INTEGER;"), NULL}, |
|
|
|
{SQL("ALTER TABLE channels ADD in_msatoshi_offered INTEGER;"), NULL}, |
|
|
|
{SQL("ALTER TABLE channels ADD in_msatoshi_fulfilled INTEGER;"), NULL}, |
|
|
|
{SQL("ALTER TABLE channels ADD out_payments_offered INTEGER;"), NULL}, |
|
|
|
{SQL("ALTER TABLE channels ADD out_payments_fulfilled INTEGER;"), NULL}, |
|
|
|
{SQL("ALTER TABLE channels ADD out_msatoshi_offered INTEGER;"), NULL}, |
|
|
|
{SQL("ALTER TABLE channels ADD out_msatoshi_fulfilled INTEGER;"), NULL}, |
|
|
|
{SQL("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" |
|
|
|
" ;", NULL }, |
|
|
|
" ;"), |
|
|
|
NULL}, |
|
|
|
/* -- Routing statistics ends --*/ |
|
|
|
/* Record the msatoshi actually sent in a payment. */ |
|
|
|
{ "ALTER TABLE payments ADD msatoshi_sent INTEGER;", NULL }, |
|
|
|
{ "UPDATE payments SET msatoshi_sent = msatoshi;", NULL }, |
|
|
|
{SQL("ALTER TABLE payments ADD msatoshi_sent INTEGER;"), NULL}, |
|
|
|
{SQL("UPDATE payments SET msatoshi_sent = msatoshi;"), NULL}, |
|
|
|
/* Delete dangling utxoset entries due to Issue #1280 */ |
|
|
|
{ "DELETE FROM utxoset WHERE blockheight IN (" |
|
|
|
{SQL("DELETE FROM utxoset WHERE blockheight IN (" |
|
|
|
" SELECT DISTINCT(blockheight)" |
|
|
|
" FROM utxoset LEFT OUTER JOIN blocks on (blockheight == blocks.height) " |
|
|
|
" FROM utxoset LEFT OUTER JOIN blocks on (blockheight == " |
|
|
|
"blocks.height) " |
|
|
|
" WHERE blocks.hash IS NULL" |
|
|
|
");", NULL }, |
|
|
|
");"), |
|
|
|
NULL}, |
|
|
|
/* Record feerate range, to optimize onchaind grinding actual fees. */ |
|
|
|
{ "ALTER TABLE channels ADD min_possible_feerate INTEGER;", NULL }, |
|
|
|
{ "ALTER TABLE channels ADD max_possible_feerate INTEGER;", NULL }, |
|
|
|
{SQL("ALTER TABLE channels ADD min_possible_feerate INTEGER;"), NULL}, |
|
|
|
{SQL("ALTER TABLE channels ADD max_possible_feerate INTEGER;"), NULL}, |
|
|
|
/* https://bitcoinfees.github.io/#1d says Dec 17 peak was ~1M sat/kb
|
|
|
|
* which is 250,000 sat/Sipa */ |
|
|
|
{ "UPDATE channels SET min_possible_feerate=0, max_possible_feerate=250000;", NULL }, |
|
|
|
{SQL("UPDATE channels SET min_possible_feerate=0, " |
|
|
|
"max_possible_feerate=250000;"), |
|
|
|
NULL}, |
|
|
|
/* -- Min and max msatoshi_to_us -- */ |
|
|
|
{ "ALTER TABLE channels ADD msatoshi_to_us_min INTEGER;", NULL }, |
|
|
|
{ "ALTER TABLE channels ADD msatoshi_to_us_max INTEGER;", NULL }, |
|
|
|
{ "UPDATE channels" |
|
|
|
{SQL("ALTER TABLE channels ADD msatoshi_to_us_min INTEGER;"), NULL}, |
|
|
|
{SQL("ALTER TABLE channels ADD msatoshi_to_us_max INTEGER;"), NULL}, |
|
|
|
{SQL("UPDATE channels" |
|
|
|
" SET msatoshi_to_us_min = msatoshi_local" |
|
|
|
" , msatoshi_to_us_max = msatoshi_local" |
|
|
|
" ;", NULL }, |
|
|
|
" ;"), |
|
|
|
NULL}, |
|
|
|
/* -- Min and max msatoshi_to_us ends -- */ |
|
|
|
/* Transactions we are interested in. Either we sent them ourselves or we
|
|
|
|
* are watching them. We don't cascade block height deletes so we don't |
|
|
|
* forget any of them by accident.*/ |
|
|
|
{ "CREATE TABLE transactions (" |
|
|
|
{SQL("CREATE TABLE transactions (" |
|
|
|
" id BLOB" |
|
|
|
", blockheight INTEGER REFERENCES blocks(height) ON DELETE SET NULL" |
|
|
|
", txindex INTEGER" |
|
|
|
", rawtx BLOB" |
|
|
|
", PRIMARY KEY (id)" |
|
|
|
");", NULL }, |
|
|
|
");"), |
|
|
|
NULL}, |
|
|
|
/* -- Detailed payment failure -- */ |
|
|
|
{ "ALTER TABLE payments ADD faildetail TEXT;", NULL }, |
|
|
|
{ "UPDATE payments" |
|
|
|
{SQL("ALTER TABLE payments ADD faildetail TEXT;"), NULL}, |
|
|
|
{SQL("UPDATE payments" |
|
|
|
" SET faildetail = 'unspecified payment failure reason'" |
|
|
|
" WHERE status = 2;", NULL }, /* PAYMENT_FAILED */ |
|
|
|
" WHERE status = 2;"), |
|
|
|
NULL}, /* PAYMENT_FAILED */ |
|
|
|
/* -- Detailed payment faiure ends -- */ |
|
|
|
{ "CREATE TABLE channeltxs (" |
|
|
|
{SQL("CREATE TABLE channeltxs (" |
|
|
|
/* The id serves as insertion order and short ID */ |
|
|
|
" id INTEGER" |
|
|
|
", channel_id INTEGER REFERENCES channels(id) ON DELETE CASCADE" |
|
|
@ -333,29 +388,34 @@ static struct migration dbmigrations[] = { |
|
|
|
/* The height at which we sent the depth notice */ |
|
|
|
", blockheight INTEGER REFERENCES blocks(height) ON DELETE CASCADE" |
|
|
|
", PRIMARY KEY(id)" |
|
|
|
");", NULL }, |
|
|
|
");"), |
|
|
|
NULL}, |
|
|
|
/* -- Set the correct rescan height for PR #1398 -- */ |
|
|
|
/* Delete blocks that are higher than our initial scan point, this is a
|
|
|
|
* no-op if we don't have a channel. */ |
|
|
|
{ "DELETE FROM blocks WHERE height > (SELECT MIN(first_blocknum) FROM channels);", NULL }, |
|
|
|
{SQL("DELETE FROM blocks WHERE height > (SELECT MIN(first_blocknum) FROM " |
|
|
|
"channels);"), |
|
|
|
NULL}, |
|
|
|
/* Now make sure we have the lower bound block with the first_blocknum
|
|
|
|
* height. This may introduce a block with NULL height if we didn't have any |
|
|
|
* blocks, remove that in the next. */ |
|
|
|
{ "INSERT OR IGNORE INTO blocks (height) VALUES ((SELECT MIN(first_blocknum) FROM channels));", NULL }, |
|
|
|
{ "DELETE FROM blocks WHERE height IS NULL;", NULL }, |
|
|
|
{SQL("INSERT OR IGNORE INTO blocks (height) VALUES ((SELECT " |
|
|
|
"MIN(first_blocknum) FROM channels));"), |
|
|
|
NULL}, |
|
|
|
{SQL("DELETE FROM blocks WHERE height IS NULL;"), NULL}, |
|
|
|
/* -- End of PR #1398 -- */ |
|
|
|
{ "ALTER TABLE invoices ADD description TEXT;", NULL }, |
|
|
|
{SQL("ALTER TABLE invoices ADD description TEXT;"), NULL}, |
|
|
|
/* FIXME: payments table 'description' is really a 'label' */ |
|
|
|
{ "ALTER TABLE payments ADD description TEXT;", NULL }, |
|
|
|
{SQL("ALTER TABLE payments ADD description TEXT;"), NULL}, |
|
|
|
/* future_per_commitment_point if other side proves we're out of date -- */ |
|
|
|
{ "ALTER TABLE channels ADD future_per_commitment_point BLOB;", NULL }, |
|
|
|
{SQL("ALTER TABLE channels ADD future_per_commitment_point BLOB;"), NULL}, |
|
|
|
/* last_sent_commit array fix */ |
|
|
|
{ "ALTER TABLE channels ADD last_sent_commit BLOB;", NULL }, |
|
|
|
{SQL("ALTER TABLE channels ADD last_sent_commit BLOB;"), NULL}, |
|
|
|
/* Stats table to track forwarded HTLCs. The values in the HTLCs
|
|
|
|
* and their states are replicated here and the entries are not |
|
|
|
* deleted when the HTLC entries or the channel entries are |
|
|
|
* deleted to avoid unexpected drops in statistics. */ |
|
|
|
{ "CREATE TABLE forwarded_payments (" |
|
|
|
{SQL("CREATE TABLE forwarded_payments (" |
|
|
|
" in_htlc_id INTEGER REFERENCES channel_htlcs(id) ON DELETE SET NULL" |
|
|
|
", out_htlc_id INTEGER REFERENCES channel_htlcs(id) ON DELETE SET NULL" |
|
|
|
", in_channel_scid INTEGER" |
|
|
@ -364,34 +424,38 @@ static struct migration dbmigrations[] = { |
|
|
|
", out_msatoshi INTEGER" |
|
|
|
", state INTEGER" |
|
|
|
", UNIQUE(in_htlc_id, out_htlc_id)" |
|
|
|
");", NULL }, |
|
|
|
");"), |
|
|
|
NULL}, |
|
|
|
/* Add a direction for failed payments. */ |
|
|
|
{ "ALTER TABLE payments ADD faildirection INTEGER;", NULL }, /* erring_direction */ |
|
|
|
{SQL("ALTER TABLE payments ADD faildirection INTEGER;"), |
|
|
|
NULL}, /* erring_direction */ |
|
|
|
/* Fix dangling peers with no channels. */ |
|
|
|
{ "DELETE FROM peers WHERE id NOT IN (SELECT peer_id FROM channels);", NULL }, |
|
|
|
{ "ALTER TABLE outputs ADD scriptpubkey BLOB;", NULL }, |
|
|
|
{SQL("DELETE FROM peers WHERE id NOT IN (SELECT peer_id FROM channels);"), |
|
|
|
NULL}, |
|
|
|
{SQL("ALTER TABLE outputs ADD scriptpubkey BLOB;"), NULL}, |
|
|
|
/* Keep bolt11 string for payments. */ |
|
|
|
{ "ALTER TABLE payments ADD bolt11 TEXT;", NULL }, |
|
|
|
{SQL("ALTER TABLE payments ADD bolt11 TEXT;"), NULL}, |
|
|
|
/* PR #2342 feerate per channel */ |
|
|
|
{ "ALTER TABLE channels ADD feerate_base INTEGER;", NULL }, |
|
|
|
{ "ALTER TABLE channels ADD feerate_ppm INTEGER;", NULL }, |
|
|
|
{ NULL, migrate_pr2342_feerate_per_channel }, |
|
|
|
{ "ALTER TABLE channel_htlcs ADD received_time INTEGER", NULL }, |
|
|
|
{ "ALTER TABLE forwarded_payments ADD received_time INTEGER", NULL }, |
|
|
|
{ "ALTER TABLE forwarded_payments ADD resolved_time INTEGER", NULL }, |
|
|
|
{ "ALTER TABLE channels ADD remote_upfront_shutdown_script BLOB;", NULL }, |
|
|
|
{SQL("ALTER TABLE channels ADD feerate_base INTEGER;"), NULL}, |
|
|
|
{SQL("ALTER TABLE channels ADD feerate_ppm INTEGER;"), NULL}, |
|
|
|
{NULL, migrate_pr2342_feerate_per_channel}, |
|
|
|
{SQL("ALTER TABLE channel_htlcs ADD received_time INTEGER"), NULL}, |
|
|
|
{SQL("ALTER TABLE forwarded_payments ADD received_time INTEGER"), NULL}, |
|
|
|
{SQL("ALTER TABLE forwarded_payments ADD resolved_time INTEGER"), NULL}, |
|
|
|
{SQL("ALTER TABLE channels ADD remote_upfront_shutdown_script BLOB;"), |
|
|
|
NULL}, |
|
|
|
/* PR #2524: Add failcode into forward_payment */ |
|
|
|
{ "ALTER TABLE forwarded_payments ADD failcode INTEGER;", NULL }, |
|
|
|
{SQL("ALTER TABLE forwarded_payments ADD failcode INTEGER;"), NULL}, |
|
|
|
/* remote signatures for channel announcement */ |
|
|
|
{ "ALTER TABLE channels ADD remote_ann_node_sig BLOB;", NULL }, |
|
|
|
{ "ALTER TABLE channels ADD remote_ann_bitcoin_sig BLOB;", NULL }, |
|
|
|
{SQL("ALTER TABLE channels ADD remote_ann_node_sig BLOB;"), NULL}, |
|
|
|
{SQL("ALTER TABLE channels ADD remote_ann_bitcoin_sig BLOB;"), NULL}, |
|
|
|
/* Additional information for transaction tracking and listing */ |
|
|
|
{ "ALTER TABLE transactions ADD type INTEGER;", NULL }, |
|
|
|
{SQL("ALTER TABLE transactions ADD type INTEGER;"), NULL}, |
|
|
|
/* Not a foreign key on purpose since we still delete channels from
|
|
|
|
* the DB which would remove this. It is mainly used to group payments |
|
|
|
* in the list view anyway, e.g., show all close and htlc transactions |
|
|
|
* as a single bundle. */ |
|
|
|
{ "ALTER TABLE transactions ADD channel_id INTEGER;", NULL}, |
|
|
|
{SQL("ALTER TABLE transactions ADD channel_id INTEGER;"), NULL}, |
|
|
|
}; |
|
|
|
|
|
|
|
/* Leak tracking. */ |
|
|
|