Skip to content

Commit ff09ef2

Browse files
authored
refactor: Make filter loading range based (#269)
1 parent ad7a6e8 commit ff09ef2

File tree

5 files changed

+44
-29
lines changed

5 files changed

+44
-29
lines changed

dash-spv/src/storage/disk/state.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -600,13 +600,8 @@ impl StorageManager for DiskStorageManager {
600600
self.filters.write().await.store_items_at_height(&[filter.to_vec()], height, self).await
601601
}
602602

603-
async fn load_filter(&self, height: u32) -> StorageResult<Option<Vec<u8>>> {
604-
self.filters
605-
.write()
606-
.await
607-
.get_items(height..height + 1)
608-
.await
609-
.map(|items| items.first().cloned())
603+
async fn load_filters(&self, range: std::ops::Range<u32>) -> StorageResult<Vec<Vec<u8>>> {
604+
self.filters.write().await.get_items(range).await
610605
}
611606

612607
async fn store_metadata(&mut self, key: &str, value: &[u8]) -> StorageResult<()> {

dash-spv/src/storage/memory.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,14 @@ impl StorageManager for MemoryStorageManager {
201201
Ok(())
202202
}
203203

204-
async fn load_filter(&self, height: u32) -> StorageResult<Option<Vec<u8>>> {
205-
Ok(self.filters.get(&height).cloned())
204+
async fn load_filters(&self, range: Range<u32>) -> StorageResult<Vec<Vec<u8>>> {
205+
let mut result = Vec::new();
206+
for height in range {
207+
if let Some(filter) = self.filters.get(&height) {
208+
result.push(filter.clone());
209+
}
210+
}
211+
Ok(result)
206212
}
207213

208214
async fn store_metadata(&mut self, key: &str, value: &[u8]) -> StorageResult<()> {

dash-spv/src/storage/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ pub trait StorageManager: Send + Sync {
142142
/// Store a compact filter at a blockchain height.
143143
async fn store_filter(&mut self, height: u32, filter: &[u8]) -> StorageResult<()>;
144144

145-
/// Load a compact filter by blockchain height.
146-
async fn load_filter(&self, height: u32) -> StorageResult<Option<Vec<u8>>>;
145+
/// Load compact filters in the given blockchain height range.
146+
async fn load_filters(&self, range: Range<u32>) -> StorageResult<Vec<Vec<u8>>>;
147147

148148
/// Store metadata.
149149
async fn store_metadata(&mut self, key: &str, value: &[u8]) -> StorageResult<()>;

dash-spv/tests/segmented_storage_test.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -314,11 +314,13 @@ async fn test_mixed_operations() {
314314
assert_eq!(storage.get_tip_height().await.unwrap(), Some(74_999));
315315
assert_eq!(storage.get_filter_tip_height().await.unwrap(), Some(74_999));
316316

317-
assert_eq!(storage.load_filter(1000).await.unwrap().unwrap(), vec![(1000 % 256) as u8; 100]);
318-
assert_eq!(
319-
storage.load_filter(50_000).await.unwrap().unwrap(),
320-
vec![(50_000 % 256) as u8; 100]
321-
);
317+
let filters = storage.load_filters(1000..1001).await.unwrap();
318+
assert_eq!(filters.len(), 1);
319+
assert_eq!(filters[0], vec![(1000 % 256) as u8; 100]);
320+
321+
let filters = storage.load_filters(50_000..50_001).await.unwrap();
322+
assert_eq!(filters.len(), 1);
323+
assert_eq!(filters[0], vec![(50_000 % 256) as u8; 100]);
322324

323325
assert_eq!(storage.load_metadata("test_key").await.unwrap().unwrap(), b"test_value");
324326

dash-spv/tests/storage_test.rs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -124,17 +124,29 @@ async fn test_memory_storage_filter_headers() {
124124
async fn test_memory_storage_filters() {
125125
let mut storage = MemoryStorageManager::new().await.expect("Failed to create memory storage");
126126

127-
// Store some test filters
128-
let filter_data = vec![1, 2, 3, 4, 5];
129-
storage.store_filter(100, &filter_data).await.expect("Failed to store filter");
130-
131-
// Retrieve filter
132-
let retrieved_filter = storage.load_filter(100).await.unwrap();
133-
assert!(retrieved_filter.is_some());
134-
assert_eq!(retrieved_filter.unwrap(), filter_data);
135-
136-
// Test non-existent filter
137-
assert!(storage.load_filter(999).await.unwrap().is_none());
127+
// Store some test filters at consecutive heights
128+
let filter_data_0 = vec![1, 2, 3, 4, 5];
129+
let filter_data_1 = vec![6, 7, 8, 9, 10];
130+
let filter_data_2 = vec![11, 12, 13, 14, 15];
131+
storage.store_filter(100, &filter_data_0).await.expect("Failed to store filter");
132+
storage.store_filter(101, &filter_data_1).await.expect("Failed to store filter");
133+
storage.store_filter(102, &filter_data_2).await.expect("Failed to store filter");
134+
135+
// Retrieve single filter via range
136+
let retrieved_filters = storage.load_filters(100..101).await.unwrap();
137+
assert_eq!(retrieved_filters.len(), 1);
138+
assert_eq!(retrieved_filters[0], filter_data_0);
139+
140+
// Retrieve multiple filters
141+
let retrieved_filters = storage.load_filters(100..103).await.unwrap();
142+
assert_eq!(retrieved_filters.len(), 3);
143+
assert_eq!(retrieved_filters[0], filter_data_0);
144+
assert_eq!(retrieved_filters[1], filter_data_1);
145+
assert_eq!(retrieved_filters[2], filter_data_2);
146+
147+
// Test non-existent range returns empty vector
148+
let empty_filters = storage.load_filters(999..1000).await.unwrap();
149+
assert!(empty_filters.is_empty());
138150
}
139151

140152
#[tokio::test]
@@ -200,7 +212,7 @@ async fn test_memory_storage_clear() {
200212
// Verify data exists
201213
assert_eq!(storage.get_tip_height().await.unwrap(), Some(4));
202214
assert_eq!(storage.get_filter_tip_height().await.unwrap(), Some(2));
203-
assert!(storage.load_filter(1).await.unwrap().is_some());
215+
assert!(!storage.load_filters(1..2).await.unwrap().is_empty());
204216
assert!(storage.load_metadata("test").await.unwrap().is_some());
205217

206218
// Clear storage
@@ -209,7 +221,7 @@ async fn test_memory_storage_clear() {
209221
// Verify everything is cleared
210222
assert_eq!(storage.get_tip_height().await.unwrap(), None);
211223
assert_eq!(storage.get_filter_tip_height().await.unwrap(), None);
212-
assert!(storage.load_filter(1).await.unwrap().is_none());
224+
assert!(storage.load_filters(1..2).await.unwrap().is_empty());
213225
assert!(storage.load_metadata("test").await.unwrap().is_none());
214226
assert!(storage.load_headers(0..5).await.unwrap().is_empty());
215227
}

0 commit comments

Comments
 (0)