@@ -2,14 +2,13 @@ use std::path;
22use std:: sync:: Arc ;
33use std:: sync:: atomic:: { AtomicBool , Ordering } ;
44
5- use ckb_logger:: info;
6- #[ cfg( feature = "stats" ) ]
75use ckb_logger:: info;
86use ckb_metrics:: HistogramTimer ;
97#[ cfg( feature = "stats" ) ]
108use ckb_util:: { Mutex , MutexGuard } ;
9+ use ckb_util:: { RwLock , RwLockReadGuard } ;
1110
12- use ckb_types:: packed:: Byte32 ;
11+ use ckb_types:: { U256 , core :: EpochNumberWithFraction , packed:: Byte32 } ;
1312
1413use super :: { MemoryMap , SledBackend } ;
1514use crate :: types:: HeaderIndexView ;
@@ -21,6 +20,7 @@ pub(crate) struct HeaderMapKernel {
2120 memory_limit : usize ,
2221 // if ckb is in IBD mode, don't shrink memory map
2322 ibd_finished : Arc < AtomicBool > ,
23+ shared_best_header : RwLock < HeaderIndexView > ,
2424 // Statistics
2525 #[ cfg( feature = "stats" ) ]
2626 stats : Mutex < HeaderMapKernelStats > ,
@@ -54,6 +54,8 @@ impl Drop for HeaderMapKernel {
5454 self . memory
5555 . remove_batch ( items. iter ( ) . map ( |item| item. hash ( ) ) , false ) ;
5656 }
57+ let best_header = self . shared_best_header . read ( ) . clone ( ) ;
58+ self . backend . store_shared_best_header ( & best_header) ;
5759 info ! ( "HeaderMap persisted all items to backend" ) ;
5860 }
5961}
@@ -69,6 +71,11 @@ impl HeaderMapKernel {
6971 {
7072 let memory = Default :: default ( ) ;
7173 let backend = SledBackend :: new ( tmpdir) ;
74+ info ! ( "backend is empty: {}" , backend. is_empty( ) ) ;
75+ let shared_best_header_value = backend
76+ . load_shared_best_header ( )
77+ . unwrap_or_else ( Self :: default_shared_best_header) ;
78+ let shared_best_header = RwLock :: new ( shared_best_header_value) ;
7279
7380 #[ cfg( not( feature = "stats" ) ) ]
7481 {
@@ -77,6 +84,7 @@ impl HeaderMapKernel {
7784 backend,
7885 memory_limit,
7986 ibd_finished,
87+ shared_best_header,
8088 }
8189 }
8290
@@ -87,6 +95,7 @@ impl HeaderMapKernel {
8795 backend,
8896 memory_limit,
8997 ibd_finished,
98+ shared_best_header,
9099 stats : Mutex :: new ( HeaderMapKernelStats :: new ( 50_000 ) ) ,
91100 }
92101 }
@@ -192,6 +201,43 @@ impl HeaderMapKernel {
192201 }
193202 }
194203
204+ pub ( crate ) fn shared_best_header ( & self ) -> HeaderIndexView {
205+ self . shared_best_header . read ( ) . clone ( )
206+ }
207+
208+ pub ( crate ) fn shared_best_header_ref ( & self ) -> RwLockReadGuard < HeaderIndexView > {
209+ self . shared_best_header . read ( )
210+ }
211+
212+ pub ( crate ) fn set_shared_best_header ( & self , header : HeaderIndexView ) {
213+ if let Some ( metrics) = ckb_metrics:: handle ( ) {
214+ metrics. ckb_shared_best_number . set ( header. number ( ) as i64 ) ;
215+ }
216+ * self . shared_best_header . write ( ) = header;
217+ }
218+
219+ pub ( crate ) fn may_set_shared_best_header ( & self , header : HeaderIndexView ) {
220+ {
221+ let current = self . shared_best_header . read ( ) ;
222+ if !header. is_better_than ( current. total_difficulty ( ) ) {
223+ return ;
224+ }
225+ }
226+
227+ self . set_shared_best_header ( header) ;
228+ }
229+
230+ fn default_shared_best_header ( ) -> HeaderIndexView {
231+ HeaderIndexView :: new (
232+ Byte32 :: zero ( ) ,
233+ 0 ,
234+ EpochNumberWithFraction :: from_full_value ( 0 ) ,
235+ 0 ,
236+ Byte32 :: default ( ) ,
237+ U256 :: zero ( ) ,
238+ )
239+ }
240+
195241 #[ cfg( feature = "stats" ) ]
196242 fn trace ( & self ) {
197243 let mut stats = self . stats ( ) ;
0 commit comments