@@ -25,6 +25,7 @@ use cnetwork::NodeId;
2525use cstate:: {
2626 ActionHandler , AssetScheme , AssetSchemeAddress , OwnedAsset , OwnedAssetAddress , StateDB , TopLevelState , TopStateView ,
2727} ;
28+ use ctimer:: { TimeoutHandler , TimerApi , TimerToken } ;
2829use ctypes:: invoice:: Invoice ;
2930use ctypes:: transaction:: Transaction ;
3031use ctypes:: { BlockNumber , ShardId } ;
@@ -41,7 +42,8 @@ use super::{
4142 AccountData , AssetClient , Balance , BlockChain as BlockChainTrait , BlockChainClient , BlockChainInfo , BlockInfo ,
4243 BlockProducer , ChainInfo , ChainNotify , ClientConfig , DatabaseClient , EngineClient , EngineInfo ,
4344 Error as ClientError , ExecuteClient , ImportBlock , ImportResult , ImportSealedBlock , MiningBlockChainClient ,
44- ParcelInfo , PrepareOpenBlock , RegularKey , RegularKeyOwner , ReopenBlock , Seq , Shard , StateOrBlock , TransactionInfo ,
45+ ParcelInfo , PrepareOpenBlock , RegularKey , RegularKeyOwner , ReopenBlock , ResealTimer , Seq , Shard , StateOrBlock ,
46+ TransactionInfo ,
4547} ;
4648use crate :: block:: { ClosedBlock , IsBlock , OpenBlock , SealedBlock } ;
4749use crate :: blockchain:: {
@@ -79,6 +81,9 @@ pub struct Client {
7981 genesis_accounts : Vec < Address > ,
8082
8183 importer : Importer ,
84+
85+ /// Timer for reseal_min_period/reseal_max_period on miner client
86+ reseal_timer : RwLock < Option < TimerApi > > ,
8287}
8388
8489impl Client {
@@ -121,13 +126,18 @@ impl Client {
121126 queue_parcels : AtomicUsize :: new ( 0 ) ,
122127 genesis_accounts,
123128 importer,
129+ reseal_timer : RwLock :: new ( None ) ,
124130 } ) ;
125131
126132 // ensure buffered changes are flushed.
127133 client. db . flush ( ) . map_err ( ClientError :: Database ) ?;
128134 Ok ( client)
129135 }
130136
137+ pub fn register_reseal_timer ( & self , timer : TimerApi ) {
138+ self . register_timer ( timer) ;
139+ }
140+
131141 /// Returns engine reference.
132142 pub fn engine ( & self ) -> & CodeChainEngine {
133143 & * self . engine
@@ -260,6 +270,53 @@ impl Client {
260270 }
261271}
262272
273+ const RESEAL_MAX_TIMER_TOKEN : TimerToken = 0 ;
274+ const RESEAL_MIN_TIMER_TOKEN : TimerToken = 1 ;
275+
276+ impl TimeoutHandler for Client {
277+ fn on_timeout ( & self , token : TimerToken ) {
278+ match token {
279+ RESEAL_MAX_TIMER_TOKEN => {
280+ // Working in PoW only
281+ if self . engine ( ) . seals_internally ( ) . is_none ( ) && !self . importer . miner . prepare_work_sealing ( self ) {
282+ self . update_sealing ( true ) ;
283+ }
284+ }
285+ RESEAL_MIN_TIMER_TOKEN => {
286+ // Checking self.ready_parcels() for efficiency
287+ if !self . ready_parcels ( ) . is_empty ( ) {
288+ self . update_sealing ( false ) ;
289+ }
290+ }
291+ _ => unreachable ! ( ) ,
292+ }
293+ }
294+ }
295+
296+ impl ResealTimer for Client {
297+ fn register_timer ( & self , timer : TimerApi ) {
298+ * self . reseal_timer . write ( ) = Some ( timer) ;
299+ }
300+
301+ fn set_max_timer ( & self ) {
302+ if let Some ( reseal_timer) = self . reseal_timer . read ( ) . as_ref ( ) {
303+ reseal_timer. cancel ( RESEAL_MAX_TIMER_TOKEN ) . expect ( "Reseal max timer clear succeeds" ) ;
304+ reseal_timer
305+ . schedule_once ( self . importer . miner . get_options ( ) . reseal_max_period , RESEAL_MAX_TIMER_TOKEN )
306+ . expect ( "Reseal max timer set succeeds" ) ;
307+ } ;
308+ }
309+
310+ fn set_min_timer ( & self ) {
311+ if let Some ( reseal_timer) = self . reseal_timer . read ( ) . as_ref ( ) {
312+ reseal_timer. cancel ( RESEAL_MIN_TIMER_TOKEN ) . expect ( "Reseal min timer clear succeeds" ) ;
313+ reseal_timer
314+ . schedule_once ( self . importer . miner . get_options ( ) . reseal_min_period , RESEAL_MIN_TIMER_TOKEN )
315+ . expect ( "Reseal min timer set succeeds" ) ;
316+ } ;
317+ }
318+ }
319+
263320impl DatabaseClient for Client {
264321 fn database ( & self ) -> Arc < KeyValueDB > {
265322 Arc :: clone ( & self . db ( ) )
@@ -367,8 +424,8 @@ impl EngineInfo for Client {
367424
368425impl EngineClient for Client {
369426 /// Make a new block and seal it.
370- fn update_sealing ( & self ) {
371- self . importer . miner . update_sealing ( self )
427+ fn update_sealing ( & self , allow_empty_block : bool ) {
428+ self . importer . miner . update_sealing ( self , allow_empty_block )
372429 }
373430
374431 /// Submit a seal for a block in the mining queue.
0 commit comments