22use std:: time:: Instant ;
33
44use anyhow:: Context ;
5- use bdk_bitcoind_rpc:: bip158:: { Event , EventInner , FilterIter } ;
5+ use bdk_bitcoind_rpc:: bip158:: { Event , FilterIter } ;
66use bdk_chain:: bitcoin:: { constants:: genesis_block, secp256k1:: Secp256k1 , Network } ;
77use bdk_chain:: indexer:: keychain_txout:: KeychainTxOutIndex ;
88use bdk_chain:: local_chain:: LocalChain ;
99use bdk_chain:: miniscript:: Descriptor ;
1010use bdk_chain:: { BlockId , ConfirmationBlockTime , IndexedTxGraph , SpkIterator } ;
1111use bdk_testenv:: anyhow;
12- use bitcoin:: Address ;
1312
1413// This example shows how BDK chain and tx-graph structures are updated using compact
1514// filters syncing. Assumes a connection can be made to a bitcoin node via environment
1615// variables `RPC_URL` and `RPC_COOKIE`.
1716
1817// Usage: `cargo run -p bdk_bitcoind_rpc --example filter_iter`
1918
20- const EXTERNAL : & str = "tr([7d94197e]tprv8ZgxMBicQKsPe1chHGzaa84k1inY2nAXUL8iPSyWESPrEst4E5oCFXhPATqj5fvw34LDknJz7rtXyEC4fKoXryUdc9q87pTTzfQyv61cKdE /86'/1'/0'/0/*)#uswl2jj7 " ;
21- const INTERNAL : & str = "tr([7d94197e]tprv8ZgxMBicQKsPe1chHGzaa84k1inY2nAXUL8iPSyWESPrEst4E5oCFXhPATqj5fvw34LDknJz7rtXyEC4fKoXryUdc9q87pTTzfQyv61cKdE /86'/1'/0'/1/*)#dyt7h8zx " ;
19+ const EXTERNAL : & str = "tr([83737d5e /86'/1'/0']tpubDDR5GgtoxS8fJyjjvdahN4VzV5DV6jtbcyvVXhEKq2XtpxjxBXmxH3r8QrNbQqHg4bJM1EGkxi7Pjfkgnui9jQWqS7kxHvX6rhUeriLDKxz /0/*)" ;
20+ const INTERNAL : & str = "tr([83737d5e /86'/1'/0']tpubDDR5GgtoxS8fJyjjvdahN4VzV5DV6jtbcyvVXhEKq2XtpxjxBXmxH3r8QrNbQqHg4bJM1EGkxi7Pjfkgnui9jQWqS7kxHvX6rhUeriLDKxz /1/*)" ;
2221const SPK_COUNT : u32 = 25 ;
2322const NETWORK : Network = Network :: Signet ;
2423
25- const START_HEIGHT : u32 = 170_000 ;
26- const START_HASH : & str = "00000041c812a89f084f633e4cf47e819a2f6b1c0a15162355a930410522c99d " ;
24+ const START_HEIGHT : u32 = 205_000 ;
25+ const START_HASH : & str = "0000002bd0f82f8c0c0f1e19128f84c938763641dba85c44bdb6aed1678d16cb " ;
2726
2827fn main ( ) -> anyhow:: Result < ( ) > {
2928 // Setup receiving chain and graph structures.
@@ -52,38 +51,31 @@ fn main() -> anyhow::Result<()> {
5251 let rpc_client =
5352 bitcoincore_rpc:: Client :: new ( & url, bitcoincore_rpc:: Auth :: CookieFile ( cookie. into ( ) ) ) ?;
5453
55- // Initialize block emitter
56- let cp = chain. tip ( ) ;
57- let start_height = cp. height ( ) ;
58- let mut emitter = FilterIter :: new_with_checkpoint ( & rpc_client, cp) ;
54+ // Initialize `FilterIter`
55+ let mut spks = vec ! [ ] ;
5956 for ( _, desc) in graph. index . keychains ( ) {
60- let spks = SpkIterator :: new_with_range ( desc, 0 ..SPK_COUNT ) . map ( |( _, spk) | spk) ;
61- emitter. add_spks ( spks) ;
57+ spks. extend ( SpkIterator :: new_with_range ( desc, 0 ..SPK_COUNT ) . map ( |( _, s) | s) ) ;
6258 }
59+ let iter = FilterIter :: new ( & rpc_client, chain. tip ( ) , spks) ;
6360
6461 let start = Instant :: now ( ) ;
6562
66- // Sync
67- if let Some ( tip) = emitter. get_tip ( ) ? {
68- let blocks_to_scan = tip. height - start_height;
69-
70- for event in emitter. by_ref ( ) {
71- let event = event?;
72- let curr = event. height ( ) ;
73- // apply relevant blocks
74- if let Event :: Block ( EventInner { height, ref block } ) = event {
63+ for res in iter {
64+ let event = res?;
65+ match event {
66+ Event :: NoMatch { .. } => { }
67+ Event :: Block { cp, ref block } => {
68+ // Apply relevant tx data
69+ let height = cp. height ( ) ;
7570 let _ = graph. apply_block_relevant ( block, height) ;
76- println ! ( "Matched block {curr}" ) ;
71+ // Update chain tip
72+ let _ = chain. apply_update ( cp) ?;
73+ println ! ( "Matched block {height}" ) ;
7774 }
78- if curr % 1000 == 0 {
79- let progress = ( curr - start_height) as f32 / blocks_to_scan as f32 ;
80- println ! ( "[{:.2}%]" , progress * 100.0 ) ;
75+ Event :: Tip { cp } => {
76+ let _ = chain. apply_update ( cp) ?;
8177 }
8278 }
83- // update chain
84- if let Some ( cp) = emitter. chain_update ( ) {
85- let _ = chain. apply_update ( cp) ?;
86- }
8779 }
8880
8981 println ! ( "\n took: {}s" , start. elapsed( ) . as_secs( ) ) ;
@@ -105,9 +97,18 @@ fn main() -> anyhow::Result<()> {
10597 }
10698 }
10799
108- let unused_spk = graph. index . reveal_next_spk ( "external" ) . unwrap ( ) . 0 . 1 ;
109- let unused_address = Address :: from_script ( & unused_spk, NETWORK ) ?;
110- println ! ( "Next external address: {unused_address}" ) ;
100+ for canon_tx in graph. graph ( ) . list_canonical_txs (
101+ & chain,
102+ chain. tip ( ) . block_id ( ) ,
103+ bdk_chain:: CanonicalizationParams :: default ( ) ,
104+ ) {
105+ if !canon_tx. chain_position . is_confirmed ( ) {
106+ println ! (
107+ "ERROR: canonical tx should be confirmed {}" ,
108+ canon_tx. tx_node. txid
109+ ) ;
110+ }
111+ }
111112
112113 Ok ( ( ) )
113114}
0 commit comments