@@ -3,6 +3,7 @@ use bitcoin::{constants, Address, Amount, Network, ScriptBuf};
33use bdk_bitcoind_rpc:: bip158:: { Event , FilterIter } ;
44use bdk_core:: { BlockId , CheckPoint } ;
55use bdk_testenv:: { anyhow, bitcoind, block_id, TestEnv } ;
6+ use bitcoin:: secp256k1:: rand;
67use bitcoincore_rpc:: RpcApi ;
78
89fn testenv ( ) -> anyhow:: Result < TestEnv > {
@@ -169,34 +170,44 @@ fn test_reorg_handling() -> anyhow::Result<()> {
169170 let env = testenv ( ) ?;
170171 let rpc = env. rpc_client ( ) ;
171172
172- // Make sure we have a chain with sufficient height
173+ let secp = bitcoin:: secp256k1:: Secp256k1 :: new ( ) ;
174+
175+ // Generate compressed key pair
176+ let ( sk, _) = secp. generate_keypair ( & mut rand:: thread_rng ( ) ) ;
177+ let secp_pubkey = bitcoin:: secp256k1:: PublicKey :: from_secret_key ( & secp, & sk) ;
178+ let pubkey = bitcoin:: PublicKey :: new ( secp_pubkey) ;
179+
180+ // Get wpkh (will be compressed since from_secret_key creates compressed keys)
181+ let wpkh = pubkey
182+ . wpubkey_hash ( )
183+ . expect ( "Public key should be compressed for wpkh" ) ;
184+
185+ let spk = ScriptBuf :: new_p2wpkh ( & wpkh) ;
186+
187+ // Mine initial chain up to height 99
173188 while rpc. get_block_count ( ) ? < 99 {
174189 env. mine_blocks ( 1 , None ) ?;
175190 }
176191
177- // Mine initial chain: 100:A, 101:B
192+ // Mine initial blocks 100:A, 101:B
178193 let block_a_hash = env. mine_blocks ( 1 , None ) ?[ 0 ] ;
179194 let _block_b_hash = env. mine_blocks ( 1 , None ) ?[ 0 ] ;
180195
181- // Create SPK to test with
182- let dummy_spk = ScriptBuf :: new ( ) ;
183-
196+ // Create FilterIter starting at height 100
184197 let mut iter = FilterIter :: new_with_height ( rpc, 100 ) ;
185- iter. add_spks ( vec ! [ dummy_spk . clone( ) ] ) ;
198+ iter. add_spk ( spk . clone ( ) ) ;
186199
187- // Process block 100:A
200+ // Process block 100:A (NoMatch)
188201 assert ! ( matches!(
189202 iter. next( ) . transpose( ) ?,
190203 Some ( Event :: NoMatch ( 100 ) )
191204 ) ) ;
192205
193- // Reorg to 100:A', 101:B'
194- // 1. Invalidate existing blocks
206+ // Reorg: Invalidate A, mine new chain A'->B' with a matching transaction
195207 rpc. invalidate_block ( & block_a_hash) ?;
196208
197- // 2. Mine new chain with transaction matching our SPK
198- // Create a transaction that matches our dummy SPK for block A'
199- let address = Address :: from_script ( & dummy_spk, Network :: Regtest ) ?;
209+ // Create transaction matching our SPK
210+ let address = Address :: from_script ( & spk, Network :: Regtest ) ?;
200211 rpc. send_to_address (
201212 & address,
202213 Amount :: from_sat ( 1000 ) ,
@@ -208,24 +219,27 @@ fn test_reorg_handling() -> anyhow::Result<()> {
208219 None ,
209220 ) ?;
210221
211- // Mine new blocks
222+ // Mine new blocks 100:A', 101:B'
212223 let block_a_prime = env. mine_blocks ( 1 , None ) ?[ 0 ] ;
213224 let _block_b_prime = env. mine_blocks ( 1 , None ) ?[ 0 ] ;
214225
215- // Process new blocks - should detect reorg and match the transaction
226+ // Process reorged blocks
216227 match iter. next ( ) . transpose ( ) ? {
217228 Some ( Event :: Block ( inner) ) => {
218229 assert_eq ! ( inner. height, 100 ) ;
219230 assert_eq ! ( inner. block. block_hash( ) , block_a_prime) ;
231+ // Verify transaction exists
232+ assert ! ( inner
233+ . block
234+ . txdata
235+ . iter( )
236+ . any( |tx| tx. output. iter( ) . any( |o| o. script_pubkey == spk) ) ) ;
220237 }
221- other => panic ! ( "Expected block 100:A' , got {:?}" , other) ,
238+ other => panic ! ( "Expected Block( 100) , got {:?}" , other) ,
222239 }
223240
224- // The second block should be a NoMatch since we don't have a matching transaction
225241 match iter. next ( ) . transpose ( ) ? {
226- Some ( Event :: NoMatch ( 101 ) ) => { /* Expected */ }
242+ Some ( Event :: NoMatch ( 101 ) ) => Ok ( ( ) ) ,
227243 other => panic ! ( "Expected NoMatch(101), got {:?}" , other) ,
228244 }
229-
230- Ok ( ( ) )
231245}
0 commit comments