diff --git a/app-libs/stf/src/stf_sgx.rs b/app-libs/stf/src/stf_sgx.rs index c3362241c4..5c56cc197e 100644 --- a/app-libs/stf/src/stf_sgx.rs +++ b/app-libs/stf/src/stf_sgx.rs @@ -38,7 +38,7 @@ use itp_stf_interface::{ }; use itp_stf_primitives::{error::StfError, traits::TrustedCallVerification}; use itp_storage::storage_value_key; -use itp_types::parentchain::{AccountId, ParentchainCall, ParentchainId}; +use itp_types::parentchain::{AccountId, Hash, ParentchainCall, ParentchainId}; use itp_utils::stringify::account_id_to_string; use log::*; use sp_runtime::traits::StaticLookup; @@ -280,7 +280,7 @@ impl ParentchainPalletInstancesInterface for Stf where State: SgxExternalitiesTrait, - Runtime: frame_system::Config
+ Runtime: frame_system::Config
+ pallet_parentchain::Config + pallet_parentchain::Config + pallet_parentchain::Config, @@ -431,6 +431,40 @@ where Ok(()) } + fn set_genesis_hash( + state: &mut State, + genesis_hash: Hash, + parentchain_id: ParentchainId, + ) -> Result<(), Self::Error> { + state.execute_with(|| match parentchain_id { + ParentchainId::Integritee => pallet_parentchain::Call::< + Runtime, + ParentchainInstanceIntegritee, + >::init_parentchain_genesis_hash { + genesis: genesis_hash, + } + .dispatch_bypass_filter(Runtime::RuntimeOrigin::root()) + .map_err(|e| Self::Error::Dispatch(format!("Init genesis hash error: {:?}", e.error))), + ParentchainId::TargetA => pallet_parentchain::Call::< + Runtime, + ParentchainInstanceTargetA, + >::init_parentchain_genesis_hash { + genesis: genesis_hash, + } + .dispatch_bypass_filter(Runtime::RuntimeOrigin::root()) + .map_err(|e| Self::Error::Dispatch(format!("Init genesis hash error: {:?}", e.error))), + ParentchainId::TargetB => pallet_parentchain::Call::< + Runtime, + ParentchainInstanceTargetB, + >::init_parentchain_genesis_hash { + genesis: genesis_hash, + } + .dispatch_bypass_filter(Runtime::RuntimeOrigin::root()) + .map_err(|e| Self::Error::Dispatch(format!("Init genesis hash error: {:?}", e.error))), + })?; + Ok(()) + } + fn get_shard_vault_ensure_single_parentchain( state: &mut State, ) -> Result, Self::Error> { diff --git a/core-primitives/stf-interface/src/parentchain_pallet.rs b/core-primitives/stf-interface/src/parentchain_pallet.rs index b73898f104..4cd7a224d8 100644 --- a/core-primitives/stf-interface/src/parentchain_pallet.rs +++ b/core-primitives/stf-interface/src/parentchain_pallet.rs @@ -15,7 +15,7 @@ */ -use itp_types::parentchain::{AccountId, ParentchainId}; +use itp_types::parentchain::{AccountId, Hash, ParentchainId}; /// Interface trait of the parentchain pallet. pub trait ParentchainPalletInstancesInterface { @@ -51,6 +51,12 @@ pub trait ParentchainPalletInstancesInterface { parentchain_id: ParentchainId, ) -> Result<(), Self::Error>; + fn set_genesis_hash( + state: &mut State, + genesis_hash: Hash, + parentchain_id: ParentchainId, + ) -> Result<(), Self::Error>; + fn get_shard_vault_ensure_single_parentchain( state: &mut State, ) -> Result, Self::Error>; diff --git a/core-primitives/types/src/parentchain.rs b/core-primitives/types/src/parentchain.rs index 6904903273..f8690e45ac 100644 --- a/core-primitives/types/src/parentchain.rs +++ b/core-primitives/types/src/parentchain.rs @@ -91,6 +91,7 @@ impl std::fmt::Display for ParentchainId { pub trait IdentifyParentchain { fn parentchain_id(&self) -> ParentchainId; + fn genesis_hash(&self) -> Option; } pub trait FilterEvents { diff --git a/core/parentchain/light-client/src/concurrent_access.rs b/core/parentchain/light-client/src/concurrent_access.rs index fda60d74b0..db925253f9 100644 --- a/core/parentchain/light-client/src/concurrent_access.rs +++ b/core/parentchain/light-client/src/concurrent_access.rs @@ -30,7 +30,7 @@ use crate::{ LightValidationState, Validator as ValidatorTrait, }; use finality_grandpa::BlockNumberOps; -use itp_types::parentchain::{IdentifyParentchain, ParentchainId}; +use itp_types::parentchain::{Hash, IdentifyParentchain, ParentchainId}; use sp_runtime::traits::{Block as ParentchainBlockTrait, NumberFor}; use std::{marker::PhantomData, sync::Arc}; @@ -80,12 +80,18 @@ impl } } -impl IdentifyParentchain - for ValidatorAccessor +impl< + Validator: IdentifyParentchain, + ParentchainBlock, + LightClientSeal: IdentifyParentchain + LightClientSealing, + > IdentifyParentchain for ValidatorAccessor { fn parentchain_id(&self) -> ParentchainId { (*self.seal).parentchain_id() } + fn genesis_hash(&self) -> Option { + self.light_validation.read().unwrap().genesis_hash() + } } impl ValidatorAccess diff --git a/core/parentchain/light-client/src/io.rs b/core/parentchain/light-client/src/io.rs index aa6e4b75aa..204daa50c6 100644 --- a/core/parentchain/light-client/src/io.rs +++ b/core/parentchain/light-client/src/io.rs @@ -27,7 +27,7 @@ use codec::{Decode, Encode}; use core::{fmt::Debug, marker::PhantomData}; use itp_ocall_api::EnclaveOnChainOCallApi; use itp_sgx_io::{seal, unseal}; -use itp_types::parentchain::{IdentifyParentchain, ParentchainId}; +use itp_types::parentchain::{Hash, IdentifyParentchain, ParentchainId}; use log::*; use sp_runtime::traits::{Block, Header}; use std::{ @@ -93,6 +93,9 @@ impl IdentifyParentchain for LightClientStateSeal { fn parentchain_id(&self) -> ParentchainId { self.parentchain_id } + fn genesis_hash(&self) -> Option { + None + } } impl LightClientSealing @@ -194,6 +197,9 @@ impl IdentifyParentchain for LightClientStateSealSync ParentchainId { self.seal.parentchain_id } + fn genesis_hash(&self) -> Option { + None + } } impl LightClientSealing diff --git a/core/parentchain/light-client/src/light_validation.rs b/core/parentchain/light-client/src/light_validation.rs index 37d41ba757..88a7349a74 100644 --- a/core/parentchain/light-client/src/light_validation.rs +++ b/core/parentchain/light-client/src/light_validation.rs @@ -25,11 +25,11 @@ use codec::Encode; use core::iter::Iterator; use itp_ocall_api::EnclaveOnChainOCallApi; use itp_storage::{Error as StorageError, StorageProof, StorageProofChecker}; -use itp_types::parentchain::{IdentifyParentchain, ParentchainId}; +use itp_types::parentchain::{Hash, IdentifyParentchain, ParentchainId}; use log::error; use sp_runtime::{ generic::SignedBlock, - traits::{Block as ParentchainBlockTrait, Header as HeaderTrait}, + traits::{Block as ParentchainBlockTrait, Block as BlockT, Header as HeaderTrait}, Justifications, OpaqueExtrinsic, }; use std::{boxed::Box, fmt, sync::Arc, vec::Vec}; @@ -42,12 +42,16 @@ pub struct LightValidation { finality: Arc + Sync + Send + 'static>>, } -impl IdentifyParentchain - for LightValidation +impl IdentifyParentchain for LightValidation +where + Block: BlockT + ParentchainBlockTrait, { fn parentchain_id(&self) -> ParentchainId { self.parentchain_id } + fn genesis_hash(&self) -> Option { + self.light_validation_state.genesis_hash().ok() + } } impl diff --git a/core/parentchain/light-client/src/mocks/validator_access_mock.rs b/core/parentchain/light-client/src/mocks/validator_access_mock.rs index 107008f98d..07c3804fc2 100644 --- a/core/parentchain/light-client/src/mocks/validator_access_mock.rs +++ b/core/parentchain/light-client/src/mocks/validator_access_mock.rs @@ -27,7 +27,7 @@ use crate::{ mocks::validator_mock::ValidatorMock, }; use itp_types::{ - parentchain::{IdentifyParentchain, ParentchainId}, + parentchain::{Hash, IdentifyParentchain, ParentchainId}, Block, }; @@ -63,4 +63,7 @@ impl IdentifyParentchain for ValidatorAccessMock { fn parentchain_id(&self) -> ParentchainId { ParentchainId::Integritee } + fn genesis_hash(&self) -> Option { + Some(Hash::default()) + } } diff --git a/enclave-runtime/src/shard_creation_info.rs b/enclave-runtime/src/shard_creation_info.rs index 4eef7be830..b79c0726a5 100644 --- a/enclave-runtime/src/shard_creation_info.rs +++ b/enclave-runtime/src/shard_creation_info.rs @@ -23,12 +23,17 @@ use crate::{ use codec::{Decode, Encode}; use itp_component_container::ComponentGetter; +use crate::utils::{ + get_validator_accessor_from_integritee_solo_or_parachain, + get_validator_accessor_from_target_a_solo_or_parachain, + get_validator_accessor_from_target_b_solo_or_parachain, +}; use itp_stf_interface::{ parentchain_pallet::ParentchainPalletInstancesInterface, ShardCreationInfo, ShardCreationQuery, }; use itp_stf_state_handler::{handle_state::HandleState, query_shard_state::QueryShardState}; use itp_types::{ - parentchain::{Header, ParentchainId}, + parentchain::{Hash, Header, IdentifyParentchain, ParentchainId}, ShardIdentifier, }; use itp_utils::write_slice_and_whitespace_pad; @@ -100,14 +105,29 @@ fn init_shard_creation_parentchain_header_internal( }; let (state_lock, mut state) = state_handler.load_for_mutation(&shard)?; + EnclaveStf::set_creation_block(&mut state, header, parentchain_id) .map_err(|e| Error::Stf(e.to_string()))?; + + let genesis_hash = get_genesis_hash(parentchain_id)?; + EnclaveStf::set_genesis_hash(&mut state, genesis_hash, parentchain_id) + .map_err(|e| Error::Stf(e.to_string()))?; + state_handler.write_after_mutation(state, state_lock, &shard)?; shard_config::init_shard_config(shard)?; Ok(()) } +fn get_genesis_hash(parentchain_id: ParentchainId) -> EnclaveResult { + let va = match parentchain_id { + ParentchainId::Integritee => get_validator_accessor_from_integritee_solo_or_parachain(), + ParentchainId::TargetA => get_validator_accessor_from_target_a_solo_or_parachain(), + ParentchainId::TargetB => get_validator_accessor_from_target_b_solo_or_parachain(), + }?; + va.genesis_hash() + .ok_or_else(|| Error::Other("genesis hash missing for parentchain".into())) +} /// reads the shard vault account id form state if it has been initialized previously pub(crate) fn get_shard_creation_info_internal( shard: ShardIdentifier, diff --git a/service/src/main_impl.rs b/service/src/main_impl.rs index 6d8f636571..d62474c664 100644 --- a/service/src/main_impl.rs +++ b/service/src/main_impl.rs @@ -778,12 +778,13 @@ where // TODO: #1451: Fix api-client type hacks let head = Header::decode(&mut api_head.encode().as_slice()) .expect("Can decode previously encoded header; qed"); - // we ignore failure - let _ = enclave.init_shard_creation_parentchain_header(shard, &parentchain_id, &head); let (parentchain_handler, last_synched_header) = init_parentchain(enclave, &node_api, tee_account_id, parentchain_id, shard); + // we ignore failure + let _ = enclave.init_shard_creation_parentchain_header(shard, &parentchain_id, &head); + if WorkerModeProvider::worker_mode() != WorkerMode::Teeracle { println!( "[{:?}] Finished initializing light client, syncing parentchain...",