@@ -2917,7 +2917,8 @@ static void got_utxo(struct wallet *w,
2917
2917
const struct wally_tx * wtx ,
2918
2918
size_t outnum ,
2919
2919
bool is_coinbase ,
2920
- const u32 * blockheight )
2920
+ const u32 * blockheight ,
2921
+ struct bitcoin_outpoint * outpoint )
2921
2922
{
2922
2923
struct utxo * utxo = tal (tmpctx , struct utxo );
2923
2924
const struct wally_tx_output * txout = & wtx -> outputs [outnum ];
@@ -2972,6 +2973,8 @@ static void got_utxo(struct wallet *w,
2972
2973
outpointfilter_add (w -> owned_outpoints , & utxo -> outpoint );
2973
2974
2974
2975
wallet_annotate_txout (w , & utxo -> outpoint , TX_WALLET_DEPOSIT , 0 );
2976
+ if (outpoint )
2977
+ * outpoint = utxo -> outpoint ;
2975
2978
}
2976
2979
2977
2980
int wallet_extract_owned_outputs (struct wallet * w , const struct wally_tx * wtx ,
@@ -2991,7 +2994,7 @@ int wallet_extract_owned_outputs(struct wallet *w, const struct wally_tx *wtx,
2991
2994
if (!wallet_can_spend (w , txout -> script , txout -> script_len , & keyindex ))
2992
2995
continue ;
2993
2996
2994
- got_utxo (w , keyindex , wtx , i , is_coinbase , blockheight );
2997
+ got_utxo (w , keyindex , wtx , i , is_coinbase , blockheight , NULL );
2995
2998
num_utxos ++ ;
2996
2999
}
2997
3000
return num_utxos ;
@@ -6512,3 +6515,170 @@ struct issued_address_type *wallet_list_addresses(const tal_t *ctx, struct walle
6512
6515
tal_free (stmt );
6513
6516
return addresseslist ;
6514
6517
}
6518
+
6519
+ struct missing {
6520
+ size_t num_found ;
6521
+ struct missing_addr * addrs ;
6522
+ };
6523
+
6524
+ struct missing_addr {
6525
+ u64 keyidx ;
6526
+ const u8 * scriptpubkey ;
6527
+ };
6528
+
6529
+ static void mutual_close_p2pkh_catch (struct bitcoind * bitcoind ,
6530
+ u32 height ,
6531
+ struct bitcoin_blkid * blkid ,
6532
+ struct bitcoin_block * blk ,
6533
+ struct missing * missing )
6534
+ {
6535
+ struct wallet * w = bitcoind -> ld -> wallet ;
6536
+
6537
+ /* Are we finished? */
6538
+ if (!blkid ) {
6539
+ log_broken (bitcoind -> ld -> log ,
6540
+ "Rescan finished! %zu outputs recovered. Let's never do that again." ,
6541
+ missing -> num_found );
6542
+ db_set_intvar (w -> db , "needs_p2wpkh_close_rescan" , 0 );
6543
+ /* Call is allocated off of this, so we can't free just yet */
6544
+ tal_steal (tmpctx , missing );
6545
+ return ;
6546
+ }
6547
+
6548
+ log_debug (bitcoind -> ld -> log , "Mutual close p2wpkh recovery block %u" , height );
6549
+ for (size_t i = 0 ; i < tal_count (blk -> tx ); i ++ ) {
6550
+ const struct wally_tx * wtx = blk -> tx [i ]-> wtx ;
6551
+ for (size_t outnum = 0 ; outnum < wtx -> num_outputs ; outnum ++ ) {
6552
+ const struct wally_tx_output * txout = & wtx -> outputs [outnum ];
6553
+ for (size_t n = 0 ; n < tal_count (missing -> addrs ); n ++ ) {
6554
+ struct bitcoin_outpoint outp ;
6555
+ log_debug (bitcoind -> ld -> log , "%zu out %zu: %s (seeking %s)" ,
6556
+ i , outnum ,
6557
+ tal_hexstr (tmpctx , txout -> script , txout -> script_len ),
6558
+ tal_hex (tmpctx , missing -> addrs [n ].scriptpubkey ));
6559
+ if (!memeq (txout -> script , txout -> script_len ,
6560
+ missing -> addrs [n ].scriptpubkey ,
6561
+ tal_bytelen (missing -> addrs [n ].scriptpubkey )))
6562
+ continue ;
6563
+ got_utxo (w , missing -> addrs [n ].keyidx ,
6564
+ wtx , outnum , i == 0 , & height , & outp );
6565
+ log_broken (bitcoind -> ld -> log , "Rescan found %s!" ,
6566
+ fmt_bitcoin_outpoint (tmpctx , & outp ));
6567
+ missing -> num_found ++ ;
6568
+ }
6569
+ }
6570
+ }
6571
+
6572
+ /* Next block! */
6573
+ bitcoind_getrawblockbyheight (missing , bitcoind , height + 1 ,
6574
+ mutual_close_p2pkh_catch , missing );
6575
+ }
6576
+
6577
+ void wallet_begin_old_close_rescan (struct lightningd * ld )
6578
+ {
6579
+ struct db_stmt * stmt ;
6580
+ u32 earliest_block = UINT32_MAX ;
6581
+ struct missing * missing ;
6582
+ int v = db_get_intvar (ld -> wallet -> db , "needs_p2wpkh_close_rescan" , -1 );
6583
+ if (v == 0 )
6584
+ return ;
6585
+ assert (v == 1 );
6586
+
6587
+ /* Channels where we might have already seen a mutual close,
6588
+ * which said their key was only taproot, but we didn't see an
6589
+ * output, may actually have closed to the p2wpkh address.
6590
+ * Some debugging help with ChatGPT here!
6591
+ */
6592
+ stmt = db_prepare_v2 (ld -> wallet -> db ,
6593
+ SQL ("SELECT "
6594
+ " full_channel_id"
6595
+ ", state"
6596
+ ", scid"
6597
+ ", shutdown_keyidx_local"
6598
+ " FROM channels"
6599
+ " JOIN addresses"
6600
+ " ON channels.shutdown_keyidx_local = addresses.keyidx"
6601
+ " WHERE addresses.addrtype = ?"
6602
+ " AND NOT EXISTS ("
6603
+ " SELECT 1"
6604
+ " FROM outputs"
6605
+ " WHERE outputs.keyindex = addresses.keyidx"
6606
+ ");" ));
6607
+ db_bind_int (stmt , wallet_addrtype_in_db (ADDR_P2TR ));
6608
+ db_query_prepared (stmt );
6609
+
6610
+ missing = tal (tmpctx , struct missing );
6611
+ missing -> num_found = 0 ;
6612
+ missing -> addrs = tal_arr (missing , struct missing_addr , 0 );
6613
+ while (db_step (stmt )) {
6614
+ enum channel_state state ;
6615
+ struct short_channel_id scid ;
6616
+ struct channel_id cid ;
6617
+ struct missing_addr maddr ;
6618
+ struct ext_key ext ;
6619
+
6620
+ state = channel_state_in_db (db_col_int (stmt , "state" ));
6621
+ switch (state ) {
6622
+ case DUALOPEND_OPEN_INIT :
6623
+ case CHANNELD_AWAITING_LOCKIN :
6624
+ case CHANNELD_NORMAL :
6625
+ case CHANNELD_SHUTTING_DOWN :
6626
+ case CLOSINGD_SIGEXCHANGE :
6627
+ case DUALOPEND_OPEN_COMMITTED :
6628
+ case DUALOPEND_AWAITING_LOCKIN :
6629
+ case CHANNELD_AWAITING_SPLICE :
6630
+ case DUALOPEND_OPEN_COMMIT_READY :
6631
+ db_col_ignore (stmt , "full_channel_id" );
6632
+ db_col_ignore (stmt , "scid" );
6633
+ db_col_ignore (stmt , "shutdown_keyidx_local" );
6634
+ continue ;
6635
+ /* States where we may have already seen close */
6636
+ case CLOSINGD_COMPLETE :
6637
+ case AWAITING_UNILATERAL :
6638
+ case FUNDING_SPEND_SEEN :
6639
+ case ONCHAIN :
6640
+ case CLOSED :
6641
+ db_col_channel_id (stmt , "full_channel_id" , & cid );
6642
+ maddr .keyidx = db_col_u64 (stmt , "shutdown_keyidx_local" );
6643
+
6644
+ /* This can happen with zeroconf, but it's unusual. In that case
6645
+ * we haven't even seen the open, let alone the close.*/
6646
+ if (db_col_is_null (stmt , "scid" ))
6647
+ continue ;
6648
+
6649
+ /* Don't search for close before open */
6650
+ scid = db_col_short_channel_id (stmt , "scid" );
6651
+ if (short_channel_id_blocknum (scid ) < earliest_block )
6652
+ earliest_block = short_channel_id_blocknum (scid );
6653
+
6654
+ if (bip32_key_from_parent (ld -> bip32_base , maddr .keyidx ,
6655
+ BIP32_FLAG_KEY_PUBLIC | BIP32_FLAG_SKIP_HASH ,
6656
+ & ext ) != WALLY_OK ) {
6657
+ abort ();
6658
+ }
6659
+ maddr .scriptpubkey = scriptpubkey_p2wpkh_derkey (missing , ext .pub_key );
6660
+ tal_arr_expand (& missing -> addrs , maddr );
6661
+ }
6662
+ }
6663
+ tal_free (stmt );
6664
+
6665
+ /* No results? We didn't have a problem, never test again. */
6666
+ if (tal_count (missing -> addrs ) == 0 ) {
6667
+ db_set_intvar (ld -> wallet -> db , "needs_p2wpkh_close_rescan" , 0 );
6668
+ return ;
6669
+ }
6670
+
6671
+ /* We only released 24.11 in December, so don't go back before
6672
+ * block 870000 which was mid-November */
6673
+ if (streq (chainparams -> network_name , "bitcoin" ) && earliest_block < 870000 )
6674
+ earliest_block = 870000 ;
6675
+
6676
+ log_broken (ld -> log ,
6677
+ "Potentially missing %zu outputs from previous closes: scanning from block %u" ,
6678
+ tal_count (missing -> addrs ), earliest_block );
6679
+
6680
+ /* This is not a leak, though it may take a while! */
6681
+ tal_steal (ld , notleak (missing ));
6682
+ bitcoind_getrawblockbyheight (missing , ld -> topology -> bitcoind , earliest_block ,
6683
+ mutual_close_p2pkh_catch , missing );
6684
+ }
0 commit comments