diff --git a/src/bitcoin/mod.rs b/src/bitcoin/mod.rs index 6e47f148..bd9c6735 100644 --- a/src/bitcoin/mod.rs +++ b/src/bitcoin/mod.rs @@ -204,7 +204,7 @@ impl BitcoinInterface for d::BitcoinD { outpoint, amount, block_height, - address, + address: UTxOAddress::Address(address), is_immature, }) } else { @@ -523,6 +523,14 @@ pub struct UTxO { pub outpoint: bitcoin::OutPoint, pub amount: bitcoin::Amount, pub block_height: Option, - pub address: bitcoin::Address, + pub address: UTxOAddress, pub is_immature: bool, } + +/// Details about the UTXO address. +#[derive(Debug, Clone)] +pub enum UTxOAddress { + Address(bitcoin::Address), + /// Derivation index and whether it is from the change descriptor. + DerivIndex(ChildNumber, bool), +} diff --git a/src/bitcoin/poller/looper.rs b/src/bitcoin/poller/looper.rs index 877bc9db..39e6a6d6 100644 --- a/src/bitcoin/poller/looper.rs +++ b/src/bitcoin/poller/looper.rs @@ -1,5 +1,5 @@ use crate::{ - bitcoin::{BitcoinInterface, BlockChainTip, UTxO}, + bitcoin::{BitcoinInterface, BlockChainTip, UTxO, UTxOAddress}, database::{Coin, DatabaseConnection, DatabaseInterface}, descriptors, }; @@ -46,44 +46,53 @@ fn update_coins( .. } = utxo; // We can only really treat them if we know the derivation index that was used. - let address = match address.require_network(network) { - Ok(addr) => addr, - Err(e) => { - log::error!("Invalid network for address: {}", e); - continue; - } - }; - if let Some((derivation_index, is_change)) = db_conn.derivation_index_by_address(&address) { - // First of if we are receiving coins that are beyond our next derivation index, - // adjust it. - if derivation_index > db_conn.receive_index() { - db_conn.set_receive_index(derivation_index, secp); - } - if derivation_index > db_conn.change_index() { - db_conn.set_change_index(derivation_index, secp); - } - - // Now record this coin as a newly received one. - if !curr_coins.contains_key(&utxo.outpoint) { - let coin = Coin { - outpoint, - is_immature, - amount, - derivation_index, - is_change, - block_info: None, - spend_txid: None, - spend_block: None, + let (derivation_index, is_change) = match address { + UTxOAddress::Address(address) => { + let address = match address.require_network(network) { + Ok(addr) => addr, + Err(e) => { + log::error!("Invalid network for address: {}", e); + continue; + } }; - received.push(coin); + if let Some((derivation_index, is_change)) = + db_conn.derivation_index_by_address(&address) + { + (derivation_index, is_change) + } else { + // TODO: maybe we could try out something here? Like bruteforcing the next 200 indexes? + log::error!( + "Could not get derivation index for coin '{}' (address: '{}')", + &utxo.outpoint, + &address + ); + continue; + } } - } else { - // TODO: maybe we could try out something here? Like bruteforcing the next 200 indexes? - log::error!( - "Could not get derivation index for coin '{}' (address: '{}')", - &utxo.outpoint, - &address - ); + UTxOAddress::DerivIndex(index, is_change) => (index, is_change), + }; + // First of if we are receiving coins that are beyond our next derivation index, + // adjust it. + if derivation_index > db_conn.receive_index() { + db_conn.set_receive_index(derivation_index, secp); + } + if derivation_index > db_conn.change_index() { + db_conn.set_change_index(derivation_index, secp); + } + + // Now record this coin as a newly received one. + if !curr_coins.contains_key(&utxo.outpoint) { + let coin = Coin { + outpoint, + is_immature, + amount, + derivation_index, + is_change, + block_info: None, + spend_txid: None, + spend_block: None, + }; + received.push(coin); } } log::debug!("Newly received coins: {:?}", received);