bitcoin: allow to store UTXO deriv index

This commit is contained in:
jp1ac4 2024-08-06 16:27:05 +01:00 committed by Michael Mallan
parent 4c02b0d431
commit 689442c2c9
No known key found for this signature in database
GPG Key ID: 5177CDCEDB0EABEB
2 changed files with 56 additions and 39 deletions

View File

@ -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<i32>,
pub address: bitcoin::Address<address::NetworkUnchecked>,
pub address: UTxOAddress,
pub is_immature: bool,
}
/// Details about the UTXO address.
#[derive(Debug, Clone)]
pub enum UTxOAddress {
Address(bitcoin::Address<address::NetworkUnchecked>),
/// Derivation index and whether it is from the change descriptor.
DerivIndex(ChildNumber, bool),
}

View File

@ -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);