@@ -8,8 +8,9 @@ use ckb_logger::info;
88use ckb_metrics:: HistogramTimer ;
99#[ cfg( feature = "stats" ) ]
1010use ckb_util:: { Mutex , MutexGuard } ;
11+ use ckb_util:: { RwLock , RwLockReadGuard } ;
1112
12- use ckb_types:: packed:: Byte32 ;
13+ use ckb_types:: { U256 , core :: EpochNumberWithFraction , packed:: Byte32 } ;
1314
1415use super :: { MemoryMap , SledBackend } ;
1516use crate :: types:: HeaderIndexView ;
@@ -21,6 +22,7 @@ pub(crate) struct HeaderMapKernel {
2122 memory_limit : usize ,
2223 // if ckb is in IBD mode, don't shrink memory map
2324 ibd_finished : Arc < AtomicBool > ,
25+ shared_best_header : RwLock < HeaderIndexView > ,
2426 // Statistics
2527 #[ cfg( feature = "stats" ) ]
2628 stats : Mutex < HeaderMapKernelStats > ,
@@ -54,6 +56,8 @@ impl Drop for HeaderMapKernel {
5456 self . memory
5557 . remove_batch ( items. iter ( ) . map ( |item| item. hash ( ) ) , false ) ;
5658 }
59+ let best_header = self . shared_best_header . read ( ) . clone ( ) ;
60+ self . backend . store_shared_best_header ( & best_header) ;
5761 info ! ( "HeaderMap persisted all items to backend" ) ;
5862 }
5963}
@@ -69,6 +73,11 @@ impl HeaderMapKernel {
6973 {
7074 let memory = Default :: default ( ) ;
7175 let backend = SledBackend :: new ( tmpdir) ;
76+ info ! ( "backend is empty: {}" , backend. is_empty( ) ) ;
77+ let shared_best_header_value = backend
78+ . load_shared_best_header ( )
79+ . unwrap_or_else ( Self :: default_shared_best_header) ;
80+ let shared_best_header = RwLock :: new ( shared_best_header_value) ;
7281
7382 #[ cfg( not( feature = "stats" ) ) ]
7483 {
@@ -77,6 +86,7 @@ impl HeaderMapKernel {
7786 backend,
7887 memory_limit,
7988 ibd_finished,
89+ shared_best_header,
8090 }
8191 }
8292
@@ -87,6 +97,7 @@ impl HeaderMapKernel {
8797 backend,
8898 memory_limit,
8999 ibd_finished,
100+ shared_best_header,
90101 stats : Mutex :: new ( HeaderMapKernelStats :: new ( 50_000 ) ) ,
91102 }
92103 }
@@ -192,6 +203,43 @@ impl HeaderMapKernel {
192203 }
193204 }
194205
206+ pub ( crate ) fn shared_best_header ( & self ) -> HeaderIndexView {
207+ self . shared_best_header . read ( ) . clone ( )
208+ }
209+
210+ pub ( crate ) fn shared_best_header_ref ( & self ) -> RwLockReadGuard < HeaderIndexView > {
211+ self . shared_best_header . read ( )
212+ }
213+
214+ pub ( crate ) fn set_shared_best_header ( & self , header : HeaderIndexView ) {
215+ if let Some ( metrics) = ckb_metrics:: handle ( ) {
216+ metrics. ckb_shared_best_number . set ( header. number ( ) as i64 ) ;
217+ }
218+ * self . shared_best_header . write ( ) = header;
219+ }
220+
221+ pub ( crate ) fn may_set_shared_best_header ( & self , header : HeaderIndexView ) {
222+ {
223+ let current = self . shared_best_header . read ( ) ;
224+ if !header. is_better_than ( current. total_difficulty ( ) ) {
225+ return ;
226+ }
227+ }
228+
229+ self . set_shared_best_header ( header) ;
230+ }
231+
232+ fn default_shared_best_header ( ) -> HeaderIndexView {
233+ HeaderIndexView :: new (
234+ Byte32 :: zero ( ) ,
235+ 0 ,
236+ EpochNumberWithFraction :: from_full_value ( 0 ) ,
237+ 0 ,
238+ Byte32 :: default ( ) ,
239+ U256 :: zero ( ) ,
240+ )
241+ }
242+
195243 #[ cfg( feature = "stats" ) ]
196244 fn trace ( & self ) {
197245 let mut stats = self . stats ( ) ;
0 commit comments