Skip to content

Commit 947d0fa

Browse files
committed
test: Add multiple wallet syncing
This test takes the first wallet to a stale block, then shuts down the node. A new wallet is introduced, and we assert that the first wallet still detects and applies the reorganization.
1 parent 8a1a67e commit 947d0fa

1 file changed

Lines changed: 93 additions & 0 deletions

File tree

tests/client.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// #![allow(unused)]
22
use bdk_kyoto::{Idle, Single};
3+
use bdk_wallet::chain::{DescriptorExt, DescriptorId};
4+
use std::collections::BTreeMap;
35
use std::net::IpAddr;
46
use std::path::PathBuf;
57
use std::time::Duration;
@@ -17,6 +19,8 @@ use bdk_wallet::Update;
1719

1820
const EXTERNAL_DESCRIPTOR: &str = "tr([7d94197e/86'/1'/0']tpubDCyQVJj8KzjiQsFjmb3KwECVXPvMwvAxxZGCP9XmWSopmjW3bCV3wD7TgxrUhiGSueDS1MU5X1Vb1YjYcp8jitXc5fXfdC1z68hDDEyKRNr/0/*)";
1921
const INTERNAL_DESCRIPTOR: &str = "tr([7d94197e/86'/1'/0']tpubDCyQVJj8KzjiQsFjmb3KwECVXPvMwvAxxZGCP9XmWSopmjW3bCV3wD7TgxrUhiGSueDS1MU5X1Vb1YjYcp8jitXc5fXfdC1z68hDDEyKRNr/1/*)";
22+
const RECV_TWO: &str = "wpkh([9122d9e0/84'/1'/0']tpubDCYVtmaSaDzTxcgvoP5AHZNbZKZzrvoNH9KARep88vESc6MxRqAp4LmePc2eeGX6XUxBcdhAmkthWTDqygPz2wLAyHWisD299Lkdrj5egY6/0/*)";
23+
const CHANGE_TWO: &str = "wpkh([9122d9e0/84'/1'/0']tpubDCYVtmaSaDzTxcgvoP5AHZNbZKZzrvoNH9KARep88vESc6MxRqAp4LmePc2eeGX6XUxBcdhAmkthWTDqygPz2wLAyHWisD299Lkdrj5egY6/1/*)";
2024

2125
fn testenv() -> anyhow::Result<TestEnv> {
2226
use bdk_testenv::Config;
@@ -239,3 +243,92 @@ async fn update_handles_dormant_wallet() -> anyhow::Result<()> {
239243

240244
Ok(())
241245
}
246+
247+
#[tokio::test]
248+
async fn two_wallets_can_update() -> anyhow::Result<()> {
249+
let env = testenv()?;
250+
251+
let mut wallet = CreateParams::new(EXTERNAL_DESCRIPTOR, INTERNAL_DESCRIPTOR)
252+
.network(Network::Regtest)
253+
.create_wallet_no_persist()?;
254+
let addr = wallet.peek_address(KeychainKind::External, 0).address;
255+
256+
let tempdir = tempfile::tempdir()?.path().join("kyoto-data");
257+
let client = init_node(&env, &wallet, tempdir.clone())?;
258+
let (client, _, mut update_subscriber) = client.subscribe();
259+
let client = client.start();
260+
let requester = client.requester();
261+
262+
// mine blocks
263+
let miner = env
264+
.rpc_client()
265+
.get_new_address(None, None)?
266+
.assume_checked();
267+
let _hashes = env.mine_blocks(100, Some(miner.clone()))?;
268+
wait_for_height(&env, 101).await?;
269+
270+
// send tx
271+
let amt = Amount::from_btc(0.21)?;
272+
let txid = env.send(&addr, amt)?;
273+
let hashes = env.mine_blocks(1, Some(miner.clone()))?;
274+
let blockhash = hashes[0];
275+
wait_for_height(&env, 102).await?;
276+
277+
// get update
278+
let res = update_subscriber.update().await?;
279+
let (anchor, anchor_txid) = *res.tx_update.anchors.iter().next().unwrap();
280+
assert_eq!(anchor.block_id.hash, blockhash);
281+
assert_eq!(anchor_txid, txid);
282+
wallet.apply_update(res).unwrap();
283+
284+
// shut down then reorg
285+
requester.shutdown()?;
286+
287+
let hashes = env.reorg(1)?; // 102
288+
let new_blockhash = hashes[0];
289+
_ = env.mine_blocks(20, Some(miner))?; // 122
290+
wait_for_height(&env, 122).await?;
291+
292+
// add a new wallet to the sync request
293+
let wallet_two = CreateParams::new(RECV_TWO, CHANGE_TWO)
294+
.network(Network::Regtest)
295+
.create_wallet_no_persist()?;
296+
let peer = env.bitcoind.params.p2p_socket.unwrap();
297+
let ip: IpAddr = (*peer.ip()).into();
298+
let port = peer.port();
299+
let mut peer = TrustedPeer::from_ip(ip);
300+
peer.port = Some(port);
301+
let client = Builder::new(Network::Regtest)
302+
.add_peer(peer)
303+
.data_dir(tempdir)
304+
.required_peers(1)
305+
.build_with_wallets(vec![
306+
(&wallet, ScanType::Sync),
307+
(&wallet_two, ScanType::Sync),
308+
])?;
309+
let (client, _, mut update_subscriber) = client.subscribe();
310+
let client = client.start();
311+
let requester = client.requester();
312+
313+
// expect tx to confirm at same height but different blockhash
314+
let results = update_subscriber.updates().await?;
315+
let res = results
316+
.collect::<BTreeMap<DescriptorId, Update>>()
317+
.get(
318+
&wallet
319+
.public_descriptor(KeychainKind::External)
320+
.descriptor_id(),
321+
)
322+
.unwrap()
323+
.clone();
324+
let (anchor, anchor_txid) = *res.tx_update.anchors.iter().next().unwrap();
325+
assert_eq!(anchor_txid, txid);
326+
assert_eq!(anchor.block_id.height, 102);
327+
assert_ne!(anchor.block_id.hash, blockhash);
328+
assert_eq!(anchor.block_id.hash, new_blockhash);
329+
wallet.apply_update(res).unwrap();
330+
331+
requester.shutdown()?;
332+
333+
Ok(())
334+
}

0 commit comments

Comments
 (0)