Skip to content

Commit

Permalink
adding a point in time test with electrsd/esplora
Browse files Browse the repository at this point in the history
  • Loading branch information
ulrichard committed Jan 8, 2024
1 parent 097c7a9 commit fda985a
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 4 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ esplora-client = { version = "0.4", default-features = false, optional = true }
log = "^0.4"

[features]
use-esplora-blocking = ["esplora-client/blocking"]
use-esplora-blocking = ["esplora-client/blocking", "bdk/use-esplora-blocking"]

[dev-dependencies]
rstest = "^0.11"
bdk-testutils = "^0.4"
bdk = { version = "0.28", default-features = true }
electrsd = { version = "0.23", features = ["bitcoind_22_0", "electrs_0_9_1"] }
electrsd = { version = "0.23.1", features = ["bitcoind_23_0", "esplora_a33e97e1", "legacy"] }
88 changes: 88 additions & 0 deletions tests/point_in_time.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#[cfg(feature = "use-esplora-blocking")]
mod regtestenv;
#[cfg(feature = "use-esplora-blocking")]
use bdk::bitcoin::Network;
#[cfg(feature = "use-esplora-blocking")]
use bdk::blockchain::esplora::EsploraBlockchain;
#[cfg(feature = "use-esplora-blocking")]
use bdk::blockchain::{Blockchain, GetHeight};
#[cfg(feature = "use-esplora-blocking")]
use bdk::database::memory::MemoryDatabase;
#[cfg(feature = "use-esplora-blocking")]
use bdk::wallet::{SyncOptions, Wallet};
#[cfg(feature = "use-esplora-blocking")]
use bdk::Error;
#[cfg(feature = "use-esplora-blocking")]
use bdk::SignOptions;
#[cfg(feature = "use-esplora-blocking")]
use bdk_reserves::reserves::*;
#[cfg(feature = "use-esplora-blocking")]
use electrsd::bitcoind::bitcoincore_rpc::bitcoin::Address;
#[cfg(feature = "use-esplora-blocking")]
use esplora_client::Builder;
#[cfg(feature = "use-esplora-blocking")]
use regtestenv::RegTestEnv;
#[cfg(feature = "use-esplora-blocking")]
use std::str::FromStr;

fn construct_wallet(desc: &str, network: Network) -> Result<Wallet<MemoryDatabase>, Error> {
let wallet = Wallet::new(desc, None, network, MemoryDatabase::default())?;

Ok(wallet)
}

#[test]
#[cfg(feature = "use-esplora-blocking")]
fn point_in_time() {
let wallet = construct_wallet(
"wpkh(cTTgG6x13nQjAeECaCaDrjrUdcjReZBGspcmNavsnSRyXq7zXT7r)",
Network::Regtest,
)
.unwrap();

let regtestenv = RegTestEnv::new();
regtestenv.generate(&[&wallet]);
let esplora_url = format!("http://{}", regtestenv.esplora_url().as_ref().unwrap());
let client = Builder::new(&esplora_url).build_blocking().unwrap();
let blockchain = EsploraBlockchain::from_client(client, 20);
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
let old_height = blockchain.get_height().unwrap();
let old_balance = wallet.get_balance().unwrap();

let message = "This belonged to me.";
let mut psbt = wallet.create_proof(message).unwrap();
let signopts = SignOptions {
trust_witness_utxo: true,
..Default::default()
};
let finalized = wallet.sign(&mut psbt, signopts.clone()).unwrap();
let proof = psbt;
assert!(finalized);

let spendable = proof
.verify_reserve_proof(message, WalletAtHeight::new(&wallet, old_height))
.unwrap();
assert_eq!(spendable, old_balance.confirmed);

const MY_FOREIGN_ADDR: &str = "mpSFfNURcFTz2yJxBzRY9NhnozxeJ2AUC8";
let foreign_addr = Address::from_str(MY_FOREIGN_ADDR).unwrap();
let mut builder = wallet.build_tx();
builder
.add_recipient(foreign_addr.script_pubkey(), 1_000)
.fee_rate(bdk::FeeRate::from_sat_per_vb(2.0));
let (mut psbt, _) = builder.finish().unwrap();
let finalized = wallet.sign(&mut psbt, signopts).unwrap();
assert!(finalized);
blockchain.broadcast(&psbt.extract_tx()).unwrap();
wallet.sync(&blockchain, SyncOptions::default()).unwrap();

regtestenv.generate_to_address(6, &foreign_addr);

let new_balance = wallet.get_balance().unwrap();
assert_ne!(old_balance, new_balance);

let spendable = proof
.verify_reserve_proof(message, WalletAtHeight::new(&wallet, old_height))
.unwrap();
assert_eq!(spendable, old_balance.confirmed);
}
11 changes: 9 additions & 2 deletions tests/regtestenv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,26 @@ impl RegTestEnv {

let mut elect_conf = electrsd::Conf::default();
elect_conf.view_stderr = false; // setting this to true will lead to very verbose logging
elect_conf.http_enabled = true;
let elect_exe =
electrsd::downloaded_exe_path().expect("We should always have downloaded path");
let electrsd = ElectrsD::with_conf(elect_exe, &bitcoind, &elect_conf).unwrap();

RegTestEnv { bitcoind, electrsd }
}

/// returns the URL where a client can connect to the embedded electrum server
/// returns the URL where an electrum client can connect to the embedded electrum server
pub fn electrum_url(&self) -> &str {
&self.electrsd.electrum_url
}

/// returns the URL where an esplora client can connect to the embedded esplora server
pub fn esplora_url(&self) -> &Option<String> {
&self.electrsd.esplora_url
}

/// generates some blocks to have some coins to test with
/// @wallets: either a single wallet, or all the signer wallets that belong to the same multisig.
pub fn generate(&self, wallets: &[&Wallet<MemoryDatabase>]) {
let addr2 = wallets[0].get_address(AddressIndex::Peek(1)).unwrap();
let addr1 = wallets[0].get_address(AddressIndex::Peek(0)).unwrap();
Expand Down Expand Up @@ -89,7 +96,7 @@ impl RegTestEnv {
.for_each(|wallet| wallet.sync(&blockchain, SyncOptions::default()).unwrap());
}

fn generate_to_address(&self, blocks: usize, address: &Address) {
pub fn generate_to_address(&self, blocks: usize, address: &Address) {
let old_height = self
.electrsd
.client
Expand Down

0 comments on commit fda985a

Please sign in to comment.