@@ -23,15 +23,23 @@ pub use its_consensus_common::BlockImport;
2323use crate :: { AuraVerifier , EnclaveOnChainOCallApi , SidechainBlockTrait } ;
2424use ita_stf:: hash:: TrustedOperationOrHash ;
2525use itc_parentchain_block_import_dispatcher:: triggered_dispatcher:: TriggerParentchainBlockImport ;
26+ use itc_parentchain_indirect_calls_executor:: executor:: litentry:: get_scheduled_enclave:: GLOBAL_SIDECHAIN_SCHEDULED_ENCLABES ;
27+ use itp_component_container:: component_container:: ComponentGetter ;
2628use itp_enclave_metrics:: EnclaveMetric ;
29+ use itp_enclave_scheduled:: ScheduledEnclaveHandle ;
2730use itp_ocall_api:: { EnclaveMetricsOCallApi , EnclaveSidechainOCallApi } ;
2831use itp_settings:: sidechain:: SLOT_DURATION ;
2932use itp_sgx_crypto:: { key_repository:: AccessKey , StateCrypto } ;
3033use itp_sgx_externalities:: SgxExternalities ;
3134use itp_stf_state_handler:: handle_state:: HandleState ;
3235use itp_top_pool_author:: traits:: { AuthorApi , OnBlockImported } ;
33- use itp_types:: H256 ;
34- use its_consensus_common:: Error as ConsensusError ;
36+ use itp_types:: { ShardIdentifier , H256 } ;
37+ use its_consensus_common:: {
38+ block_production_suspension:: {
39+ BlockProductionSuspender , SuspendBlockProductionTrait , GLOBAL_BLOCK_SUSPENDER ,
40+ } ,
41+ Error as ConsensusError ,
42+ } ;
3543use its_primitives:: traits:: {
3644 BlockData , Header as HeaderTrait , ShardIdentifierFor , SignedBlock as SignedBlockTrait ,
3745} ;
@@ -193,6 +201,7 @@ impl<
193201 type SidechainState = SgxExternalities ;
194202 type StateCrypto = <StateKeyRepository as AccessKey >:: KeyType ;
195203 type Context = OCallApi ;
204+ type BlockSuspender = BlockProductionSuspender ;
196205
197206 fn verifier (
198207 & self ,
@@ -236,9 +245,40 @@ impl<
236245 where
237246 F : FnOnce ( & Self :: SidechainState ) -> Result < SignedSidechainBlock , ConsensusError > ,
238247 {
239- self . state_handler
248+ let sidechain_block = self
249+ . state_handler
240250 . execute_on_current ( shard, |state, _| verifying_function ( state) )
241- . map_err ( |e| ConsensusError :: Other ( format ! ( "{:?}" , e) . into ( ) ) ) ?
251+ . map_err ( |e| ConsensusError :: Other ( format ! ( "{:?}" , e) . into ( ) ) ) ??;
252+ let block_number = sidechain_block. block ( ) . header ( ) . block_number ( ) ;
253+ // get schedule block_number and mr_enclave
254+ let scheduled_enclaves = GLOBAL_SIDECHAIN_SCHEDULED_ENCLABES
255+ . get ( )
256+ . map_err ( |_| ConsensusError :: GetScheduledEnclavesFailed ) ?;
257+ if let Some ( scheduled_enclave) = scheduled_enclaves. get_next_scheduled_enclave ( block_number)
258+ {
259+ let block_suspender = self . block_suspender ( ) ;
260+ let scheduled_mr_enclave = scheduled_enclave. mr_enclave ;
261+ let scheduled_block_number = scheduled_enclave. sidechain_block_number ;
262+ let current_mr_enclave = block_suspender
263+ . current_mr_enclave ( )
264+ . map_err ( |_| ConsensusError :: GetMrEnclaveFailed ) ?;
265+ if current_mr_enclave != scheduled_mr_enclave {
266+ if scheduled_block_number <= block_number {
267+ block_suspender
268+ . suspend_for_production ( )
269+ . map_err ( |_| ConsensusError :: SetBlockSuspenderFailed ) ?;
270+ warn ! ( "need to update, reason: enclave is outdated" ) ;
271+ }
272+ if scheduled_block_number == block_number {
273+ let old_id = ShardIdentifier :: from_slice ( & current_mr_enclave[ ..] ) ;
274+ let new_id = ShardIdentifier :: from_slice ( & scheduled_mr_enclave[ ..] ) ;
275+ self . state_handler
276+ . migrate_shard ( old_id, new_id)
277+ . map_err ( |_| ConsensusError :: MigrationFailed ) ?;
278+ }
279+ }
280+ }
281+ Ok ( sidechain_block)
242282 }
243283
244284 fn state_key ( & self ) -> Result < Self :: StateCrypto , ConsensusError > {
@@ -251,6 +291,10 @@ impl<
251291 & self . ocall_api
252292 }
253293
294+ fn block_suspender ( & self ) -> Self :: BlockSuspender {
295+ GLOBAL_BLOCK_SUSPENDER . clone ( )
296+ }
297+
254298 fn import_parentchain_block (
255299 & self ,
256300 sidechain_block : & SignedSidechainBlock :: Block ,
0 commit comments