@@ -5,11 +5,13 @@ use ckb_db::{
5
5
DBPinnableSlice ,
6
6
} ;
7
7
use ckb_db_schema:: {
8
- Col , COLUMN_BLOCK_BODY , COLUMN_BLOCK_EPOCH , COLUMN_BLOCK_EXT , COLUMN_BLOCK_EXTENSION ,
9
- COLUMN_BLOCK_FILTER , COLUMN_BLOCK_FILTER_HASH , COLUMN_BLOCK_HEADER , COLUMN_BLOCK_PROPOSAL_IDS ,
10
- COLUMN_BLOCK_UNCLE , COLUMN_CELL , COLUMN_CELL_DATA , COLUMN_CELL_DATA_HASH ,
11
- COLUMN_CHAIN_ROOT_MMR , COLUMN_EPOCH , COLUMN_INDEX , COLUMN_META , COLUMN_TRANSACTION_INFO ,
12
- COLUMN_UNCLES , META_CURRENT_EPOCH_KEY , META_LATEST_BUILT_FILTER_DATA_KEY , META_TIP_HEADER_KEY ,
8
+ Col , CELLS_ROOT_MMR_ELEMENT_KEY_PREFIX , CELLS_ROOT_MMR_SIZE_KEY_PREFIX ,
9
+ CELLS_ROOT_MMR_STATUS_KEY_PREFIX , COLUMN_BLOCK_BODY , COLUMN_BLOCK_EPOCH , COLUMN_BLOCK_EXT ,
10
+ COLUMN_BLOCK_EXTENSION , COLUMN_BLOCK_FILTER , COLUMN_BLOCK_FILTER_HASH , COLUMN_BLOCK_HEADER ,
11
+ COLUMN_BLOCK_PROPOSAL_IDS , COLUMN_BLOCK_UNCLE , COLUMN_CELL , COLUMN_CELLS_ROOT_MMR ,
12
+ COLUMN_CELL_DATA , COLUMN_CELL_DATA_HASH , COLUMN_CHAIN_ROOT_MMR , COLUMN_EPOCH , COLUMN_INDEX ,
13
+ COLUMN_META , COLUMN_TRANSACTION_INFO , COLUMN_UNCLES , META_CURRENT_EPOCH_KEY ,
14
+ META_LATEST_BUILT_FILTER_DATA_KEY , META_TIP_HEADER_KEY ,
13
15
} ;
14
16
use ckb_freezer:: Freezer ;
15
17
use ckb_types:: {
@@ -20,6 +22,8 @@ use ckb_types::{
20
22
} ,
21
23
packed:: { self , OutPoint } ,
22
24
prelude:: * ,
25
+ utilities:: merkle_mountain_range:: CellStatus ,
26
+ H256 ,
23
27
} ;
24
28
25
29
/// The `ChainStore` trait provides chain data store interface
@@ -576,6 +580,44 @@ pub trait ChainStore: Send + Sync + Sized {
576
580
} )
577
581
}
578
582
583
+ /// Gets cells root mmr size by block number
584
+ fn get_cells_root_mmr_size ( & self , block_number : BlockNumber ) -> u64 {
585
+ let start_key = [ CELLS_ROOT_MMR_SIZE_KEY_PREFIX , & block_number. to_be_bytes ( ) ] . concat ( ) ;
586
+ self . get_iter (
587
+ COLUMN_CELLS_ROOT_MMR ,
588
+ IteratorMode :: From ( & start_key, Direction :: Reverse ) ,
589
+ )
590
+ . take_while ( |( key, _) | key. starts_with ( CELLS_ROOT_MMR_SIZE_KEY_PREFIX ) )
591
+ . next ( )
592
+ . map ( |( _key, value) | u64:: from_le_bytes ( value. as_ref ( ) . try_into ( ) . expect ( "stored u64" ) ) )
593
+ . unwrap_or_default ( )
594
+ }
595
+
596
+ /// Gets cells root mmr status by out point
597
+ fn get_cells_root_mmr_status ( & self , out_point : & OutPoint ) -> Option < CellStatus > {
598
+ let key = [ CELLS_ROOT_MMR_STATUS_KEY_PREFIX , out_point. as_slice ( ) ] . concat ( ) ;
599
+ self . get ( COLUMN_CELLS_ROOT_MMR , & key)
600
+ . map ( |slice| CellStatus :: new_unchecked ( slice. as_ref ( ) ) )
601
+ }
602
+
603
+ /// Gets cells root mmr element by position and block number
604
+ fn get_cells_root_mmr_element ( & self , position : u64 , block_number : BlockNumber ) -> Option < H256 > {
605
+ // block_number is stored as big endian for prefix search in lexicographical order
606
+ let start_key = [
607
+ CELLS_ROOT_MMR_ELEMENT_KEY_PREFIX ,
608
+ & position. to_le_bytes ( ) ,
609
+ & block_number. to_be_bytes ( ) ,
610
+ ]
611
+ . concat ( ) ;
612
+ self . get_iter (
613
+ COLUMN_CELLS_ROOT_MMR ,
614
+ IteratorMode :: From ( & start_key, Direction :: Reverse ) ,
615
+ )
616
+ . take_while ( |( key, _) | key. starts_with ( & start_key[ 0 ..9 ] ) )
617
+ . next ( )
618
+ . map ( |( _key, value) | H256 :: from_slice ( value. as_ref ( ) ) . expect ( "stored H256" ) )
619
+ }
620
+
579
621
/// Gets ancestor block header by a base block hash and number
580
622
fn get_ancestor ( & self , base : & packed:: Byte32 , number : BlockNumber ) -> Option < HeaderView > {
581
623
let header = self . get_block_header ( base) ?;
0 commit comments