@@ -333,6 +333,7 @@ impl std::error::Error for Error {}
333
333
mod test {
334
334
use super :: * ;
335
335
336
+ use bdk_chain:: local_chain:: LocalChain ;
336
337
use bdk_testenv:: { anyhow, bitcoind, TestEnv } ;
337
338
use bitcoin:: { Address , Amount , Network , ScriptBuf } ;
338
339
use bitcoincore_rpc:: RpcApi ;
@@ -347,6 +348,67 @@ mod test {
347
348
} )
348
349
}
349
350
351
+ #[ test]
352
+ fn chain_update_must_connect_with_reorg_after_constructing_iter ( ) -> anyhow:: Result < ( ) > {
353
+ let env = testenv ( ) ?;
354
+ let _ = env. mine_blocks ( 100 , None ) ;
355
+
356
+ // Initialize `chain` to have 3 blocks: genesis, some-middle-block and the original tip.
357
+ let ( mut chain, _) = LocalChain :: from_genesis_hash ( env. genesis_hash ( ) ?) ;
358
+ {
359
+ let tip_height = env. rpc_client ( ) . get_block_count ( ) ?;
360
+ let tip_hash = env. rpc_client ( ) . get_block_hash ( tip_height) ?;
361
+ let mid_height = tip_height / 2 ;
362
+ let mid_hash = env. rpc_client ( ) . get_block_hash ( mid_height) ?;
363
+ chain. insert_block ( BlockId {
364
+ height : tip_height as _ ,
365
+ hash : tip_hash,
366
+ } ) ?;
367
+ chain. insert_block ( BlockId {
368
+ height : mid_height as _ ,
369
+ hash : mid_hash,
370
+ } ) ?;
371
+ }
372
+
373
+ // Advance remote chain.
374
+ let _ = env. mine_blocks ( 1 , None ) ;
375
+
376
+ // Initialize `iter` with the `chain`'s view.
377
+ let mut iter = FilterIter :: new_with_checkpoint ( env. rpc_client ( ) , chain. tip ( ) ) ?;
378
+ iter. add_spk (
379
+ env. rpc_client ( )
380
+ . get_new_address ( None , None ) ?
381
+ . assume_checked ( )
382
+ . script_pubkey ( ) ,
383
+ ) ;
384
+
385
+ // Reorg happends after initializing `iter`.
386
+ env. reorg ( 2 ) ?;
387
+
388
+ // Exhaust `iter`.
389
+ let _ = iter. get_tip ( ) ?. expect ( "must get target" ) ;
390
+ while let Some ( r) = iter. next ( ) {
391
+ r?;
392
+ }
393
+
394
+ // Try contruct chain update and apply it.
395
+ let update = iter. chain_update ( ) . expect ( "must get update" ) ;
396
+ print_cp ( "update" , & update) ;
397
+ print_cp ( "chain" , & chain. tip ( ) ) ;
398
+ chain. apply_update ( update) . expect ( "must apply update" ) ;
399
+
400
+ Ok ( ( ) )
401
+ }
402
+
403
+ fn print_cp ( label : & str , cp : & CheckPoint ) {
404
+ println ! ( "Printing heights of '{label}': " ) ;
405
+ for b in cp. iter ( ) {
406
+ let height = b. height ( ) ;
407
+ let hash = b. hash ( ) ;
408
+ println ! ( "\t {height:3} : {hash}" ) ;
409
+ }
410
+ }
411
+
350
412
#[ test]
351
413
fn filter_iter_matches_blocks ( ) -> anyhow:: Result < ( ) > {
352
414
let env = testenv ( ) ?;
0 commit comments