@@ -11,7 +11,7 @@ use tracing::debug;
1111
1212use crate :: {
1313 filter:: LogFilter ,
14- types:: { IndexedBlock , IndexedLog , IndexedReceipt , IndexedTransaction } ,
14+ types:: { IndexStats , IndexedBlock , IndexedLog , IndexedReceipt , IndexedTransaction } ,
1515} ;
1616
1717/// In-memory storage for indexed blocks, transactions, receipts, and logs.
@@ -161,6 +161,36 @@ impl BlockIndex {
161161 result
162162 }
163163
164+ /// Returns the total number of indexed blocks.
165+ pub fn block_count ( & self ) -> usize {
166+ self . blocks_by_hash . read ( ) . len ( )
167+ }
168+
169+ /// Returns the total number of indexed transactions.
170+ pub fn transaction_count ( & self ) -> usize {
171+ self . transactions . read ( ) . len ( )
172+ }
173+
174+ /// Returns the total number of indexed receipts.
175+ pub fn receipt_count ( & self ) -> usize {
176+ self . receipts . read ( ) . len ( )
177+ }
178+
179+ /// Returns true if the index is empty (no blocks indexed).
180+ pub fn is_empty ( & self ) -> bool {
181+ self . blocks_by_hash . read ( ) . is_empty ( )
182+ }
183+
184+ /// Returns statistics about the index.
185+ pub fn stats ( & self ) -> IndexStats {
186+ IndexStats {
187+ block_count : self . block_count ( ) ,
188+ transaction_count : self . transaction_count ( ) ,
189+ receipt_count : self . receipt_count ( ) ,
190+ head_block_number : self . head_block_number ( ) ,
191+ }
192+ }
193+
164194 fn matches_filter ( log : & IndexedLog , filter : & LogFilter ) -> bool {
165195 if let Some ( addresses) = & filter. address
166196 && !addresses. contains ( & log. address )
@@ -239,7 +269,7 @@ mod tests {
239269 let block_hash = B256 :: repeat_byte ( 1 ) ;
240270 let block = create_test_block ( 1 , block_hash) ;
241271
242- index. insert_block ( block. clone ( ) , vec ! [ ] , vec ! [ ] ) ;
272+ index. insert_block ( block, vec ! [ ] , vec ! [ ] ) ;
243273
244274 let retrieved = index. get_block_by_hash ( & block_hash) . unwrap ( ) ;
245275 assert_eq ! ( retrieved. number, 1 ) ;
@@ -258,7 +288,7 @@ mod tests {
258288 let tx = create_test_tx ( tx_hash, block_hash, 1 ) ;
259289 let receipt = create_test_receipt ( tx_hash, block_hash, 1 ) ;
260290
261- index. insert_block ( block, vec ! [ tx] , vec ! [ receipt. clone ( ) ] ) ;
291+ index. insert_block ( block, vec ! [ tx] , vec ! [ receipt] ) ;
262292
263293 let retrieved_tx = index. get_transaction ( & tx_hash) . unwrap ( ) ;
264294 assert_eq ! ( retrieved_tx. hash, tx_hash) ;
@@ -325,4 +355,75 @@ mod tests {
325355 let logs = index. get_logs ( & filter) ;
326356 assert ! ( logs. is_empty( ) ) ;
327357 }
358+
359+ #[ test]
360+ fn test_is_empty ( ) {
361+ let index = BlockIndex :: new ( ) ;
362+ assert ! ( index. is_empty( ) ) ;
363+
364+ index. insert_block ( create_test_block ( 1 , B256 :: repeat_byte ( 1 ) ) , vec ! [ ] , vec ! [ ] ) ;
365+ assert ! ( !index. is_empty( ) ) ;
366+ }
367+
368+ #[ test]
369+ fn test_block_count ( ) {
370+ let index = BlockIndex :: new ( ) ;
371+ assert_eq ! ( index. block_count( ) , 0 ) ;
372+
373+ index. insert_block ( create_test_block ( 1 , B256 :: repeat_byte ( 1 ) ) , vec ! [ ] , vec ! [ ] ) ;
374+ assert_eq ! ( index. block_count( ) , 1 ) ;
375+
376+ index. insert_block ( create_test_block ( 2 , B256 :: repeat_byte ( 2 ) ) , vec ! [ ] , vec ! [ ] ) ;
377+ assert_eq ! ( index. block_count( ) , 2 ) ;
378+ }
379+
380+ #[ test]
381+ fn test_transaction_count ( ) {
382+ let index = BlockIndex :: new ( ) ;
383+ assert_eq ! ( index. transaction_count( ) , 0 ) ;
384+
385+ let block_hash = B256 :: repeat_byte ( 1 ) ;
386+ let tx1 = create_test_tx ( B256 :: repeat_byte ( 2 ) , block_hash, 1 ) ;
387+ let tx2 = create_test_tx ( B256 :: repeat_byte ( 3 ) , block_hash, 1 ) ;
388+
389+ index. insert_block ( create_test_block ( 1 , block_hash) , vec ! [ tx1, tx2] , vec ! [ ] ) ;
390+ assert_eq ! ( index. transaction_count( ) , 2 ) ;
391+ }
392+
393+ #[ test]
394+ fn test_receipt_count ( ) {
395+ let index = BlockIndex :: new ( ) ;
396+ assert_eq ! ( index. receipt_count( ) , 0 ) ;
397+
398+ let block_hash = B256 :: repeat_byte ( 1 ) ;
399+ let tx_hash = B256 :: repeat_byte ( 2 ) ;
400+ let receipt = create_test_receipt ( tx_hash, block_hash, 1 ) ;
401+
402+ index. insert_block ( create_test_block ( 1 , block_hash) , vec ! [ ] , vec ! [ receipt] ) ;
403+ assert_eq ! ( index. receipt_count( ) , 1 ) ;
404+ }
405+
406+ #[ test]
407+ fn test_stats ( ) {
408+ let index = BlockIndex :: new ( ) ;
409+
410+ let stats = index. stats ( ) ;
411+ assert_eq ! ( stats. block_count, 0 ) ;
412+ assert_eq ! ( stats. transaction_count, 0 ) ;
413+ assert_eq ! ( stats. receipt_count, 0 ) ;
414+ assert_eq ! ( stats. head_block_number, 0 ) ;
415+
416+ let block_hash = B256 :: repeat_byte ( 1 ) ;
417+ let tx_hash = B256 :: repeat_byte ( 2 ) ;
418+ let tx = create_test_tx ( tx_hash, block_hash, 5 ) ;
419+ let receipt = create_test_receipt ( tx_hash, block_hash, 5 ) ;
420+
421+ index. insert_block ( create_test_block ( 5 , block_hash) , vec ! [ tx] , vec ! [ receipt] ) ;
422+
423+ let stats = index. stats ( ) ;
424+ assert_eq ! ( stats. block_count, 1 ) ;
425+ assert_eq ! ( stats. transaction_count, 1 ) ;
426+ assert_eq ! ( stats. receipt_count, 1 ) ;
427+ assert_eq ! ( stats. head_block_number, 5 ) ;
428+ }
328429}
0 commit comments