Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 39 additions & 11 deletions key-wallet/src/managed_account/address_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -885,8 +885,8 @@ impl AddressPool {
/// Generate addresses to maintain the gap limit
pub fn maintain_gap_limit(&mut self, key_source: &KeySource) -> Result<Vec<Address>> {
let target = match self.highest_used {
None => self.gap_limit,
Some(highest) => highest + self.gap_limit + 1,
None => self.gap_limit - 1,
Some(highest) => highest + self.gap_limit,
};

let mut new_addresses = Vec::new();
Expand Down Expand Up @@ -1229,21 +1229,49 @@ mod tests {
#[test]
fn test_gap_limit_maintenance() {
let base_path = DerivationPath::from(vec![ChildNumber::from_normal_idx(0).unwrap()]);
let mut pool = AddressPool::new_without_generation(
let key_source = test_key_source();
let gap_limit = 5;

// Create pool with gap_limit addresses already generated
let mut pool = AddressPool::new(
base_path,
AddressPoolType::External,
5,
gap_limit,
Network::Testnet,
);
let key_source = test_key_source();
&key_source,
)
.unwrap();

// Verify gap_limit addresses generated, none used
assert_eq!(pool.highest_generated, Some(gap_limit - 1));
assert_eq!(pool.highest_used, None);
assert_eq!(pool.addresses.len(), gap_limit as usize);

// Calling maintain_gap_limit should not generate any new addresses when none are used
let new_addresses = pool.maintain_gap_limit(&key_source).unwrap();
assert_eq!(new_addresses.len(), 0);
assert_eq!(pool.highest_generated, Some(gap_limit - 1));
assert_eq!(pool.addresses.len(), gap_limit as usize);

// Mark address at index 0 as used
pool.mark_index_used(0);
assert_eq!(pool.highest_used, Some(0));

// Should generate exactly 1 address to maintain gap_limit unused after index 0
let new_addresses = pool.maintain_gap_limit(&key_source).unwrap();
assert_eq!(new_addresses.len(), 1);
assert_eq!(pool.highest_generated, Some(gap_limit));
assert_eq!(pool.addresses.len(), gap_limit as usize + 1);

// Generate initial addresses
pool.generate_addresses(3, &key_source, true).unwrap();
// Mark address at index 1 and 2 as used
pool.mark_index_used(1);
pool.mark_index_used(2);

// Maintain gap limit
let _new_addrs = pool.maintain_gap_limit(&key_source).unwrap();
assert!(pool.highest_generated.unwrap_or(0) >= 6); // Should have at least index 1 + gap limit 5
// Should generate exactly 2 more addresses
let new_addresses = pool.maintain_gap_limit(&key_source).unwrap();
assert_eq!(new_addresses.len(), 2);
assert_eq!(pool.highest_generated, Some(gap_limit + 2));
assert_eq!(pool.addresses.len(), gap_limit as usize + 3);
}

#[test]
Expand Down