Skip to content

Commit

Permalink
fix(chain): KeychainTxOutIndex::lookahead_to_target
Browse files Browse the repository at this point in the history
  • Loading branch information
evanlinjin committed Feb 16, 2024
1 parent 50c549b commit e59eec9
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 4 deletions.
13 changes: 9 additions & 4 deletions crates/chain/src/keychain/txout_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,12 +326,17 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
self.lookahead
}

/// Store lookahead scripts until `target_index`.
/// Store lookahead scripts until `target_index` (inclusive).
///
/// This does not change the `lookahead` setting.
/// This does not change the global `lookahead` setting.
pub fn lookahead_to_target(&mut self, keychain: &K, target_index: u32) {
let next_index = self.next_store_index(keychain);
if let Some(temp_lookahead) = target_index.checked_sub(next_index).filter(|&v| v > 0) {
let (next_index, _) = self.next_index(keychain);

let temp_lookahead = (target_index + 1)
.checked_sub(next_index)
.filter(|&index| index > 0);

if let Some(temp_lookahead) = temp_lookahead {
self.replenish_lookahead(keychain, temp_lookahead);
}
}
Expand Down
95 changes: 95 additions & 0 deletions crates/chain/tests/test_keychain_txout_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,3 +386,98 @@ fn test_non_wildcard_derivations() {
1,
);
}

#[test]
fn lookahead_to_target() {
#[derive(Default)]
struct TestCase {
lookahead: u32, // Global lookahead value
external_last_revealed: Option<u32>, // Last revealed index for external keychain
internal_last_revealed: Option<u32>, // Last revealed index for internal keychain
external_target: Option<u32>, // Call `lookahead_to_target(External, u32)`
internal_target: Option<u32>, // Call `lookahead_to_target(Internal, u32)`
}

let test_cases = &[
TestCase {
lookahead: 0,
external_target: Some(100),
..Default::default()
},
TestCase {
lookahead: 10,
internal_target: Some(99),
..Default::default()
},
TestCase {
lookahead: 100,
internal_target: Some(9),
external_target: Some(10),
..Default::default()
},
TestCase {
lookahead: 12,
external_last_revealed: Some(2),
internal_last_revealed: Some(2),
internal_target: Some(15),
external_target: Some(13),
},
TestCase {
lookahead: 13,
external_last_revealed: Some(100),
internal_last_revealed: Some(21),
internal_target: Some(120),
external_target: Some(130),
},
];

for t in test_cases {
let (mut index, _, _) = init_txout_index(t.lookahead);

if let Some(last_revealed) = t.external_last_revealed {
let _ = index.reveal_to_target(&TestKeychain::External, last_revealed);
}

if let Some(last_revealed) = t.internal_last_revealed {
let _ = index.reveal_to_target(&TestKeychain::Internal, last_revealed);
}

if let Some(external_target) = t.external_target {
let normal_last = match t.external_last_revealed {
Some(last_revealed) => Some(last_revealed + t.lookahead),
None => t.lookahead.checked_sub(1),
};

index.lookahead_to_target(&TestKeychain::External, external_target);
let external_keys = index
.inner()
.all_spks()
.range((TestKeychain::External, 0)..=(TestKeychain::External, u32::MAX))
.map(|(k, _)| k.clone())
.collect::<Vec<_>>();
let exp_external_keys = core::iter::repeat(TestKeychain::External)
.zip(0_u32..=Ord::max(external_target, normal_last.unwrap_or(0)))
.collect::<Vec<_>>();
assert_eq!(external_keys, exp_external_keys);
}

if let Some(internal_target) = t.internal_target {
let normal_last = match t.internal_last_revealed {
Some(last_revealed) => Some(last_revealed + t.lookahead),
None => t.lookahead.checked_sub(1),
};

index.lookahead_to_target(&TestKeychain::Internal, internal_target);
let external_keys = index
.inner()
.all_spks()
.range((TestKeychain::Internal, 0)..=(TestKeychain::Internal, u32::MAX))
.map(|(k, _)| k.clone())
.collect::<Vec<_>>();
let exp_external_keys = core::iter::repeat(TestKeychain::Internal)
.zip(0_u32..=Ord::max(internal_target, normal_last.unwrap_or(0)))
.collect::<Vec<_>>();
assert_eq!(external_keys, exp_external_keys);
}
}
}

0 comments on commit e59eec9

Please sign in to comment.