From 99a9cbf0f83fda6f98892c23ac89324f04b650ff Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Tue, 16 Aug 2022 16:04:05 +0200 Subject: [PATCH] poller: query derivation index by address from DB --- src/bitcoin/d/mod.rs | 10 +++++++++- src/bitcoin/mod.rs | 5 ++++- src/bitcoin/poller/looper.rs | 37 ++++++++++++++++++++---------------- src/database/mod.rs | 13 +++++++++++++ src/testutils.rs | 4 ++++ 5 files changed, 51 insertions(+), 18 deletions(-) diff --git a/src/bitcoin/d/mod.rs b/src/bitcoin/d/mod.rs index ad62c48d..e2edcca2 100644 --- a/src/bitcoin/d/mod.rs +++ b/src/bitcoin/d/mod.rs @@ -671,11 +671,12 @@ fn roundup_progress(progress: f64) -> f64 { } /// A 'received' entry in the 'listsinceblock' result. -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone)] pub struct LSBlockEntry { pub outpoint: bitcoin::OutPoint, pub amount: bitcoin::Amount, pub block_height: Option, + pub address: bitcoin::Address, } impl From<&Json> for LSBlockEntry { @@ -702,10 +703,17 @@ impl From<&Json> for LSBlockEntry { .and_then(Json::as_i64) .map(|bh| bh as i32); + let address = json + .get("address") + .and_then(Json::as_str) + .and_then(|s| bitcoin::Address::from_str(s).ok()) + .expect("bitcoind can't give a bad address"); + LSBlockEntry { outpoint, amount, block_height, + address, } } } diff --git a/src/bitcoin/mod.rs b/src/bitcoin/mod.rs index dc0e8ddf..650d5572 100644 --- a/src/bitcoin/mod.rs +++ b/src/bitcoin/mod.rs @@ -79,11 +79,13 @@ impl BitcoinInterface for d::BitcoinD { outpoint, amount, block_height, + address, } = entry; UTxO { outpoint, amount, block_height, + address, } }) .collect() @@ -168,9 +170,10 @@ impl BitcoinInterface for sync::Arc> // FIXME: We could avoid this type (and all the conversions entailing allocations) if bitcoind // exposed the derivation index from the parent descriptor in the LSB result. -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone)] pub struct UTxO { pub outpoint: bitcoin::OutPoint, pub amount: bitcoin::Amount, pub block_height: Option, + pub address: bitcoin::Address, } diff --git a/src/bitcoin/poller/looper.rs b/src/bitcoin/poller/looper.rs index 3c10f537..66e0c2d0 100644 --- a/src/bitcoin/poller/looper.rs +++ b/src/bitcoin/poller/looper.rs @@ -8,7 +8,7 @@ use std::{ thread, time, }; -use miniscript::bitcoin::{self, util::bip32}; +use miniscript::bitcoin; #[derive(Debug, Clone)] struct UpdatedCoins { @@ -30,21 +30,26 @@ fn update_coins( let curr_coins = db_conn.unspent_coins(); let mut received = Vec::new(); for utxo in bit.received_coins(&previous_tip) { - // FIXME: have a DB table to query those... - let derivation_index = bip32::ChildNumber::from(0); - // This works because the hash only takes the outpoint into account. - if !curr_coins.contains_key(&utxo.outpoint) { - let UTxO { - outpoint, amount, .. - } = utxo; - let coin = Coin { - outpoint, - amount, - derivation_index, - block_height: None, - spend_txid: None, - }; - received.push(coin); + if let Some(derivation_index) = db_conn.derivation_index_by_address(&utxo.address) { + if !curr_coins.contains_key(&utxo.outpoint) { + let UTxO { + outpoint, amount, .. + } = utxo; + let coin = Coin { + outpoint, + amount, + derivation_index, + block_height: None, + spend_txid: None, + }; + received.push(coin); + } + } else { + log::error!( + "Could not get derivation index for coin '{}' (address: '{}')", + &utxo.outpoint, + &utxo.address + ); } } diff --git a/src/database/mod.rs b/src/database/mod.rs index 6fd27ee4..68f5d105 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -46,6 +46,11 @@ pub trait DatabaseConnection { fn increment_derivation_index(&mut self, secp: &secp256k1::Secp256k1); + fn derivation_index_by_address( + &mut self, + address: &bitcoin::Address, + ) -> Option; + /// Get all UTxOs. fn unspent_coins(&mut self) -> HashMap; @@ -125,6 +130,14 @@ impl DatabaseConnection for SqliteConn { fn spend_coins<'a>(&mut self, outpoints: &[(bitcoin::OutPoint, bitcoin::Txid)]) { self.spend_coins(outpoints) } + + fn derivation_index_by_address( + &mut self, + address: &bitcoin::Address, + ) -> Option { + self.db_address(address) + .map(|db_addr| db_addr.derivation_index) + } } #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/src/testutils.rs b/src/testutils.rs index 989cafc8..9f4781ba 100644 --- a/src/testutils.rs +++ b/src/testutils.rs @@ -133,6 +133,10 @@ impl DatabaseConnection for DummyDbConn { *spender = Some(*spend_txid); } } + + fn derivation_index_by_address(&mut self, _: &bitcoin::Address) -> Option { + None + } } pub struct DummyMinisafe {