@@ -2917,7 +2917,8 @@ static void got_utxo(struct wallet *w,
29172917 const struct wally_tx * wtx ,
29182918 size_t outnum ,
29192919 bool is_coinbase ,
2920- const u32 * blockheight )
2920+ const u32 * blockheight ,
2921+ struct bitcoin_outpoint * outpoint )
29212922{
29222923 struct utxo * utxo = tal (tmpctx , struct utxo );
29232924 const struct wally_tx_output * txout = & wtx -> outputs [outnum ];
@@ -2972,6 +2973,8 @@ static void got_utxo(struct wallet *w,
29722973 outpointfilter_add (w -> owned_outpoints , & utxo -> outpoint );
29732974
29742975 wallet_annotate_txout (w , & utxo -> outpoint , TX_WALLET_DEPOSIT , 0 );
2976+ if (outpoint )
2977+ * outpoint = utxo -> outpoint ;
29752978}
29762979
29772980int 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,
29912994 if (!wallet_can_spend (w , txout -> script , txout -> script_len , & keyindex ))
29922995 continue ;
29932996
2994- got_utxo (w , keyindex , wtx , i , is_coinbase , blockheight );
2997+ got_utxo (w , keyindex , wtx , i , is_coinbase , blockheight , NULL );
29952998 num_utxos ++ ;
29962999 }
29973000 return num_utxos ;
@@ -6512,3 +6515,170 @@ struct issued_address_type *wallet_list_addresses(const tal_t *ctx, struct walle
65126515 tal_free (stmt );
65136516 return addresseslist ;
65146517}
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