@@ -980,10 +980,62 @@ mod tests {
980980 let result75 = cursor75. seek ( storage_key) ?. unwrap ( ) ;
981981 assert_eq ! ( result75. 1 , U256 :: from( 100 ) ) ;
982982
983- // Cursor after deletion should see zero
983+ // Cursor after deletion should NOT see the entry ( zero values are skipped)
984984 let mut cursor150 = storage. storage_hashed_cursor ( hashed_address, 150 ) ?;
985- let result150 = cursor150. seek ( storage_key) ?. unwrap ( ) ;
986- assert_eq ! ( result150. 1 , U256 :: ZERO ) ;
985+ let result150 = cursor150. seek ( storage_key) ?;
986+ assert ! ( result150. is_none( ) , "Zero values should be skipped/deleted" ) ;
987+
988+ Ok ( ( ) )
989+ }
990+
991+ /// Test that zero values are skipped during iteration
992+ #[ test_case( InMemoryExternalStorage :: new( ) ; "InMemory" ) ]
993+ #[ tokio:: test]
994+ async fn test_storage_cursor_skips_zero_values < S : ExternalStorage > (
995+ storage : S ,
996+ ) -> Result < ( ) , ExternalStorageError > {
997+ let hashed_address = B256 :: repeat_byte ( 0x01 ) ;
998+
999+ // Create a mix of non-zero and zero value storage slots
1000+ let storage_slots = vec ! [
1001+ ( B256 :: repeat_byte( 0x10 ) , U256 :: from( 100 ) ) , // Non-zero
1002+ ( B256 :: repeat_byte( 0x20 ) , U256 :: ZERO ) , // Zero value - should be skipped
1003+ ( B256 :: repeat_byte( 0x30 ) , U256 :: from( 300 ) ) , // Non-zero
1004+ ( B256 :: repeat_byte( 0x40 ) , U256 :: ZERO ) , // Zero value - should be skipped
1005+ ( B256 :: repeat_byte( 0x50 ) , U256 :: from( 500 ) ) , // Non-zero
1006+ ] ;
1007+
1008+ // Store all slots
1009+ storage. store_hashed_storages ( hashed_address, storage_slots. clone ( ) , 50 ) . await ?;
1010+
1011+ // Create cursor and iterate through all entries
1012+ let mut cursor = storage. storage_hashed_cursor ( hashed_address, 100 ) ?;
1013+ let mut found_slots = Vec :: new ( ) ;
1014+ while let Some ( ( key, value) ) = cursor. next ( ) ? {
1015+ found_slots. push ( ( key, value) ) ;
1016+ }
1017+
1018+ // Should only find 3 non-zero values
1019+ assert_eq ! ( found_slots. len( ) , 3 , "Zero values should be skipped during iteration" ) ;
1020+
1021+ // Verify the non-zero values are the ones we stored
1022+ assert_eq ! ( found_slots[ 0 ] , ( B256 :: repeat_byte( 0x10 ) , U256 :: from( 100 ) ) ) ;
1023+ assert_eq ! ( found_slots[ 1 ] , ( B256 :: repeat_byte( 0x30 ) , U256 :: from( 300 ) ) ) ;
1024+ assert_eq ! ( found_slots[ 2 ] , ( B256 :: repeat_byte( 0x50 ) , U256 :: from( 500 ) ) ) ;
1025+
1026+ // Verify seeking to a zero-value slot returns None or skips to next non-zero
1027+ let mut seek_cursor = storage. storage_hashed_cursor ( hashed_address, 100 ) ?;
1028+ let seek_result = seek_cursor. seek ( B256 :: repeat_byte ( 0x20 ) ) ?;
1029+
1030+ // Should either return None or skip to the next non-zero value (0x30)
1031+ if let Some ( ( key, value) ) = seek_result {
1032+ assert_eq ! (
1033+ key,
1034+ B256 :: repeat_byte( 0x30 ) ,
1035+ "Should skip zero value and find next non-zero"
1036+ ) ;
1037+ assert_eq ! ( value, U256 :: from( 300 ) ) ;
1038+ }
9871039
9881040 Ok ( ( ) )
9891041 }
0 commit comments