Skip to content

Commit 919e74a

Browse files
authored
Merge pull request #890 from evanlinjin/simplify-reveal-to-target-logic
Simplify `reveal_to_target` logic
2 parents 2ae69ca + 72b1e2a commit 919e74a

File tree

2 files changed

+67
-27
lines changed

2 files changed

+67
-27
lines changed

crates/chain/src/keychain/txout_index.rs

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ pub struct KeychainTxOutIndex<K> {
6363
inner: SpkTxOutIndex<(K, u32)>,
6464
// descriptors of each keychain
6565
keychains: BTreeMap<K, Descriptor<DescriptorPublicKey>>,
66-
// last stored indexes
66+
// last revealed indexes
6767
last_revealed: BTreeMap<K, u32>,
6868
// lookahead settings for each keychain
6969
lookahead: BTreeMap<K, u32>,
@@ -381,40 +381,39 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
381381
let has_wildcard = descriptor.has_wildcard();
382382

383383
let target_index = if has_wildcard { target_index } else { 0 };
384-
let next_store_index = self.next_store_index(keychain);
385384
let next_reveal_index = self.last_revealed.get(keychain).map_or(0, |v| *v + 1);
386385
let lookahead = self.lookahead.get(keychain).map_or(0, |v| *v);
387386

388-
// if we can reveal new indexes, the latest revealed index goes here
389-
let mut revealed_index = None;
387+
debug_assert_eq!(
388+
next_reveal_index + lookahead,
389+
self.next_store_index(keychain)
390+
);
391+
392+
// if we need to reveal new indices, the latest revealed index goes here
393+
let mut reveal_to_index = None;
390394

391-
// if the target is already surpassed, we have nothing to reveal
392-
if next_reveal_index <= target_index
393-
// if the target is already stored (due to lookahead), this can be our newly revealed index
394-
&& target_index < next_reveal_index + lookahead
395-
{
396-
revealed_index = Some(target_index);
395+
// if the target is not yet revealed, but is already stored (due to lookahead), we need to
396+
// set the `reveal_to_index` as target here (as the `for` loop below only updates
397+
// `reveal_to_index` for indexes that are NOT stored)
398+
if next_reveal_index <= target_index && target_index < next_reveal_index + lookahead {
399+
reveal_to_index = Some(target_index);
397400
}
398401

399402
// we range over indexes that are not stored
400403
let range = next_reveal_index + lookahead..=target_index + lookahead;
401-
402404
for (new_index, new_spk) in range_descriptor_spks(Cow::Borrowed(descriptor), range) {
403-
// no need to store if already stored
404-
if new_index >= next_store_index {
405-
let _inserted = self
406-
.inner
407-
.insert_spk((keychain.clone(), new_index), new_spk);
408-
debug_assert!(_inserted, "must not have existing spk",);
409-
}
405+
let _inserted = self
406+
.inner
407+
.insert_spk((keychain.clone(), new_index), new_spk);
408+
debug_assert!(_inserted, "must not have existing spk",);
410409

411410
// everything after `target_index` is stored for lookahead only
412411
if new_index <= target_index {
413-
revealed_index = Some(new_index);
412+
reveal_to_index = Some(new_index);
414413
}
415414
}
416415

417-
match revealed_index {
416+
match reveal_to_index {
418417
Some(index) => {
419418
let _old_index = self.last_revealed.insert(keychain.clone(), index);
420419
debug_assert!(_old_index < Some(index));

crates/chain/tests/test_keychain_txout_index.rs

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use bdk_chain::{
77
keychain::{DerivationAdditions, KeychainTxOutIndex},
88
};
99

10-
use bitcoin::{secp256k1::Secp256k1, Script, Transaction, TxOut};
10+
use bitcoin::{secp256k1::Secp256k1, OutPoint, Script, Transaction, TxOut};
1111
use miniscript::{Descriptor, DescriptorPublicKey};
1212

1313
#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
@@ -210,13 +210,54 @@ fn test_lookahead() {
210210
last_internal_index as usize + 1,
211211
);
212212
}
213+
}
213214

214-
// when:
215-
// - scanning txouts with spks above last stored index
216-
// expect:
217-
// - cached scripts count should increase as expected
218-
// - last stored index should increase as expected
219-
// TODO!
215+
// when:
216+
// - scanning txouts with spks above last stored index
217+
// expect:
218+
// - last revealed index should increase as expected
219+
// - last used index should change as expected
220+
#[test]
221+
fn test_scan_with_lookahead() {
222+
let (mut txout_index, external_desc, _) = init_txout_index();
223+
txout_index.set_lookahead_for_all(10);
224+
225+
let spks: BTreeMap<u32, Script> = [0, 10, 20, 30]
226+
.into_iter()
227+
.map(|i| (i, external_desc.at_derivation_index(i).script_pubkey()))
228+
.collect();
229+
230+
for (&spk_i, spk) in &spks {
231+
let op = OutPoint::new(h!("fake tx"), spk_i);
232+
let txout = TxOut {
233+
script_pubkey: spk.clone(),
234+
value: 0,
235+
};
236+
237+
let additions = txout_index.scan_txout(op, &txout);
238+
assert_eq!(
239+
additions.as_inner(),
240+
&[(TestKeychain::External, spk_i)].into()
241+
);
242+
assert_eq!(
243+
txout_index.last_revealed_index(&TestKeychain::External),
244+
Some(spk_i)
245+
);
246+
assert_eq!(
247+
txout_index.last_used_index(&TestKeychain::External),
248+
Some(spk_i)
249+
);
250+
}
251+
252+
// now try with index 41 (lookahead surpassed), we expect that the txout to not be indexed
253+
let spk_41 = external_desc.at_derivation_index(41).script_pubkey();
254+
let op = OutPoint::new(h!("fake tx"), 41);
255+
let txout = TxOut {
256+
script_pubkey: spk_41,
257+
value: 0,
258+
};
259+
let additions = txout_index.scan_txout(op, &txout);
260+
assert!(additions.is_empty());
220261
}
221262

222263
#[test]

0 commit comments

Comments
 (0)