[blockchain] Add a trait to create Blockchain
s from a configuration
This is the first set of changes for #42
This commit is contained in:
parent
6094656a54
commit
5eee18bed2
@ -37,9 +37,9 @@ use log::{debug, error, info, trace, LevelFilter};
|
|||||||
use bitcoin::Network;
|
use bitcoin::Network;
|
||||||
|
|
||||||
use bdk::bitcoin;
|
use bdk::bitcoin;
|
||||||
use bdk::blockchain::ElectrumBlockchain;
|
use bdk::blockchain::electrum::{ElectrumBlockchain, ElectrumBlockchainConfig};
|
||||||
|
use bdk::blockchain::ConfigurableBlockchain;
|
||||||
use bdk::cli;
|
use bdk::cli;
|
||||||
use bdk::electrum_client::Client;
|
|
||||||
use bdk::sled;
|
use bdk::sled;
|
||||||
use bdk::Wallet;
|
use bdk::Wallet;
|
||||||
|
|
||||||
@ -89,17 +89,16 @@ fn main() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
debug!("database opened successfully");
|
debug!("database opened successfully");
|
||||||
|
|
||||||
let client = Client::new(
|
let blockchain_config = ElectrumBlockchainConfig {
|
||||||
matches.value_of("server").unwrap(),
|
url: matches.value_of("server").unwrap().to_string(),
|
||||||
matches.value_of("proxy"),
|
socks5: matches.value_of("proxy").map(ToString::to_string),
|
||||||
)
|
};
|
||||||
.unwrap();
|
|
||||||
let wallet = Wallet::new(
|
let wallet = Wallet::new(
|
||||||
descriptor,
|
descriptor,
|
||||||
change_descriptor,
|
change_descriptor,
|
||||||
network,
|
network,
|
||||||
tree,
|
tree,
|
||||||
ElectrumBlockchain::from(client),
|
ElectrumBlockchain::from_config(&blockchain_config).unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let wallet = Arc::new(wallet);
|
let wallet = Arc::new(wallet);
|
||||||
|
@ -68,7 +68,7 @@ use std::sync::{Arc, Mutex};
|
|||||||
use log::{debug, error, info, trace};
|
use log::{debug, error, info, trace};
|
||||||
|
|
||||||
use bitcoin::network::message_blockdata::Inventory;
|
use bitcoin::network::message_blockdata::Inventory;
|
||||||
use bitcoin::{OutPoint, Transaction, Txid};
|
use bitcoin::{Network, OutPoint, Transaction, Txid};
|
||||||
|
|
||||||
use rocksdb::{Options, SliceTransform, DB};
|
use rocksdb::{Options, SliceTransform, DB};
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ mod peer;
|
|||||||
mod store;
|
mod store;
|
||||||
mod sync;
|
mod sync;
|
||||||
|
|
||||||
use super::{Blockchain, Capability, Progress};
|
use super::{Blockchain, Capability, ConfigurableBlockchain, Progress};
|
||||||
use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils};
|
use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::types::{ScriptType, TransactionDetails, UTXO};
|
use crate::types::{ScriptType, TransactionDetails, UTXO};
|
||||||
@ -460,6 +460,54 @@ impl Blockchain for CompactFiltersBlockchain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Data to connect to a Bitcoin P2P peer
|
||||||
|
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub struct BitcoinPeerConfig {
|
||||||
|
pub address: String,
|
||||||
|
pub socks5: Option<String>,
|
||||||
|
pub socks5_credentials: Option<(String, String)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configuration for a [`CompactFiltersBlockchain`]
|
||||||
|
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub struct CompactFiltersBlockchainConfig {
|
||||||
|
pub peers: Vec<BitcoinPeerConfig>,
|
||||||
|
pub network: Network,
|
||||||
|
pub storage_dir: String,
|
||||||
|
pub skip_blocks: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConfigurableBlockchain for CompactFiltersBlockchain {
|
||||||
|
type Config = CompactFiltersBlockchainConfig;
|
||||||
|
|
||||||
|
fn from_config(config: &Self::Config) -> Result<Self, Error> {
|
||||||
|
let mempool = Arc::new(Mempool::default());
|
||||||
|
let peers = config
|
||||||
|
.peers
|
||||||
|
.iter()
|
||||||
|
.map(|peer_conf| match &peer_conf.socks5 {
|
||||||
|
None => Peer::connect(&peer_conf.address, Arc::clone(&mempool), config.network),
|
||||||
|
Some(proxy) => Peer::connect_proxy(
|
||||||
|
peer_conf.address.as_str(),
|
||||||
|
proxy,
|
||||||
|
peer_conf
|
||||||
|
.socks5_credentials
|
||||||
|
.as_ref()
|
||||||
|
.map(|(a, b)| (a.as_str(), b.as_str())),
|
||||||
|
Arc::clone(&mempool),
|
||||||
|
config.network,
|
||||||
|
),
|
||||||
|
})
|
||||||
|
.collect::<Result<_, _>>()?;
|
||||||
|
|
||||||
|
Ok(CompactFiltersBlockchain::new(
|
||||||
|
peers,
|
||||||
|
&config.storage_dir,
|
||||||
|
config.skip_blocks,
|
||||||
|
)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An error that can occur during sync with a [`CompactFiltersBlockchain`]
|
/// An error that can occur during sync with a [`CompactFiltersBlockchain`]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum CompactFiltersError {
|
pub enum CompactFiltersError {
|
||||||
|
@ -173,3 +173,21 @@ impl ElectrumLikeSync for Client {
|
|||||||
self.transaction_get(txid).map_err(Error::Electrum)
|
self.transaction_get(txid).map_err(Error::Electrum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Configuration for an [`ElectrumBlockchain`]
|
||||||
|
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub struct ElectrumBlockchainConfig {
|
||||||
|
pub url: String,
|
||||||
|
pub socks5: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConfigurableBlockchain for ElectrumBlockchain {
|
||||||
|
type Config = ElectrumBlockchainConfig;
|
||||||
|
|
||||||
|
fn from_config(config: &Self::Config) -> Result<Self, Error> {
|
||||||
|
Ok(ElectrumBlockchain(Client::new(
|
||||||
|
config.url.as_str(),
|
||||||
|
config.socks5.as_deref(),
|
||||||
|
)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -340,6 +340,20 @@ struct EsploraListUnspent {
|
|||||||
status: EsploraGetHistoryStatus,
|
status: EsploraGetHistoryStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Configuration for an [`EsploraBlockchain`]
|
||||||
|
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub struct EsploraBlockchainConfig {
|
||||||
|
pub base_url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConfigurableBlockchain for EsploraBlockchain {
|
||||||
|
type Config = EsploraBlockchainConfig;
|
||||||
|
|
||||||
|
fn from_config(config: &Self::Config) -> Result<Self, Error> {
|
||||||
|
Ok(EsploraBlockchain::new(config.base_url.as_str()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Errors that can happen during a sync with [`EsploraBlockchain`]
|
/// Errors that can happen during a sync with [`EsploraBlockchain`]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum EsploraError {
|
pub enum EsploraError {
|
||||||
|
@ -152,6 +152,15 @@ pub trait Blockchain: BlockchainMarker {
|
|||||||
fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error>;
|
fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait for [`Blockchain`] types that can be created given a configuration
|
||||||
|
pub trait ConfigurableBlockchain: Blockchain + Sized {
|
||||||
|
/// Type that contains the configuration
|
||||||
|
type Config: std::fmt::Debug;
|
||||||
|
|
||||||
|
/// Create a new instance given a configuration
|
||||||
|
fn from_config(config: &Self::Config) -> Result<Self, Error>;
|
||||||
|
}
|
||||||
|
|
||||||
/// Data sent with a progress update over a [`channel`]
|
/// Data sent with a progress update over a [`channel`]
|
||||||
pub type ProgressData = (f32, Option<String>);
|
pub type ProgressData = (f32, Option<String>);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user