Skip to content

Commit f6fc514

Browse files
committed
fix test failure errors
1 parent 32d0592 commit f6fc514

File tree

3 files changed

+42
-29
lines changed

3 files changed

+42
-29
lines changed

crates/bitcoind_rpc/src/bip158.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -178,32 +178,31 @@ impl<C: RpcApi> Iterator for FilterIter<'_, C> {
178178
let height = block.height;
179179
let hash = block.hash;
180180

181-
// Check continuity with previous block for recent blocks
182-
// Only check blocks within the last 100 blocks as deep reorgs are extremely rare
183-
if height > 0 && height > self.height.saturating_sub(100) {
181+
// Enhanced reorg detection logic
182+
if height > 0 {
184183
let prev_height = height - 1;
185184

186-
// Use cached block if available, otherwise fetch
185+
// Get previous block hash from cache or node
187186
let prev_hash = match self.blocks.get(&prev_height).copied() {
188187
Some(hash) => hash,
189188
None => self.client.get_block_hash(prev_height as u64)?,
190189
};
191190

191+
// Verify chain continuity
192192
let current_header = self.client.get_block_header_info(&hash)?;
193193
if current_header.previous_block_hash != Some(prev_hash) {
194194
// Reorg detected: find fork point
195-
let fork_height = self.find_fork_point(height)?;
195+
let fork_height = self.find_fork_point(prev_height)?;
196196

197-
// Reset to fork height + 1 and clear invalid blocks
198-
self.height = fork_height + 1;
197+
// Reset state to fork height
198+
self.height = fork_height;
199199
self.blocks.retain(|h, _| *h <= fork_height);
200200

201-
// Re-fetch the tip to update block cache
202-
self.get_tip()?;
203-
continue;
201+
continue; // Restart processing from fork height
204202
}
205203
}
206204

205+
// Existing filter matching logic
207206
if self.spks.is_empty() {
208207
return Err(Error::NoScripts);
209208
} else if filter

crates/bitcoind_rpc/src/bip158.rs20336

Whitespace-only changes.

crates/bitcoind_rpc/tests/test_filter_iter.rs

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use bitcoin::{constants, Address, Amount, Network, ScriptBuf};
33
use bdk_bitcoind_rpc::bip158::{Event, FilterIter};
44
use bdk_core::{BlockId, CheckPoint};
55
use bdk_testenv::{anyhow, bitcoind, block_id, TestEnv};
6+
use bitcoin::secp256k1::rand;
67
use bitcoincore_rpc::RpcApi;
78

89
fn 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

Comments
 (0)