@@ -17,6 +17,7 @@ const DEFAULT_DATABASE_PATH: &str = "fjall-blocks";
1717const BLOCKS_PARTITION : & str = "blocks" ;
1818const BLOCK_HASHES_BY_SLOT_PARTITION : & str = "block-hashes-by-slot" ;
1919const BLOCK_HASHES_BY_NUMBER_PARTITION : & str = "block-hashes-by-number" ;
20+ const BLOCK_HASHES_BY_EPOCH_SLOT_PARTITION : & str = "block-hashes-by-epoch-slot" ;
2021const TXS_PARTITION : & str = "txs" ;
2122
2223impl FjallStore {
@@ -74,6 +75,10 @@ impl super::Store for FjallStore {
7475 self . blocks . get_by_number ( number)
7576 }
7677
78+ fn get_block_by_epoch_slot ( & self , epoch : u64 , epoch_slot : u64 ) -> Result < Option < Block > > {
79+ self . blocks . get_by_epoch_slot ( epoch, epoch_slot)
80+ }
81+
7782 fn get_latest_block ( & self ) -> Result < Option < Block > > {
7883 self . blocks . get_latest ( )
7984 }
@@ -83,6 +88,7 @@ struct FjallBlockStore {
8388 blocks : Partition ,
8489 block_hashes_by_slot : Partition ,
8590 block_hashes_by_number : Partition ,
91+ block_hashes_by_epoch_slot : Partition ,
8692}
8793
8894impl FjallBlockStore {
@@ -97,10 +103,15 @@ impl FjallBlockStore {
97103 BLOCK_HASHES_BY_NUMBER_PARTITION ,
98104 fjall:: PartitionCreateOptions :: default ( ) ,
99105 ) ?;
106+ let block_hashes_by_epoch_slot = keyspace. open_partition (
107+ BLOCK_HASHES_BY_EPOCH_SLOT_PARTITION ,
108+ fjall:: PartitionCreateOptions :: default ( ) ,
109+ ) ?;
100110 Ok ( Self {
101111 blocks,
102112 block_hashes_by_slot,
103113 block_hashes_by_number,
114+ block_hashes_by_epoch_slot,
104115 } )
105116 }
106117
@@ -121,6 +132,11 @@ impl FjallBlockStore {
121132 info. number . to_be_bytes ( ) ,
122133 & info. hash ,
123134 ) ;
135+ batch. insert (
136+ & self . block_hashes_by_epoch_slot ,
137+ epoch_slot_key ( info. epoch , info. epoch_slot ) ,
138+ & info. hash ,
139+ ) ;
124140 }
125141
126142 fn get_by_hash ( & self , hash : & [ u8 ] ) -> Result < Option < Block > > {
@@ -144,6 +160,14 @@ impl FjallBlockStore {
144160 self . get_by_hash ( & hash)
145161 }
146162
163+ fn get_by_epoch_slot ( & self , epoch : u64 , epoch_slot : u64 ) -> Result < Option < Block > > {
164+ let Some ( hash) = self . block_hashes_by_epoch_slot . get ( epoch_slot_key ( epoch, epoch_slot) ) ?
165+ else {
166+ return Ok ( None ) ;
167+ } ;
168+ self . get_by_hash ( & hash)
169+ }
170+
147171 fn get_latest ( & self ) -> Result < Option < Block > > {
148172 let Some ( ( _, hash) ) = self . block_hashes_by_slot . last_key_value ( ) ? else {
149173 return Ok ( None ) ;
@@ -152,6 +176,13 @@ impl FjallBlockStore {
152176 }
153177}
154178
179+ fn epoch_slot_key ( epoch : u64 , epoch_slot : u64 ) -> [ u8 ; 16 ] {
180+ let mut key = [ 0 ; 16 ] ;
181+ key[ ..8 ] . copy_from_slice ( epoch. to_be_bytes ( ) . as_slice ( ) ) ;
182+ key[ 8 ..] . copy_from_slice ( epoch_slot. to_be_bytes ( ) . as_slice ( ) ) ;
183+ key
184+ }
185+
155186struct FjallTXStore {
156187 txs : Partition ,
157188}
@@ -276,6 +307,32 @@ mod tests {
276307 assert_eq ! ( block, new_block. unwrap( ) ) ;
277308 }
278309
310+ #[ test]
311+ fn should_get_block_by_number ( ) {
312+ let state = init_state ( ) ;
313+ let bytes = test_block_bytes ( ) ;
314+ let info = test_block_info ( & bytes) ;
315+ let block = build_block ( & info, & bytes) ;
316+
317+ state. store . insert_block ( & info, & bytes) . unwrap ( ) ;
318+
319+ let new_block = state. store . get_block_by_number ( info. number ) . unwrap ( ) ;
320+ assert_eq ! ( block, new_block. unwrap( ) ) ;
321+ }
322+
323+ #[ test]
324+ fn should_get_block_by_epoch_slot ( ) {
325+ let state = init_state ( ) ;
326+ let bytes = test_block_bytes ( ) ;
327+ let info = test_block_info ( & bytes) ;
328+ let block = build_block ( & info, & bytes) ;
329+
330+ state. store . insert_block ( & info, & bytes) . unwrap ( ) ;
331+
332+ let new_block = state. store . get_block_by_epoch_slot ( info. epoch , info. epoch_slot ) . unwrap ( ) ;
333+ assert_eq ! ( block, new_block. unwrap( ) ) ;
334+ }
335+
279336 #[ test]
280337 fn should_get_latest_block ( ) {
281338 let state = init_state ( ) ;
0 commit comments