@@ -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 . read ( ) . 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,60 @@ 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+ if let Some ( reseal_timer) = self . reseal_timer . read ( ) . as_ref ( ) {
287+ reseal_timer. cancel ( RESEAL_MAX_TIMER_TOKEN ) . expect ( "Reseal max timer clear succeeds" ) ;
288+ } ;
289+
290+ // Checking self.ready_parcels() for efficiency
291+ if !self . ready_parcels ( ) . is_empty ( ) {
292+ self . update_sealing ( false ) ;
293+ }
294+ }
295+ _ => unreachable ! ( ) ,
296+ }
297+ }
298+ }
299+
300+ impl ResealTimer for Client {
301+ fn register_timer ( & self , timer : TimerApi ) {
302+ timer
303+ . schedule_once ( self . importer . miner . get_options ( ) . reseal_max_period , RESEAL_MAX_TIMER_TOKEN )
304+ . expect ( "Reseal max timer set succeeds" ) ;
305+ * self . reseal_timer . write ( ) = Some ( timer) ;
306+ }
307+
308+ fn set_max_timer ( & self ) {
309+ if let Some ( reseal_timer) = self . reseal_timer . read ( ) . as_ref ( ) {
310+ reseal_timer. cancel ( RESEAL_MAX_TIMER_TOKEN ) . expect ( "Reseal max timer clear succeeds" ) ;
311+ reseal_timer
312+ . schedule_once ( self . importer . miner . get_options ( ) . reseal_max_period , RESEAL_MAX_TIMER_TOKEN )
313+ . expect ( "Reseal max timer set succeeds" ) ;
314+ } ;
315+ }
316+
317+ fn set_min_timer ( & self ) {
318+ if let Some ( reseal_timer) = self . reseal_timer . read ( ) . as_ref ( ) {
319+ reseal_timer. cancel ( RESEAL_MIN_TIMER_TOKEN ) . expect ( "Reseal min timer clear succeeds" ) ;
320+ reseal_timer
321+ . schedule_once ( self . importer . miner . get_options ( ) . reseal_min_period , RESEAL_MIN_TIMER_TOKEN )
322+ . expect ( "Reseal min timer set succeeds" ) ;
323+ } ;
324+ }
325+ }
326+
263327impl DatabaseClient for Client {
264328 fn database ( & self ) -> Arc < KeyValueDB > {
265329 Arc :: clone ( & self . db ( ) )
@@ -367,8 +431,8 @@ impl EngineInfo for Client {
367431
368432impl EngineClient for Client {
369433 /// Make a new block and seal it.
370- fn update_sealing ( & self ) {
371- self . importer . miner . update_sealing ( self )
434+ fn update_sealing ( & self , allow_empty_block : bool ) {
435+ self . importer . miner . update_sealing ( self , allow_empty_block )
372436 }
373437
374438 /// Submit a seal for a block in the mining queue.
0 commit comments