poller: query derivation index by address from DB

This commit is contained in:
Antoine Poinsot 2022-08-16 16:04:05 +02:00
parent 3f17e9f0c3
commit 99a9cbf0f8
No known key found for this signature in database
GPG Key ID: E13FC145CD3F4304
5 changed files with 51 additions and 18 deletions

View File

@ -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<i32>,
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,
}
}
}

View File

@ -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<sync::Mutex<dyn BitcoinInterface + 'static>>
// 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<i32>,
pub address: bitcoin::Address,
}

View File

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

View File

@ -46,6 +46,11 @@ pub trait DatabaseConnection {
fn increment_derivation_index(&mut self, secp: &secp256k1::Secp256k1<secp256k1::VerifyOnly>);
fn derivation_index_by_address(
&mut self,
address: &bitcoin::Address,
) -> Option<bip32::ChildNumber>;
/// Get all UTxOs.
fn unspent_coins(&mut self) -> HashMap<bitcoin::OutPoint, Coin>;
@ -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<bip32::ChildNumber> {
self.db_address(address)
.map(|db_addr| db_addr.derivation_index)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]

View File

@ -133,6 +133,10 @@ impl DatabaseConnection for DummyDbConn {
*spender = Some(*spend_txid);
}
}
fn derivation_index_by_address(&mut self, _: &bitcoin::Address) -> Option<bip32::ChildNumber> {
None
}
}
pub struct DummyMinisafe {