chaintopology: tell gossipd that channels no longer exist on reorg.

This actually caused the flake in test_funding_reorg_private, where
l1 and l2 might not mark the original channel disabled.  In fact, they
should *remove* it as it gets reorged out.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2021-08-12 12:35:55 +09:30
parent 405b914dd9
commit 66af5f8a28
7 changed files with 108 additions and 50 deletions

View File

@ -870,6 +870,7 @@ static void remove_tip(struct chain_topology *topo)
struct block *b = topo->tip;
struct bitcoin_txid *txs;
size_t i, n;
const struct short_channel_id *removed_scids;
log_debug(topo->log, "Removing stale block %u: %s",
topo->tip->height,
@ -890,11 +891,20 @@ static void remove_tip(struct chain_topology *topo)
for (i = 0; i < n; i++)
txwatch_fire(topo, &txs[i], 0);
/* Grab these before we delete block from db */
removed_scids = wallet_utxoset_get_created(tmpctx, topo->ld->wallet,
b->height);
wallet_block_remove(topo->ld->wallet, b);
/* This may have unconfirmed txs: reconfirm as we add blocks. */
watch_for_utxo_reconfirmation(topo, topo->ld->wallet);
block_map_del(&topo->block_map, b);
tal_free(b);
/* These no longer exist, so gossipd drops any reference to them just
* as if they were spent. */
for (size_t i=0; i<tal_count(removed_scids); i++)
gossipd_notify_spend(topo->bitcoind->ld, &removed_scids[i]);
}
static void get_new_block(struct bitcoind *bitcoind,

View File

@ -1195,8 +1195,9 @@ def test_funding_reorg_private(node_factory, bitcoind):
l2.daemon.wait_for_logs([r'Removing stale block {}'.format(106),
r'Got depth change .->{} for .* REORG'.format(0)])
wait_for(lambda: chan_active(l2, '106x1x0', False))
# New one should replace old.
wait_for(lambda: chan_active(l2, '108x1x0', True))
assert l2.rpc.listchannels('106x1x0')['channels'] == []
l1.rpc.close(l2.info['id'])
bitcoind.generate_block(1, True)
@ -1241,8 +1242,8 @@ def test_funding_reorg_remote_lags(node_factory, bitcoind):
# Unblinding l2 brings it back in sync, restarts channeld and sends its announce sig
l2.daemon.rpcproxy.mock_rpc('getblockhash', None)
wait_for(lambda: chan_active(l2, '103x1x0', False))
wait_for(lambda: chan_active(l2, '104x1x0', True))
assert l2.rpc.listchannels('103x1x0')['channels'] == []
wait_for(lambda: only_one(l2.rpc.listpeers()['peers'][0]['channels'])['status'] == [
'CHANNELD_NORMAL:Reconnected, and reestablished.',

View File

@ -1826,6 +1826,12 @@ struct db_query db_postgres_queries[] = {
.placeholders = 1,
.readonly = true,
},
{
.name = "SELECT blockheight, txindex, outnum FROM utxoset WHERE blockheight = ?",
.query = "SELECT blockheight, txindex, outnum FROM utxoset WHERE blockheight = $1",
.placeholders = 1,
.readonly = true,
},
{
.name = "SELECT blockheight FROM transactions WHERE id=?",
.query = "SELECT blockheight FROM transactions WHERE id=$1",
@ -2020,10 +2026,10 @@ struct db_query db_postgres_queries[] = {
},
};
#define DB_POSTGRES_QUERY_COUNT 335
#define DB_POSTGRES_QUERY_COUNT 336
#endif /* HAVE_POSTGRES */
#endif /* LIGHTNINGD_WALLET_GEN_DB_POSTGRES */
// SHA256STAMP:27a166e040e517422e91cf7ffbd12426b34337b8d75f82d7aa4c448beae5e821
// SHA256STAMP:df06b800543e6bb886100ca428247ac1097f749098779dae43ba875154700f58

View File

@ -1826,6 +1826,12 @@ struct db_query db_sqlite3_queries[] = {
.placeholders = 1,
.readonly = true,
},
{
.name = "SELECT blockheight, txindex, outnum FROM utxoset WHERE blockheight = ?",
.query = "SELECT blockheight, txindex, outnum FROM utxoset WHERE blockheight = ?",
.placeholders = 1,
.readonly = true,
},
{
.name = "SELECT blockheight FROM transactions WHERE id=?",
.query = "SELECT blockheight FROM transactions WHERE id=?",
@ -2020,10 +2026,10 @@ struct db_query db_sqlite3_queries[] = {
},
};
#define DB_SQLITE3_QUERY_COUNT 335
#define DB_SQLITE3_QUERY_COUNT 336
#endif /* HAVE_SQLITE3 */
#endif /* LIGHTNINGD_WALLET_GEN_DB_SQLITE3 */
// SHA256STAMP:27a166e040e517422e91cf7ffbd12426b34337b8d75f82d7aa4c448beae5e821
// SHA256STAMP:df06b800543e6bb886100ca428247ac1097f749098779dae43ba875154700f58

View File

@ -1206,119 +1206,123 @@ msgstr ""
msgid "SELECT txid, spendheight, scriptpubkey, satoshis FROM utxoset WHERE blockheight = ? AND txindex = ? AND outnum = ? AND spendheight IS NULL"
msgstr ""
#: wallet/wallet.c:3746
#: wallet/wallet.c:3768
msgid "SELECT blockheight, txindex, outnum FROM utxoset WHERE spendheight = ?"
msgstr ""
#: wallet/wallet.c:3777 wallet/wallet.c:3937
#: wallet/wallet.c:3785
msgid "SELECT blockheight, txindex, outnum FROM utxoset WHERE blockheight = ?"
msgstr ""
#: wallet/wallet.c:3802 wallet/wallet.c:3962
msgid "SELECT blockheight FROM transactions WHERE id=?"
msgstr ""
#: wallet/wallet.c:3787
#: wallet/wallet.c:3812
msgid "INSERT INTO transactions ( id, blockheight, txindex, rawtx) VALUES (?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:3808
#: wallet/wallet.c:3833
msgid "UPDATE transactions SET blockheight = ?, txindex = ? WHERE id = ?"
msgstr ""
#: wallet/wallet.c:3825
#: wallet/wallet.c:3850
msgid "INSERT INTO transaction_annotations (txid, idx, location, type, channel) VALUES (?, ?, ?, ?, ?) ON CONFLICT(txid,idx) DO NOTHING;"
msgstr ""
#: wallet/wallet.c:3857
#: wallet/wallet.c:3882
msgid "SELECT type, channel_id FROM transactions WHERE id=?"
msgstr ""
#: wallet/wallet.c:3873
#: wallet/wallet.c:3898
msgid "UPDATE transactions SET type = ?, channel_id = ? WHERE id = ?"
msgstr ""
#: wallet/wallet.c:3892
#: wallet/wallet.c:3917
msgid "SELECT type FROM transactions WHERE id=?"
msgstr ""
#: wallet/wallet.c:3915
#: wallet/wallet.c:3940
msgid "SELECT rawtx FROM transactions WHERE id=?"
msgstr ""
#: wallet/wallet.c:3961
#: wallet/wallet.c:3986
msgid "SELECT blockheight, txindex FROM transactions WHERE id=?"
msgstr ""
#: wallet/wallet.c:3989
#: wallet/wallet.c:4014
msgid "SELECT id FROM transactions WHERE blockheight=?"
msgstr ""
#: wallet/wallet.c:4008
#: wallet/wallet.c:4033
msgid "INSERT INTO channeltxs ( channel_id, type, transaction_id, input_num, blockheight) VALUES (?, ?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:4032
#: wallet/wallet.c:4057
msgid "SELECT DISTINCT(channel_id) FROM channeltxs WHERE type = ?;"
msgstr ""
#: wallet/wallet.c:4053
#: wallet/wallet.c:4078
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:4098
#: wallet/wallet.c:4123
msgid "UPDATE forwarded_payments SET in_msatoshi=?, out_msatoshi=?, state=?, resolved_time=?, failcode=? WHERE in_htlc_id=?"
msgstr ""
#: wallet/wallet.c:4156
#: wallet/wallet.c:4181
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:4215
#: wallet/wallet.c:4240
msgid "SELECT CAST(COALESCE(SUM(in_msatoshi - out_msatoshi), 0) AS BIGINT)FROM forwarded_payments WHERE state = ?;"
msgstr ""
#: wallet/wallet.c:4264
#: wallet/wallet.c:4289
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:4386
#: wallet/wallet.c:4411
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:4480
#: wallet/wallet.c:4505
msgid "INSERT INTO penalty_bases ( channel_id, commitnum, txid, outnum, amount) VALUES (?, ?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:4505
#: wallet/wallet.c:4530
msgid "SELECT commitnum, txid, outnum, amount FROM penalty_bases WHERE channel_id = ?"
msgstr ""
#: wallet/wallet.c:4529
#: wallet/wallet.c:4554
msgid "DELETE FROM penalty_bases WHERE channel_id = ? AND commitnum = ?"
msgstr ""
#: wallet/wallet.c:4547
#: wallet/wallet.c:4572
msgid "SELECT 1 FROM offers WHERE offer_id = ?;"
msgstr ""
#: wallet/wallet.c:4560
#: wallet/wallet.c:4585
msgid "INSERT INTO offers ( offer_id, bolt12, label, status) VALUES (?, ?, ?, ?);"
msgstr ""
#: wallet/wallet.c:4587
#: wallet/wallet.c:4612
msgid "SELECT bolt12, label, status FROM offers WHERE offer_id = ?;"
msgstr ""
#: wallet/wallet.c:4615
#: wallet/wallet.c:4640
msgid "SELECT offer_id FROM offers;"
msgstr ""
#: wallet/wallet.c:4641
#: wallet/wallet.c:4666
msgid "UPDATE offers SET status=? WHERE offer_id = ?;"
msgstr ""
#: wallet/wallet.c:4652
#: wallet/wallet.c:4677
msgid "UPDATE invoices SET state=? WHERE state=? AND local_offer_id = ?;"
msgstr ""
#: wallet/wallet.c:4680
#: wallet/wallet.c:4705
msgid "SELECT status FROM offers WHERE offer_id = ?;"
msgstr ""
@ -1337,4 +1341,4 @@ msgstr ""
#: wallet/test/run-wallet.c:1696
msgid "INSERT INTO channels (id) VALUES (1);"
msgstr ""
# SHA256STAMP:3652b5850f08383c0f0c01a7f11c1a22ec2b4ac16018152d2770a73674fb05ec
# SHA256STAMP:d0ba3b9e4e392f7327662f333f4712582f7553a819d588ebb3641b229215e90f

View File

@ -3556,7 +3556,7 @@ void wallet_block_add(struct wallet *w, struct block *b)
void wallet_block_remove(struct wallet *w, struct block *b)
{
struct db_stmt *stmt =
db_prepare_v2(w->db, SQL("DELETE FROM blocks WHERE hash = ?"));
db_prepare_v2(w->db, SQL("DELETE FROM blocks WHERE hash = ?"));
db_bind_sha256d(stmt, 0, &b->blkid.shad);
db_exec_prepared_v2(take(stmt));
@ -3738,21 +3738,12 @@ struct outpoint *wallet_outpoint_for_scid(struct wallet *w, tal_t *ctx,
return op;
}
const struct short_channel_id *
wallet_utxoset_get_spent(const tal_t *ctx, struct wallet *w, u32 blockheight)
/* Turns "SELECT blockheight, txindex, outnum" into scids */
static const struct short_channel_id *db_scids(const tal_t *ctx,
struct db_stmt *stmt STEALS)
{
struct db_stmt *stmt;
struct short_channel_id *res;
stmt = db_prepare_v2(w->db, SQL("SELECT"
" blockheight,"
" txindex,"
" outnum "
"FROM utxoset "
"WHERE spendheight = ?"));
db_bind_int(stmt, 0, blockheight);
db_query_prepared(stmt);
struct short_channel_id *res = tal_arr(ctx, struct short_channel_id, 0);
res = tal_arr(ctx, struct short_channel_id, 0);
while (db_step(stmt)) {
struct short_channel_id scid;
u64 blocknum, txnum, outnum;
@ -3769,6 +3760,40 @@ wallet_utxoset_get_spent(const tal_t *ctx, struct wallet *w, u32 blockheight)
return res;
}
const struct short_channel_id *
wallet_utxoset_get_spent(const tal_t *ctx, struct wallet *w,
u32 blockheight)
{
struct db_stmt *stmt;
stmt = db_prepare_v2(w->db, SQL("SELECT"
" blockheight,"
" txindex,"
" outnum "
"FROM utxoset "
"WHERE spendheight = ?"));
db_bind_int(stmt, 0, blockheight);
db_query_prepared(stmt);
return db_scids(ctx, stmt);
}
const struct short_channel_id *
wallet_utxoset_get_created(const tal_t *ctx, struct wallet *w,
u32 blockheight)
{
struct db_stmt *stmt;
stmt = db_prepare_v2(w->db, SQL("SELECT"
" blockheight,"
" txindex,"
" outnum "
"FROM utxoset "
"WHERE blockheight = ?"));
db_bind_int(stmt, 0, blockheight);
db_query_prepared(stmt);
return db_scids(ctx, stmt);
}
void wallet_transaction_add(struct wallet *w, const struct wally_tx *tx,
const u32 blockheight, const u32 txindex)
{

View File

@ -1198,6 +1198,12 @@ void wallet_utxoset_add(struct wallet *w, const struct bitcoin_tx *tx,
const struct short_channel_id *
wallet_utxoset_get_spent(const tal_t *ctx, struct wallet *w, u32 blockheight);
/**
* Retrieve all UTXO entries that were created at a given blockheight.
*/
const struct short_channel_id *
wallet_utxoset_get_created(const tal_t *ctx, struct wallet *w, u32 blockheight);
void wallet_transaction_add(struct wallet *w, const struct wally_tx *tx,
const u32 blockheight, const u32 txindex);