1
- #![ allow( clippy:: print_stdout) ]
1
+ #![ allow( clippy:: print_stdout, clippy :: print_stderr ) ]
2
2
use std:: time:: Instant ;
3
3
4
4
use anyhow:: Context ;
5
- use bdk_bitcoind_rpc:: bip158:: { Event , EventInner , FilterIter } ;
5
+ use bdk_bitcoind_rpc:: bip158:: { Event , FilterIter } ;
6
6
use bdk_chain:: bitcoin:: { constants:: genesis_block, secp256k1:: Secp256k1 , Network } ;
7
7
use bdk_chain:: indexer:: keychain_txout:: KeychainTxOutIndex ;
8
8
use bdk_chain:: local_chain:: LocalChain ;
9
9
use bdk_chain:: miniscript:: Descriptor ;
10
10
use bdk_chain:: { BlockId , ConfirmationBlockTime , IndexedTxGraph , SpkIterator } ;
11
11
use bdk_testenv:: anyhow;
12
- use bitcoin:: Address ;
13
12
14
13
// This example shows how BDK chain and tx-graph structures are updated using compact
15
14
// filters syncing. Assumes a connection can be made to a bitcoin node via environment
16
15
// variables `RPC_URL` and `RPC_COOKIE`.
17
16
18
17
// Usage: `cargo run -p bdk_bitcoind_rpc --example filter_iter`
19
18
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/*)" ;
22
21
const SPK_COUNT : u32 = 25 ;
23
22
const NETWORK : Network = Network :: Signet ;
24
23
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 " ;
27
26
28
27
fn main ( ) -> anyhow:: Result < ( ) > {
29
28
// Setup receiving chain and graph structures.
@@ -52,38 +51,31 @@ fn main() -> anyhow::Result<()> {
52
51
let rpc_client =
53
52
bitcoincore_rpc:: Client :: new ( & url, bitcoincore_rpc:: Auth :: CookieFile ( cookie. into ( ) ) ) ?;
54
53
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 ! [ ] ;
59
56
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) ) ;
62
58
}
59
+ let iter = FilterIter :: new ( & rpc_client, chain. tip ( ) , spks) ;
63
60
64
61
let start = Instant :: now ( ) ;
65
62
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 ( ) ;
75
70
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}" ) ;
77
74
}
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) ?;
81
77
}
82
78
}
83
- // update chain
84
- if let Some ( cp) = emitter. chain_update ( ) {
85
- let _ = chain. apply_update ( cp) ?;
86
- }
87
79
}
88
80
89
81
println ! ( "\n took: {}s" , start. elapsed( ) . as_secs( ) ) ;
@@ -105,9 +97,18 @@ fn main() -> anyhow::Result<()> {
105
97
}
106
98
}
107
99
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
+ eprintln ! (
107
+ "ERROR: canonical tx should be confirmed {}" ,
108
+ canon_tx. tx_node. txid
109
+ ) ;
110
+ }
111
+ }
111
112
112
113
Ok ( ( ) )
113
114
}
0 commit comments