diff --git a/Cargo.lock b/Cargo.lock index b36058e33f..dc374e1ff3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2875,6 +2875,7 @@ dependencies = [ "hex", "integritee-node-runtime", "ipfs-api", + "ita-parentchain-interface", "itc-parentchain", "itc-parentchain-test", "itc-rest-client", @@ -3010,6 +3011,7 @@ dependencies = [ "bs58", "env_logger", "frame-support", + "frame-system", "futures 0.3.28", "futures 0.3.8", "ita-sgx-runtime", @@ -3029,6 +3031,7 @@ dependencies = [ "itp-utils", "log 0.4.19", "parity-scale-codec", + "scale-info", "sgx_tstd", "sgx_types", "sp-core", @@ -3424,6 +3427,7 @@ version = "0.9.0" dependencies = [ "integritee-node-runtime", "itp-types", + "parity-scale-codec", "sp-core", "sp-runtime", "substrate-api-client", @@ -3536,6 +3540,7 @@ dependencies = [ "itp-node-api", "itp-nonce-cache", "itp-types", + "itp-utils", "log 0.4.19", "parity-scale-codec", "sgx_tstd", @@ -3586,6 +3591,7 @@ dependencies = [ name = "itp-node-api-factory" version = "0.9.0" dependencies = [ + "itp-api-client-extensions", "itp-api-client-types", "sp-core", "thiserror 1.0.40", diff --git a/app-libs/parentchain-interface/Cargo.toml b/app-libs/parentchain-interface/Cargo.toml index ac1042d018..7c658ed9f6 100644 --- a/app-libs/parentchain-interface/Cargo.toml +++ b/app-libs/parentchain-interface/Cargo.toml @@ -40,8 +40,10 @@ log = { version = "0.4", default-features = false } # substrate dep binary-merkle-tree = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } frame-support = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +frame-system = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } sp-core = { default-features = false, features = ["full_crypto"], git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +scale-info = { version = "2.0.1", default-features = false, features = ["derive"] } [dev-dependencies] env_logger = "0.9.0" @@ -75,9 +77,11 @@ std = [ "log/std", #substrate "binary-merkle-tree/std", + "scale-info/std", "sp-core/std", "sp-runtime/std", "frame-support/std", + "frame-system/std", "thiserror", ] sgx = [ diff --git a/app-libs/parentchain-interface/src/integritee/extrinsic_parser.rs b/app-libs/parentchain-interface/src/integritee/extrinsic_parser.rs index 925aca30ee..af205f6d13 100644 --- a/app-libs/parentchain-interface/src/integritee/extrinsic_parser.rs +++ b/app-libs/parentchain-interface/src/integritee/extrinsic_parser.rs @@ -14,12 +14,141 @@ limitations under the License. */ - use codec::{Decode, Encode}; use core::marker::PhantomData; +use itp_api_client_types::traits::ExtrinsicParamsAdjustments; use itp_node_api::api_client::{ - Address, CallIndex, PairSignature, ParentchainSignedExtra, Signature, UncheckedExtrinsicV4, + Address, CallIndex, DefaultRuntimeConfig, ExtrinsicParams, GenericAdditionalSigned, + GenericExtrinsicParams, PairSignature, Signature, UncheckedExtrinsicV4, }; +use itp_types::parentchain::{Balance, Hash, Index}; +use sp_runtime::generic::Era; + +// re-export integritee network types +pub use itp_node_api::api_client::{ParentchainTip, Signature as ParentchainSignature}; + +#[derive(Decode, Encode, Clone, Eq, PartialEq, Debug)] +pub struct ParentchainExtrinsicParams { + era: Era, + nonce: Index, + tip: ParentchainTip, + spec_version: u32, + transaction_version: u32, + genesis_hash: Hash, + mortality_checkpoint: Hash, +} + +#[derive(Decode, Encode, Copy, Clone, Eq, PartialEq, Debug)] +pub struct ParentchainAdditionalParams { + era: Era, + mortality_checkpoint: Option, + tip: ParentchainTip, +} +impl Default for ParentchainAdditionalParams { + fn default() -> Self { + Self { era: Era::Immortal, mortality_checkpoint: None, tip: ParentchainTip::default() } + } +} + +#[derive(Decode, Encode, Copy, Clone, Eq, PartialEq, Debug)] +pub struct ParentchainSignedExtra { + pub era: Era, + #[codec(compact)] + pub nonce: Index, + pub tip: ParentchainTip, +} + +pub type ParentchainAdditionalSigned = ((), u32, u32, Hash, Hash, (), (), ()); + +impl ExtrinsicParams for ParentchainExtrinsicParams { + type AdditionalParams = ParentchainAdditionalParams; + type SignedExtra = ParentchainSignedExtra; + type AdditionalSigned = ParentchainAdditionalSigned; + + fn new( + spec_version: u32, + transaction_version: u32, + nonce: Index, + genesis_hash: Hash, + additional_params: Self::AdditionalParams, + ) -> Self { + Self { + era: additional_params.era, + tip: additional_params.tip, + spec_version, + transaction_version, + genesis_hash, + mortality_checkpoint: additional_params.mortality_checkpoint.unwrap_or(genesis_hash), + nonce, + } + } + + fn signed_extra(&self) -> Self::SignedExtra { + Self::SignedExtra { era: self.era, nonce: self.nonce, tip: self.tip } + } + + fn additional_signed(&self) -> Self::AdditionalSigned { + ( + (), + self.spec_version, + self.transaction_version, + self.genesis_hash, + self.mortality_checkpoint, + (), + (), + (), + ) + } +} + +impl ExtrinsicParamsAdjustments for ParentchainExtrinsicParams { + fn with_nonce(&self, nonce: Index) -> Self { + Self { + era: self.era, + tip: self.tip, + spec_version: self.spec_version, + transaction_version: self.transaction_version, + genesis_hash: self.genesis_hash, + mortality_checkpoint: self.mortality_checkpoint, + nonce, + } + } + fn with_additional_params(&self, additional_params: ParentchainAdditionalParams) -> Self { + Self { + era: additional_params.era, + tip: additional_params.tip, + spec_version: self.spec_version, + transaction_version: self.transaction_version, + genesis_hash: self.genesis_hash, + mortality_checkpoint: additional_params + .mortality_checkpoint + .unwrap_or(self.genesis_hash), + nonce: self.nonce, + } + } + fn with_spec_version(&self, spec_version: u32) -> Self { + Self { + era: self.era, + tip: self.tip, + spec_version, + transaction_version: self.transaction_version, + genesis_hash: self.genesis_hash, + mortality_checkpoint: self.mortality_checkpoint, + nonce: self.nonce, + } + } + fn with_transaction_version(&self, transaction_version: u32) -> Self { + Self { + era: self.era, + tip: self.tip, + spec_version: self.spec_version, + transaction_version, + genesis_hash: self.genesis_hash, + mortality_checkpoint: self.mortality_checkpoint, + nonce: self.nonce, + } + } +} pub struct ExtrinsicParser { _phantom: PhantomData, diff --git a/app-libs/parentchain-interface/src/integritee/mod.rs b/app-libs/parentchain-interface/src/integritee/mod.rs index c7dfe7a4b2..e8580c9e5b 100644 --- a/app-libs/parentchain-interface/src/integritee/mod.rs +++ b/app-libs/parentchain-interface/src/integritee/mod.rs @@ -27,7 +27,10 @@ use codec::{Decode, Encode}; use core::marker::PhantomData; pub use event_filter::FilterableEvents; pub use event_handler::ParentchainEventHandler; -pub use extrinsic_parser::ParentchainExtrinsicParser; +pub use extrinsic_parser::{ + ParentchainAdditionalParams, ParentchainAdditionalSigned, ParentchainExtrinsicParams, + ParentchainExtrinsicParser, ParentchainSignedExtra, +}; use ita_stf::TrustedCallSigned; use itc_parentchain_indirect_calls_executor::{ error::{Error, Result}, diff --git a/app-libs/parentchain-interface/src/target_a/extrinsic_parser.rs b/app-libs/parentchain-interface/src/target_a/extrinsic_parser.rs index 925aca30ee..eeda3a1d21 100644 --- a/app-libs/parentchain-interface/src/target_a/extrinsic_parser.rs +++ b/app-libs/parentchain-interface/src/target_a/extrinsic_parser.rs @@ -17,10 +17,153 @@ use codec::{Decode, Encode}; use core::marker::PhantomData; +use frame_support::{ + pallet_prelude::TypeInfo, + traits::{CrateVersion, PalletInfo}, + weights::constants::RocksDbWeight, + RuntimeDebug, +}; +use ita_sgx_runtime::{BlockHashCount, RuntimeCall, RuntimeEvent, RuntimeOrigin, Version}; use itp_node_api::api_client::{ - Address, CallIndex, PairSignature, ParentchainSignedExtra, Signature, UncheckedExtrinsicV4, + traits::ExtrinsicParamsAdjustments, Address, AssetTip, CallIndex, ExtrinsicParams, + GenericExtrinsicParams, PairSignature, Signature, UncheckedExtrinsicV4, +}; +use sp_runtime::{ + generic::Era, + traits::{AccountIdLookup, BlakeTwo256}, }; +use itp_types::parentchain::{AccountId, Balance, BlockNumber, Hash, Header, Index}; + +// re-export integritee network types +pub use itp_node_api::api_client::Signature as ParentchainSignature; + +// define custom properties for Asset Hub +pub type ParentchainTip = AssetTip; + +#[derive(Decode, Encode, Clone, Eq, PartialEq, Debug)] +pub struct ParentchainExtrinsicParams { + era: Era, + nonce: Index, + tip: ParentchainTip, + spec_version: u32, + transaction_version: u32, + genesis_hash: Hash, + mortality_checkpoint: Hash, +} + +#[derive(Decode, Encode, Copy, Clone, Eq, PartialEq, Debug)] +pub struct ParentchainAdditionalParams { + era: Era, + mortality_checkpoint: Option, + tip: ParentchainTip, +} +impl Default for ParentchainAdditionalParams { + fn default() -> Self { + Self { era: Era::Immortal, mortality_checkpoint: None, tip: ParentchainTip::default() } + } +} + +#[derive(Decode, Encode, Copy, Clone, Eq, PartialEq, Debug)] +pub struct ParentchainSignedExtra { + pub era: Era, + #[codec(compact)] + pub nonce: Index, + pub tip: ParentchainTip, +} + +pub type ParentchainAdditionalSigned = ((), u32, u32, Hash, Hash, (), (), ()); + +impl ExtrinsicParams for ParentchainExtrinsicParams { + type AdditionalParams = ParentchainAdditionalParams; + type SignedExtra = ParentchainSignedExtra; + type AdditionalSigned = ParentchainAdditionalSigned; + + fn new( + spec_version: u32, + transaction_version: u32, + nonce: Index, + genesis_hash: Hash, + additional_params: Self::AdditionalParams, + ) -> Self { + Self { + era: additional_params.era, + tip: additional_params.tip, + spec_version, + transaction_version, + genesis_hash, + mortality_checkpoint: additional_params.mortality_checkpoint.unwrap_or(genesis_hash), + nonce, + } + } + + fn signed_extra(&self) -> Self::SignedExtra { + Self::SignedExtra { era: self.era, nonce: self.nonce, tip: self.tip } + } + + fn additional_signed(&self) -> Self::AdditionalSigned { + ( + (), + self.spec_version, + self.transaction_version, + self.genesis_hash, + self.mortality_checkpoint, + (), + (), + (), + ) + } +} + +impl ExtrinsicParamsAdjustments for ParentchainExtrinsicParams { + fn with_nonce(&self, nonce: Index) -> Self { + Self { + era: self.era, + tip: self.tip, + spec_version: self.spec_version, + transaction_version: self.transaction_version, + genesis_hash: self.genesis_hash, + mortality_checkpoint: self.mortality_checkpoint, + nonce, + } + } + fn with_additional_params(&self, additional_params: ParentchainAdditionalParams) -> Self { + Self { + era: additional_params.era, + tip: additional_params.tip, + spec_version: self.spec_version, + transaction_version: self.transaction_version, + genesis_hash: self.genesis_hash, + mortality_checkpoint: additional_params + .mortality_checkpoint + .unwrap_or(self.genesis_hash), + nonce: self.nonce, + } + } + fn with_spec_version(&self, spec_version: u32) -> Self { + Self { + era: self.era, + tip: self.tip, + spec_version, + transaction_version: self.transaction_version, + genesis_hash: self.genesis_hash, + mortality_checkpoint: self.mortality_checkpoint, + nonce: self.nonce, + } + } + fn with_transaction_version(&self, transaction_version: u32) -> Self { + Self { + era: self.era, + tip: self.tip, + spec_version: self.spec_version, + transaction_version, + genesis_hash: self.genesis_hash, + mortality_checkpoint: self.mortality_checkpoint, + nonce: self.nonce, + } + } +} + pub struct ExtrinsicParser { _phantom: PhantomData, } diff --git a/app-libs/parentchain-interface/src/target_a/mod.rs b/app-libs/parentchain-interface/src/target_a/mod.rs index e26d2e45c0..991eb94893 100644 --- a/app-libs/parentchain-interface/src/target_a/mod.rs +++ b/app-libs/parentchain-interface/src/target_a/mod.rs @@ -27,8 +27,11 @@ use codec::{Decode, Encode}; use core::marker::PhantomData; pub use event_filter::FilterableEvents; pub use event_handler::ParentchainEventHandler; -pub use extrinsic_parser::ParentchainExtrinsicParser; use extrinsic_parser::ParseExtrinsic; +pub use extrinsic_parser::{ + ParentchainAdditionalParams, ParentchainAdditionalSigned, ParentchainExtrinsicParams, + ParentchainExtrinsicParser, ParentchainSignedExtra, +}; use ita_stf::TrustedCallSigned; use itc_parentchain_indirect_calls_executor::{ error::{Error, Result}, diff --git a/app-libs/parentchain-interface/src/target_b/extrinsic_parser.rs b/app-libs/parentchain-interface/src/target_b/extrinsic_parser.rs index 925aca30ee..d9de195a7b 100644 --- a/app-libs/parentchain-interface/src/target_b/extrinsic_parser.rs +++ b/app-libs/parentchain-interface/src/target_b/extrinsic_parser.rs @@ -18,7 +18,15 @@ use codec::{Decode, Encode}; use core::marker::PhantomData; use itp_node_api::api_client::{ - Address, CallIndex, PairSignature, ParentchainSignedExtra, Signature, UncheckedExtrinsicV4, + Address, CallIndex, PairSignature, PlainTip, Signature, UncheckedExtrinsicV4, +}; + +use itp_types::parentchain::{Balance, Hash}; + +// re-export integritee network types +pub use itp_node_api::api_client::{ + ParentchainAdditionalParams, ParentchainAdditionalSigned, ParentchainExtrinsicParams, + ParentchainSignedExtra, ParentchainTip, Signature as ParentchainSignature, }; pub struct ExtrinsicParser { diff --git a/app-libs/parentchain-interface/src/target_b/mod.rs b/app-libs/parentchain-interface/src/target_b/mod.rs index 265de1d119..dcf6bec04f 100644 --- a/app-libs/parentchain-interface/src/target_b/mod.rs +++ b/app-libs/parentchain-interface/src/target_b/mod.rs @@ -39,8 +39,11 @@ use codec::{Decode, Encode}; use core::marker::PhantomData; pub use event_filter::FilterableEvents; pub use event_handler::ParentchainEventHandler; -pub use extrinsic_parser::ParentchainExtrinsicParser; use extrinsic_parser::ParseExtrinsic; +pub use extrinsic_parser::{ + ParentchainAdditionalParams, ParentchainAdditionalSigned, ParentchainExtrinsicParams, + ParentchainExtrinsicParser, ParentchainSignedExtra, +}; use ita_stf::TrustedCallSigned; use itc_parentchain_indirect_calls_executor::{ error::{Error, Result}, diff --git a/core-primitives/extrinsics-factory/Cargo.toml b/core-primitives/extrinsics-factory/Cargo.toml index ec58f75dff..10d24eb572 100644 --- a/core-primitives/extrinsics-factory/Cargo.toml +++ b/core-primitives/extrinsics-factory/Cargo.toml @@ -14,6 +14,7 @@ substrate-api-client = { default-features = false, features = ["sync-api"], git itp-node-api = { path = "../node-api", default-features = false } itp-nonce-cache = { path = "../nonce-cache", default-features = false } itp-types = { path = "../types", default-features = false } +itp-utils = { path = "../utils", default-features = false } # sgx enabled external libraries thiserror_sgx = { package = "thiserror", git = "https://github.com/mesalock-linux/thiserror-sgx", tag = "sgx_1.1.3", optional = true } @@ -33,6 +34,7 @@ std = [ "itp-node-api/std", "itp-nonce-cache/std", "itp-types/std", + "itp-utils/std", "log/std", "substrate-api-client/std", "thiserror", diff --git a/core-primitives/extrinsics-factory/src/lib.rs b/core-primitives/extrinsics-factory/src/lib.rs index 0744d1b657..7cddcb5bf2 100644 --- a/core-primitives/extrinsics-factory/src/lib.rs +++ b/core-primitives/extrinsics-factory/src/lib.rs @@ -30,15 +30,22 @@ pub mod sgx_reexport_prelude { } use codec::Encode; +use core::fmt::Debug; use error::Result; use itp_node_api::{ api_client::{ - ExtrinsicParams, ParentchainAdditionalParams, ParentchainExtrinsicParams, SignExtrinsic, + traits::ExtrinsicParamsAdjustments, ExtrinsicParams, ParentchainAdditionalParams, + ParentchainExtrinsicParams, SignExtrinsic, }, metadata::{provider::AccessNodeMetadata, NodeMetadata}, }; use itp_nonce_cache::{MutateNonce, Nonce}; -use itp_types::{parentchain::AccountId, OpaqueCall}; +use itp_types::{ + parentchain::{AccountId, Hash, Index}, + OpaqueCall, +}; +use itp_utils::hex::hex_encode; +use log::trace; use sp_core::H256; use sp_runtime::{generic::Era, OpaqueExtrinsic}; use std::{sync::Arc, vec::Vec}; @@ -53,87 +60,151 @@ pub mod mock; /// /// Also increases the nonce counter for each extrinsic that is created. pub trait CreateExtrinsics { - fn create_extrinsics( - &self, - calls: &[OpaqueCall], - extrinsics_params: Option, - ) -> Result>; + fn create_extrinsics(&self, calls: &[OpaqueCall]) -> Result>; } /// Extrinsics factory -pub struct ExtrinsicsFactory -where +pub struct ExtrinsicsFactory< + Signer, + NonceCache, + NodeMetadataRepository, + MyExtrinsicParams, + MyAdditionalParams, + MySignedExtra, + MyAdditionalSigned, +> where Signer: SignExtrinsic, NonceCache: MutateNonce, NodeMetadataRepository: AccessNodeMetadata, + MyExtrinsicParams: ExtrinsicParams< + Index, + Hash, + AdditionalParams = MyAdditionalParams, + SignedExtra = MySignedExtra, + AdditionalSigned = MyAdditionalSigned, + >, { genesis_hash: H256, signer: Signer, + extrinsic_params: MyExtrinsicParams, nonce_cache: Arc, node_metadata_repository: Arc, } -impl - ExtrinsicsFactory -where +impl< + Signer, + NonceCache, + NodeMetadataRepository, + MyExtrinsicParams, + MyAdditionalParams, + MySignedExtra, + MyAdditionalSigned, + > + ExtrinsicsFactory< + Signer, + NonceCache, + NodeMetadataRepository, + MyExtrinsicParams, + MyAdditionalParams, + MySignedExtra, + MyAdditionalSigned, + > where Signer: SignExtrinsic, NonceCache: MutateNonce, NodeMetadataRepository: AccessNodeMetadata, + MyExtrinsicParams: Clone + + ExtrinsicParams< + Index, + Hash, + AdditionalParams = MyAdditionalParams, + SignedExtra = MySignedExtra, + AdditionalSigned = MyAdditionalSigned, + >, + MySignedExtra: Encode, + MyAdditionalSigned: Encode, { pub fn new( genesis_hash: H256, signer: Signer, + extrinsic_params: MyExtrinsicParams, nonce_cache: Arc, node_metadata_repository: Arc, ) -> Self { - ExtrinsicsFactory { genesis_hash, signer, nonce_cache, node_metadata_repository } + ExtrinsicsFactory { + genesis_hash, + signer, + extrinsic_params, + nonce_cache, + node_metadata_repository, + } } pub fn with_signer(&self, signer: Signer, nonce_cache: Arc) -> Self { ExtrinsicsFactory { genesis_hash: self.genesis_hash, signer, + extrinsic_params: self.extrinsic_params.clone(), nonce_cache, node_metadata_repository: self.node_metadata_repository.clone(), } } } -impl CreateExtrinsics - for ExtrinsicsFactory -where +impl< + Signer, + NonceCache, + NodeMetadataRepository, + MyExtrinsicParams, + MyAdditionalParams, + MySignedExtra, + MyAdditionalSigned, + > CreateExtrinsics + for ExtrinsicsFactory< + Signer, + NonceCache, + NodeMetadataRepository, + MyExtrinsicParams, + MyAdditionalParams, + MySignedExtra, + MyAdditionalSigned, + > where Signer: SignExtrinsic, NonceCache: MutateNonce, NodeMetadataRepository: AccessNodeMetadata, + MyExtrinsicParams: Clone + + Debug + + ExtrinsicParamsAdjustments + + ExtrinsicParams< + Index, + Hash, + AdditionalParams = MyAdditionalParams, + SignedExtra = MySignedExtra, + AdditionalSigned = MyAdditionalSigned, + >, + MySignedExtra: Encode + Copy, + MyAdditionalSigned: Encode + Copy, { - fn create_extrinsics( - &self, - calls: &[OpaqueCall], - extrinsics_params: Option, - ) -> Result> { + fn create_extrinsics(&self, calls: &[OpaqueCall]) -> Result> { let mut nonce_lock = self.nonce_cache.load_for_mutation()?; let mut nonce_value = nonce_lock.0; - let additional_extrinsic_params = extrinsics_params.unwrap_or_else(|| { - ParentchainAdditionalParams::new().era(Era::Immortal, self.genesis_hash).tip(0) - }); - let (runtime_spec_version, runtime_transaction_version) = self.node_metadata_repository.get_from_metadata(|m| { (m.get_runtime_version(), m.get_runtime_transaction_version()) })?; + let mut xt_params = self + .extrinsic_params + .with_spec_version(runtime_spec_version) + .with_transaction_version(runtime_transaction_version); + let extrinsics_buffer: Vec = calls .iter() .map(|call| { - let extrinsic_params = ParentchainExtrinsicParams::new( - runtime_spec_version, - runtime_transaction_version, - nonce_value, - self.genesis_hash, - additional_extrinsic_params, - ); - let xt = compose_extrinsic_offline!(&self.signer, call, extrinsic_params).encode(); + xt_params = xt_params.with_nonce(nonce_value); + trace!("create_extrinsic: encoded call: {} ", hex_encode(&call.encode())); + trace!(" extrinsic params: {:?}", xt_params); + let xt = compose_extrinsic_offline!(&self.signer, call, xt_params.clone()).encode(); nonce_value += 1; xt }) @@ -173,7 +244,7 @@ pub mod tests { ); let opaque_calls = [OpaqueCall(vec![3u8; 42]), OpaqueCall(vec![12u8, 78])]; - let xts = extrinsics_factory.create_extrinsics(&opaque_calls, None).unwrap(); + let xts = extrinsics_factory.create_extrinsics(&opaque_calls).unwrap(); assert_eq!(opaque_calls.len(), xts.len()); assert_eq!(nonce_cache.get_nonce().unwrap(), Nonce(opaque_calls.len() as NonceValue)); @@ -199,7 +270,7 @@ pub mod tests { ); let opaque_calls = [OpaqueCall(vec![3u8; 42]), OpaqueCall(vec![12u8, 78])]; - let xts = extrinsics_factory.create_extrinsics(&opaque_calls, None).unwrap(); + let xts = extrinsics_factory.create_extrinsics(&opaque_calls).unwrap(); assert_eq!(opaque_calls.len(), xts.len()); assert_eq!(nonce_cache2.get_nonce().unwrap(), Nonce(opaque_calls.len() as NonceValue)); diff --git a/core-primitives/extrinsics-factory/src/mock.rs b/core-primitives/extrinsics-factory/src/mock.rs index 4e1923210e..2d9364ec8f 100644 --- a/core-primitives/extrinsics-factory/src/mock.rs +++ b/core-primitives/extrinsics-factory/src/mock.rs @@ -28,11 +28,7 @@ use std::vec::Vec; pub struct ExtrinsicsFactoryMock; impl CreateExtrinsics for ExtrinsicsFactoryMock { - fn create_extrinsics( - &self, - _calls: &[OpaqueCall], - _additional_params: Option, - ) -> Result> { + fn create_extrinsics(&self, _calls: &[OpaqueCall]) -> Result> { // Intention was to map an OpaqueCall to some dummy OpaqueExtrinsic, // so the output vector has the same size as the input one (and thus can be tested from the outside). // However, it doesn't seem to be possible to construct an empty of dummy OpaqueExtrinsic, diff --git a/core-primitives/node-api/api-client-extensions/src/account.rs b/core-primitives/node-api/api-client-extensions/src/account.rs index d2becda266..927e826dd0 100644 --- a/core-primitives/node-api/api-client-extensions/src/account.rs +++ b/core-primitives/node-api/api-client-extensions/src/account.rs @@ -17,8 +17,9 @@ use crate::ApiResult; use itp_api_client_types::{ - traits::GetAccountInformation, Api, Config, ParentchainRuntimeConfig, Request, + traits::GetAccountInformation, Api, Config, ParentchainPlainTipRuntimeConfig, Request, }; +use itp_types::parentchain::{AccountData, Balance}; /// ApiClient extension that contains some convenience methods around accounts. // Todo: make generic over `Config` type instead? @@ -31,13 +32,17 @@ pub trait AccountApi { fn get_free_balance(&self, who: &Self::AccountId) -> ApiResult; } -impl AccountApi for Api +impl AccountApi for Api where Client: Request, + RuntimeConfig: Config< + AccountData = substrate_api_client::ac_primitives::AccountData, + Balance = Balance, + >, { - type AccountId = ::AccountId; - type Index = ::Index; - type Balance = ::Balance; + type AccountId = ::AccountId; + type Index = ::Index; + type Balance = ::Balance; fn get_nonce_of(&self, who: &Self::AccountId) -> ApiResult { Ok(self.get_account_info(who)?.map(|info| info.nonce).unwrap_or_default()) diff --git a/core-primitives/node-api/api-client-extensions/src/chain.rs b/core-primitives/node-api/api-client-extensions/src/chain.rs index 89321b0034..1d9181717d 100644 --- a/core-primitives/node-api/api-client-extensions/src/chain.rs +++ b/core-primitives/node-api/api-client-extensions/src/chain.rs @@ -16,14 +16,17 @@ */ use crate::{ApiClientError, ApiResult}; +use codec::Encode; use itp_api_client_types::{ storage_key, traits::{GetChainInfo, GetStorage}, - Api, Config, Request, StorageKey, + Api, Config, ExtrinsicParams, Request, StorageKey, }; use itp_types::parentchain::{BlockNumber, StorageProof}; use sp_consensus_grandpa::{AuthorityList, VersionedAuthorityList, GRANDPA_AUTHORITIES_KEY}; use sp_runtime::generic::SignedBlock as GenericSignedBlock; +use std::ops::Deref; +use substrate_api_client::ac_primitives::UncheckedExtrinsicV4; type RawEvents = Vec; @@ -33,6 +36,10 @@ pub trait ChainApi { type Block; type Header; type BlockNumber; + type Signer; + type Address; + type Signature; + type SignedExtra; fn last_finalized_block(&self) -> ApiResult>>; fn signed_block( @@ -54,17 +61,27 @@ pub trait ChainApi { fn grandpa_authorities_proof(&self, hash: Option) -> ApiResult; fn get_events_value_proof(&self, block_hash: Option) -> ApiResult; fn get_events_for_block(&self, block_hash: Option) -> ApiResult; + fn set_signer(&mut self, signer: Self::Signer) -> ApiResult<()>; + //get_storage_proof_by_keys + //fn get_opaque_storage_by_key(&mut self, signer: Self::Signer) -> ApiResult<()>; + //fn submit_and_watch_opaque_extrinsic_until(&mut self, signer: Self::Signer) -> ApiResult<()>; + //fn submit_opaque_extrinsic(&mut self, signer: Self::Signer) -> ApiResult<()>; } impl ChainApi for Api where - RuntimeConfig: Config, + RuntimeConfig: Config + + ExtrinsicParams<::Index, ::Hash>, Client: Request, { type Hash = RuntimeConfig::Hash; - type Header = RuntimeConfig::Header; type Block = RuntimeConfig::Block; + type Header = RuntimeConfig::Header; type BlockNumber = RuntimeConfig::BlockNumber; + type Signer = RuntimeConfig::ExtrinsicSigner; + type Address = RuntimeConfig::Address; + type Signature = RuntimeConfig::Signature; + type SignedExtra = RuntimeConfig::SignedExtra; fn last_finalized_block(&self) -> ApiResult>> { self.get_finalized_head()? @@ -139,4 +156,9 @@ where let key = storage_key("System", "Events"); Ok(self.get_opaque_storage_by_key(key, block_hash)?.unwrap_or_default()) } + + fn set_signer(&mut self, signer: Self::Signer) -> ApiResult<()> { + self.set_signer(signer); + Ok(()) + } } diff --git a/core-primitives/node-api/api-client-types/Cargo.toml b/core-primitives/node-api/api-client-types/Cargo.toml index 29e9615751..3370e3e4d2 100644 --- a/core-primitives/node-api/api-client-types/Cargo.toml +++ b/core-primitives/node-api/api-client-types/Cargo.toml @@ -5,6 +5,8 @@ authors = ["Integritee AG "] edition = "2021" [dependencies] +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } + # integritee-node my-node-runtime = { package = "integritee-node-runtime", optional = true, git = "https://github.com/integritee-network/integritee-node.git", branch = "sdk-v0.12.0-polkadot-v0.9.42" } @@ -22,6 +24,7 @@ itp-types = { default-features = false, path = "../../types" } [features] default = ["std"] std = [ + "codec/std", "itp-types/std", "substrate-api-client/std", "substrate-api-client/tungstenite-client", diff --git a/core-primitives/node-api/api-client-types/src/lib.rs b/core-primitives/node-api/api-client-types/src/lib.rs index f3bee4590d..85e368c1a2 100644 --- a/core-primitives/node-api/api-client-types/src/lib.rs +++ b/core-primitives/node-api/api-client-types/src/lib.rs @@ -22,6 +22,7 @@ #![cfg_attr(not(feature = "std"), no_std)] +use codec::{Decode, Encode}; pub use itp_types::parentchain::{ AccountData, AccountId, AccountInfo, Address, Balance, Hash, Index, Signature as PairSignature, }; @@ -45,40 +46,170 @@ pub use substrate_api_client::{ // traits from the api-client pub mod traits { + use itp_types::parentchain::Index; pub use substrate_api_client::{GetAccountInformation, GetChainInfo, GetStorage}; -} -pub type ParentchainPlainTip = PlainTip; -pub type ParentchainAssetTip = AssetTip; + pub trait ExtrinsicParamsAdjustments { + fn with_nonce(&self, nonce: Index) -> Self; + fn with_additional_params(&self, additional_params: AdditionalParams) -> Self; + fn with_spec_version(&self, version: u32) -> Self; + fn with_transaction_version(&self, version: u32) -> Self; + } +} /// Configuration for the ExtrinsicParams. /// /// Valid for the default integritee node -pub type ParentchainExtrinsicParams = - GenericExtrinsicParams; -pub type ParentchainAdditionalParams = GenericAdditionalParams; -pub use DefaultRuntimeConfig as ParentchainRuntimeConfig; +#[derive(Decode, Encode, Clone, Eq, PartialEq, Debug)] +pub struct ParentchainExtrinsicParams { + era: Era, + nonce: Index, + tip: ParentchainTip, + spec_version: u32, + transaction_version: u32, + genesis_hash: Hash, + mortality_checkpoint: Hash, +} + +pub type ParentchainAdditionalSigned = GenericAdditionalSigned; + +pub type ParentchainTip = PlainTip; +// in case integritee would use the `pallet_asset_tx_payment`. +//pub type ParentchainTip = AssetTip + +impl ExtrinsicParams for ParentchainExtrinsicParams { + type AdditionalParams = ParentchainAdditionalParams; + type SignedExtra = ParentchainSignedExtra; + type AdditionalSigned = ParentchainAdditionalSigned; + + fn new( + spec_version: u32, + transaction_version: u32, + nonce: Index, + genesis_hash: Hash, + additional_params: Self::AdditionalParams, + ) -> Self { + Self { + era: additional_params.era, + tip: additional_params.tip, + spec_version, + transaction_version, + genesis_hash, + mortality_checkpoint: additional_params.mortality_checkpoint.unwrap_or(genesis_hash), + nonce, + } + } + + fn signed_extra(&self) -> Self::SignedExtra { + Self::SignedExtra { era: self.era, nonce: self.nonce, tip: self.tip } + } + + fn additional_signed(&self) -> Self::AdditionalSigned { + ( + (), + self.spec_version, + self.transaction_version, + self.genesis_hash, + self.mortality_checkpoint, + (), + (), + (), + ) + } +} + +impl ExtrinsicParamsAdjustments for ParentchainExtrinsicParams { + fn with_nonce(&self, nonce: Index) -> Self { + Self { + era: self.era, + tip: self.tip, + spec_version: self.spec_version, + transaction_version: self.transaction_version, + genesis_hash: self.genesis_hash, + mortality_checkpoint: self.mortality_checkpoint, + nonce, + } + } + fn with_additional_params(&self, additional_params: ParentchainAdditionalParams) -> Self { + Self { + era: additional_params.era, + tip: additional_params.tip, + spec_version: self.spec_version, + transaction_version: self.transaction_version, + genesis_hash: self.genesis_hash, + mortality_checkpoint: additional_params + .mortality_checkpoint + .unwrap_or(self.genesis_hash), + nonce: self.nonce, + } + } + fn with_spec_version(&self, spec_version: u32) -> Self { + Self { + era: self.era, + tip: self.tip, + spec_version, + transaction_version: self.transaction_version, + genesis_hash: self.genesis_hash, + mortality_checkpoint: self.mortality_checkpoint, + nonce: self.nonce, + } + } + fn with_transaction_version(&self, transaction_version: u32) -> Self { + Self { + era: self.era, + tip: self.tip, + spec_version: self.spec_version, + transaction_version, + genesis_hash: self.genesis_hash, + mortality_checkpoint: self.mortality_checkpoint, + nonce: self.nonce, + } + } +} + +#[derive(Decode, Encode, Copy, Clone, Eq, PartialEq, Debug)] +pub struct ParentchainAdditionalParams { + era: Era, + mortality_checkpoint: Option, + tip: ParentchainTip, +} + +impl Default for ParentchainAdditionalParams { + fn default() -> Self { + Self { era: Era::Immortal, mortality_checkpoint: None, tip: ParentchainTip::default() } + } +} +use sp_runtime::generic::Era; +use substrate_api_client::ac_primitives::WithExtrinsicParams; + +/// Standard runtime config for Substrate and Polkadot nodes. +pub type ParentchainPlainTipRuntimeConfig = + WithExtrinsicParams>; + +/// runtime config for chains like Asset Hub or Encointer +pub type ParentchainAssetTipRuntimeConfig = + WithExtrinsicParams>; -// Pay in asset fees. -// -// This needs to be used if the node uses the `pallet_asset_tx_payment`. -//pub type ParentchainExtrinsicParams = GenericExtrinsicParams; -// pub type ParentchainAdditionalParams = GenericAdditionalParams; +/// A struct representing the signed extra and additional parameters required +/// to construct a transaction and pay in token fees. +pub type PlainTipExtrinsicParams = GenericExtrinsicParams::Balance>>; +pub type AssetTipExtrinsicParams = GenericExtrinsicParams::Balance>>; pub type ParentchainUncheckedExtrinsic = UncheckedExtrinsicV4; -pub type ParentchainSignedExtra = GenericSignedExtra; +pub type ParentchainSignedExtra = GenericSignedExtra; pub type ParentchainSignature = Signature; /// Signature type of the [UncheckedExtrinsicV4]. pub type Signature = Option<(Address, PairSignature, SignedExtra)>; +use crate::traits::ExtrinsicParamsAdjustments; #[cfg(feature = "std")] pub use api::*; #[cfg(feature = "std")] mod api { - use super::ParentchainRuntimeConfig; + use super::{ParentchainAssetTipRuntimeConfig, ParentchainPlainTipRuntimeConfig}; use sp_runtime::generic::SignedBlock as GenericSignedBlock; use substrate_api_client::Api; @@ -94,5 +225,6 @@ mod api { pub type SignedBlock = GenericSignedBlock; - pub type ParentchainApi = Api; + pub type ParentchainPlainTipApi = Api; + pub type ParentchainAssetTipApi = Api; } diff --git a/core-primitives/node-api/factory/Cargo.toml b/core-primitives/node-api/factory/Cargo.toml index 234203ff24..de1a6d1bc2 100644 --- a/core-primitives/node-api/factory/Cargo.toml +++ b/core-primitives/node-api/factory/Cargo.toml @@ -12,3 +12,4 @@ sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polka # local itp-api-client-types = { path = "../api-client-types" } +itp-api-client-extensions = { path = "../api-client-extensions" } diff --git a/core-primitives/node-api/factory/src/lib.rs b/core-primitives/node-api/factory/src/lib.rs index 2a98e07a1c..b96dff9fe6 100644 --- a/core-primitives/node-api/factory/src/lib.rs +++ b/core-primitives/node-api/factory/src/lib.rs @@ -16,12 +16,15 @@ */ -use itp_api_client_types::{ParentchainApi, TungsteniteRpcClient}; +use itp_api_client_extensions::PalletTeerexApi; +use itp_api_client_types::{Request, TungsteniteRpcClient}; use sp_core::sr25519; +use std::marker::PhantomData; /// Trait to create a node API, based on a node URL and signer. pub trait CreateNodeApi { - fn create_api(&self) -> Result; + type Api: PalletTeerexApi; + fn create_api(&self) -> Result; } /// Node API factory error. @@ -49,25 +52,34 @@ impl From for NodeApiFactoryError { pub type Result = std::result::Result; +pub trait ParentchainApiWrapper { + type Api: PalletTeerexApi; + type Client; + fn new_api(client: Self::Client, signer: sr25519::Pair) -> Result; +} + /// Node API factory implementation. -pub struct NodeApiFactory { +pub struct NodeApiFactory { node_url: String, signer: sr25519::Pair, + _phantom: PhantomData, } -impl NodeApiFactory { +impl NodeApiFactory { pub fn new(url: String, signer: sr25519::Pair) -> Self { - NodeApiFactory { node_url: url, signer } + NodeApiFactory { node_url: url, signer, _phantom: Default::default() } } } -impl CreateNodeApi for NodeApiFactory { - fn create_api(&self) -> Result { +impl CreateNodeApi for NodeApiFactory +where + ApiWrapper: ParentchainApiWrapper, +{ + type Api = ApiWrapper::Api; + fn create_api(&self) -> Result { let rpc_client = TungsteniteRpcClient::new(self.node_url.as_str(), 5) .map_err(NodeApiFactoryError::FailedToCreateRpcClient)?; - let mut api = - ParentchainApi::new(rpc_client).map_err(NodeApiFactoryError::FailedToCreateNodeApi)?; - api.set_signer(self.signer.clone().into()); + let mut api = ApiWrapper::new_api(rpc_client, self.signer.clone())?; Ok(api) } } diff --git a/core/offchain-worker-executor/src/executor.rs b/core/offchain-worker-executor/src/executor.rs index 7b2f5b4df3..379b3c15f6 100644 --- a/core/offchain-worker-executor/src/executor.rs +++ b/core/offchain-worker-executor/src/executor.rs @@ -185,9 +185,8 @@ impl< } fn send_parentchain_effects(&self, parentchain_effects: Vec) -> Result<()> { - let extrinsics = self - .extrinsics_factory - .create_extrinsics(parentchain_effects.as_slice(), None)?; + let extrinsics = + self.extrinsics_factory.create_extrinsics(parentchain_effects.as_slice())?; self.validator_accessor .execute_mut_on_validator(|v| v.send_extrinsics(extrinsics))?; Ok(()) diff --git a/core/parentchain/block-importer/src/block_importer.rs b/core/parentchain/block-importer/src/block_importer.rs index 63e76e9210..da97d4127a 100644 --- a/core/parentchain/block-importer/src/block_importer.rs +++ b/core/parentchain/block-importer/src/block_importer.rs @@ -156,8 +156,7 @@ impl< } // Create extrinsics for all `unshielding` and `block processed` calls we've gathered. - let parentchain_extrinsics = - self.extrinsics_factory.create_extrinsics(calls.as_slice(), None)?; + let parentchain_extrinsics = self.extrinsics_factory.create_extrinsics(calls.as_slice())?; // Sending the extrinsic requires mut access because the validator caches the sent extrinsics internally. self.validator_accessor diff --git a/enclave-runtime/Cargo.lock b/enclave-runtime/Cargo.lock index 0bacf2606c..78f7a2f26d 100644 --- a/enclave-runtime/Cargo.lock +++ b/enclave-runtime/Cargo.lock @@ -1668,6 +1668,7 @@ dependencies = [ "binary-merkle-tree", "bs58", "frame-support", + "frame-system", "futures 0.3.8", "ita-sgx-runtime", "ita-stf", @@ -1684,6 +1685,7 @@ dependencies = [ "itp-utils", "log", "parity-scale-codec", + "scale-info", "sgx_tstd", "sgx_types", "sp-core", @@ -1982,6 +1984,7 @@ name = "itp-api-client-types" version = "0.9.0" dependencies = [ "itp-types", + "parity-scale-codec", "sp-core", "sp-runtime", "substrate-api-client", @@ -2056,6 +2059,7 @@ dependencies = [ "itp-node-api", "itp-nonce-cache", "itp-types", + "itp-utils", "log", "parity-scale-codec", "sgx_tstd", diff --git a/enclave-runtime/src/attestation.rs b/enclave-runtime/src/attestation.rs index ecbe3ac9d6..ef4149e319 100644 --- a/enclave-runtime/src/attestation.rs +++ b/enclave-runtime/src/attestation.rs @@ -382,7 +382,7 @@ pub fn generate_ias_skip_ra_extrinsic_from_der_cert_internal( fn create_extrinsics(call: OpaqueCall) -> EnclaveResult { let extrinsics_factory = get_extrinsic_factory_from_integritee_solo_or_parachain()?; - let extrinsics = extrinsics_factory.create_extrinsics(&[call], None)?; + let extrinsics = extrinsics_factory.create_extrinsics(&[call])?; Ok(extrinsics[0].clone()) } @@ -468,7 +468,7 @@ where info!(" [Enclave] Compose register collateral call: {:?}", call_ids); let call = OpaqueCall::from_tuple(&(call_ids, collateral_data, data_signature, issuer_chain)); - let extrinsic = extrinsics_factory.create_extrinsics(&[call], None)?[0].clone(); + let extrinsic = extrinsics_factory.create_extrinsics(&[call])?[0].clone(); if let Err(e) = write_slice_and_whitespace_pad(extrinsic_slice, extrinsic.encode()) { return EnclaveError::BufferError(e).into() }; diff --git a/enclave-runtime/src/initialization/global_components.rs b/enclave-runtime/src/initialization/global_components.rs index e051b947e2..cfa73f3ff5 100644 --- a/enclave-runtime/src/initialization/global_components.rs +++ b/enclave-runtime/src/initialization/global_components.rs @@ -143,8 +143,36 @@ pub type EnclaveSidechainApi = SidechainApi>; -pub type EnclaveExtrinsicsFactory = - ExtrinsicsFactory; + +pub type IntegriteeExtrinsicsFactory = ExtrinsicsFactory< + EnclaveParentchainSigner, + NonceCache, + EnclaveNodeMetadataRepository, + integritee::ParentchainExtrinsicParams, + integritee::ParentchainAdditionalParams, + integritee::ParentchainSignedExtra, + integritee::ParentchainAdditionalSigned, +>; + +pub type TargetAExtrinsicsFactory = ExtrinsicsFactory< + EnclaveParentchainSigner, + NonceCache, + EnclaveNodeMetadataRepository, + target_a::ParentchainExtrinsicParams, + target_a::ParentchainAdditionalParams, + target_a::ParentchainSignedExtra, + target_a::ParentchainAdditionalSigned, +>; + +pub type TargetBExtrinsicsFactory = ExtrinsicsFactory< + EnclaveParentchainSigner, + NonceCache, + EnclaveNodeMetadataRepository, + target_b::ParentchainExtrinsicParams, + target_b::ParentchainAdditionalParams, + target_b::ParentchainSignedExtra, + target_b::ParentchainAdditionalSigned, +>; pub type EnclaveValidatorAccessor = ValidatorAccessor< LightValidation, @@ -177,7 +205,7 @@ pub type IntegriteeParentchainBlockImporter = ParentchainBlockImporter< ParentchainBlock, EnclaveValidatorAccessor, EnclaveStfExecutor, - EnclaveExtrinsicsFactory, + IntegriteeExtrinsicsFactory, IntegriteeParentchainIndirectCallsExecutor, >; @@ -219,7 +247,7 @@ pub type TargetAParentchainBlockImporter = ParentchainBlockImporter< ParentchainBlock, EnclaveValidatorAccessor, EnclaveStfExecutor, - EnclaveExtrinsicsFactory, + TargetAExtrinsicsFactory, TargetAParentchainIndirectCallsExecutor, >; @@ -261,7 +289,7 @@ pub type TargetBParentchainBlockImporter = ParentchainBlockImporter< ParentchainBlock, EnclaveValidatorAccessor, EnclaveStfExecutor, - EnclaveExtrinsicsFactory, + TargetBExtrinsicsFactory, TargetBParentchainIndirectCallsExecutor, >; @@ -316,7 +344,7 @@ pub type EnclaveBlockImportConfirmationHandler = BlockImportConfirmationHandler< ParentchainBlock, <::Block as SidechainBlockTrait>::HeaderType, EnclaveNodeMetadataRepository, - EnclaveExtrinsicsFactory, + IntegriteeExtrinsicsFactory, EnclaveValidatorAccessor, >; pub type EnclaveSidechainBlockSyncer = PeerBlockSync< @@ -338,13 +366,37 @@ pub type EnclaveSealHandler = SealHandler< EnclaveStateHandler, EnclaveLightClientSeal, >; -pub type EnclaveOffchainWorkerExecutor = itc_offchain_worker_executor::executor::Executor< +pub type IntegriteeOffchainWorkerExecutor = itc_offchain_worker_executor::executor::Executor< + ParentchainBlock, + EnclaveTopPoolAuthor, + EnclaveStfExecutor, + EnclaveStateHandler, + EnclaveValidatorAccessor, + IntegriteeExtrinsicsFactory, + EnclaveStf, + EnclaveTrustedCallSigned, + EnclaveGetter, +>; + +pub type TargetAOffchainWorkerExecutor = itc_offchain_worker_executor::executor::Executor< + ParentchainBlock, + EnclaveTopPoolAuthor, + EnclaveStfExecutor, + EnclaveStateHandler, + EnclaveValidatorAccessor, + TargetAExtrinsicsFactory, + EnclaveStf, + EnclaveTrustedCallSigned, + EnclaveGetter, +>; + +pub type TargetBOffchainWorkerExecutor = itc_offchain_worker_executor::executor::Executor< ParentchainBlock, EnclaveTopPoolAuthor, EnclaveStfExecutor, EnclaveStateHandler, EnclaveValidatorAccessor, - EnclaveExtrinsicsFactory, + TargetBExtrinsicsFactory, EnclaveStf, EnclaveTrustedCallSigned, EnclaveGetter, diff --git a/enclave-runtime/src/initialization/parentchain/common.rs b/enclave-runtime/src/initialization/parentchain/common.rs index 077a59217e..b6194432d2 100644 --- a/enclave-runtime/src/initialization/parentchain/common.rs +++ b/enclave-runtime/src/initialization/parentchain/common.rs @@ -19,18 +19,22 @@ use crate::{ error::Result, initialization::{ global_components::{ - EnclaveExtrinsicsFactory, EnclaveNodeMetadataRepository, EnclaveOffchainWorkerExecutor, - EnclaveParentchainBlockImportQueue, EnclaveParentchainEventImportQueue, - EnclaveParentchainSigner, EnclaveStfExecutor, EnclaveValidatorAccessor, - IntegriteeParentchainBlockImportDispatcher, IntegriteeParentchainBlockImporter, + EnclaveNodeMetadataRepository, EnclaveParentchainBlockImportQueue, + EnclaveParentchainEventImportQueue, EnclaveParentchainSigner, EnclaveStfExecutor, + EnclaveValidatorAccessor, IntegriteeExtrinsicsFactory, + IntegriteeOffchainWorkerExecutor, IntegriteeParentchainBlockImportDispatcher, + IntegriteeParentchainBlockImporter, IntegriteeParentchainImmediateBlockImportDispatcher, IntegriteeParentchainIndirectCallsExecutor, - IntegriteeParentchainTriggeredBlockImportDispatcher, - TargetAParentchainBlockImportDispatcher, TargetAParentchainBlockImporter, - TargetAParentchainImmediateBlockImportDispatcher, - TargetAParentchainIndirectCallsExecutor, TargetBParentchainBlockImportDispatcher, + IntegriteeParentchainTriggeredBlockImportDispatcher, TargetAExtrinsicsFactory, + TargetAOffchainWorkerExecutor, TargetAParentchainBlockImportDispatcher, + TargetAParentchainBlockImporter, TargetAParentchainImmediateBlockImportDispatcher, + TargetAParentchainIndirectCallsExecutor, + TargetAParentchainTriggeredBlockImportDispatcher, TargetBExtrinsicsFactory, + TargetBOffchainWorkerExecutor, TargetBParentchainBlockImportDispatcher, TargetBParentchainBlockImporter, TargetBParentchainImmediateBlockImportDispatcher, - TargetBParentchainIndirectCallsExecutor, GLOBAL_OCALL_API_COMPONENT, + TargetBParentchainIndirectCallsExecutor, + TargetBParentchainTriggeredBlockImportDispatcher, GLOBAL_OCALL_API_COMPONENT, GLOBAL_SHIELDING_KEY_REPOSITORY_COMPONENT, GLOBAL_SIGNING_KEY_REPOSITORY_COMPONENT, GLOBAL_STATE_HANDLER_COMPONENT, GLOBAL_STATE_OBSERVER_COMPONENT, GLOBAL_TOP_POOL_AUTHOR_COMPONENT, @@ -38,7 +42,9 @@ use crate::{ EnclaveStfEnclaveSigner, }, }; +use ita_parentchain_interface::{integritee, target_a, target_b}; use itp_component_container::ComponentGetter; +use itp_node_api::api_client::ExtrinsicParams; use itp_nonce_cache::NonceCache; use itp_sgx_crypto::key_repository::AccessKey; use log::*; @@ -48,7 +54,7 @@ use std::sync::Arc; pub(crate) fn create_integritee_parentchain_block_importer( validator_access: Arc, stf_executor: Arc, - extrinsics_factory: Arc, + extrinsics_factory: Arc, node_metadata_repository: Arc, ) -> Result { let state_observer = GLOBAL_STATE_OBSERVER_COMPONENT.get()?; @@ -79,7 +85,7 @@ pub(crate) fn create_integritee_parentchain_block_importer( pub(crate) fn create_target_a_parentchain_block_importer( validator_access: Arc, stf_executor: Arc, - extrinsics_factory: Arc, + extrinsics_factory: Arc, node_metadata_repository: Arc, ) -> Result { let state_observer = GLOBAL_STATE_OBSERVER_COMPONENT.get()?; @@ -110,7 +116,7 @@ pub(crate) fn create_target_a_parentchain_block_importer( pub(crate) fn create_target_b_parentchain_block_importer( validator_access: Arc, stf_executor: Arc, - extrinsics_factory: Arc, + extrinsics_factory: Arc, node_metadata_repository: Arc, ) -> Result { let state_observer = GLOBAL_STATE_OBSERVER_COMPONENT.get()?; @@ -138,16 +144,67 @@ pub(crate) fn create_target_b_parentchain_block_importer( )) } -pub(crate) fn create_extrinsics_factory( +pub(crate) fn create_integritee_extrinsics_factory( genesis_hash: H256, nonce_cache: Arc, node_metadata_repository: Arc, -) -> Result> { +) -> Result> { let signer = GLOBAL_SIGNING_KEY_REPOSITORY_COMPONENT.get()?.retrieve_key()?; - Ok(Arc::new(EnclaveExtrinsicsFactory::new( + Ok(Arc::new(IntegriteeExtrinsicsFactory::new( genesis_hash, EnclaveParentchainSigner::new(signer), + integritee::ParentchainExtrinsicParams::new( + 0, + 0, + 0, + genesis_hash, + integritee::ParentchainAdditionalParams::default(), + ), + nonce_cache, + node_metadata_repository, + ))) +} + +pub(crate) fn create_target_a_extrinsics_factory( + genesis_hash: H256, + nonce_cache: Arc, + node_metadata_repository: Arc, +) -> Result> { + let signer = GLOBAL_SIGNING_KEY_REPOSITORY_COMPONENT.get()?.retrieve_key()?; + + Ok(Arc::new(TargetAExtrinsicsFactory::new( + genesis_hash, + EnclaveParentchainSigner::new(signer), + target_a::ParentchainExtrinsicParams::new( + 0, + 0, + 0, + genesis_hash, + target_a::ParentchainAdditionalParams::default(), + ), + nonce_cache, + node_metadata_repository, + ))) +} + +pub(crate) fn create_target_b_extrinsics_factory( + genesis_hash: H256, + nonce_cache: Arc, + node_metadata_repository: Arc, +) -> Result> { + let signer = GLOBAL_SIGNING_KEY_REPOSITORY_COMPONENT.get()?.retrieve_key()?; + + Ok(Arc::new(TargetBExtrinsicsFactory::new( + genesis_hash, + EnclaveParentchainSigner::new(signer), + target_b::ParentchainExtrinsicParams::new( + 0, + 0, + 0, + genesis_hash, + target_b::ParentchainAdditionalParams::default(), + ), nonce_cache, node_metadata_repository, ))) @@ -157,12 +214,12 @@ pub(crate) fn create_integritee_offchain_immediate_import_dispatcher( stf_executor: Arc, block_importer: IntegriteeParentchainBlockImporter, validator_access: Arc, - extrinsics_factory: Arc, + extrinsics_factory: Arc, ) -> Result> { let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; let top_pool_author = GLOBAL_TOP_POOL_AUTHOR_COMPONENT.get()?; - let offchain_worker_executor = Arc::new(EnclaveOffchainWorkerExecutor::new( + let offchain_worker_executor = Arc::new(IntegriteeOffchainWorkerExecutor::new( top_pool_author, stf_executor, state_handler, @@ -187,12 +244,12 @@ pub(crate) fn create_target_a_offchain_immediate_import_dispatcher( stf_executor: Arc, block_importer: TargetAParentchainBlockImporter, validator_access: Arc, - extrinsics_factory: Arc, + extrinsics_factory: Arc, ) -> Result> { let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; let top_pool_author = GLOBAL_TOP_POOL_AUTHOR_COMPONENT.get()?; - let offchain_worker_executor = Arc::new(EnclaveOffchainWorkerExecutor::new( + let offchain_worker_executor = Arc::new(TargetAOffchainWorkerExecutor::new( top_pool_author, stf_executor, state_handler, @@ -217,12 +274,12 @@ pub(crate) fn create_target_b_offchain_immediate_import_dispatcher( stf_executor: Arc, block_importer: TargetBParentchainBlockImporter, validator_access: Arc, - extrinsics_factory: Arc, + extrinsics_factory: Arc, ) -> Result> { let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; let top_pool_author = GLOBAL_TOP_POOL_AUTHOR_COMPONENT.get()?; - let offchain_worker_executor = Arc::new(EnclaveOffchainWorkerExecutor::new( + let offchain_worker_executor = Arc::new(TargetBOffchainWorkerExecutor::new( top_pool_author, stf_executor, state_handler, @@ -243,7 +300,7 @@ pub(crate) fn create_target_b_offchain_immediate_import_dispatcher( )))) } -pub(crate) fn create_sidechain_triggered_import_dispatcher( +pub(crate) fn create_sidechain_triggered_import_dispatcher_for_integritee( block_importer: IntegriteeParentchainBlockImporter, ) -> Arc { let parentchain_block_import_queue = EnclaveParentchainBlockImportQueue::default(); @@ -257,3 +314,33 @@ pub(crate) fn create_sidechain_triggered_import_dispatcher( triggered_dispatcher, ))) } + +pub(crate) fn create_sidechain_triggered_import_dispatcher_for_target_a( + block_importer: TargetAParentchainBlockImporter, +) -> Arc { + let parentchain_block_import_queue = EnclaveParentchainBlockImportQueue::default(); + let parentchain_event_import_queue = EnclaveParentchainEventImportQueue::default(); + let triggered_dispatcher = TargetAParentchainTriggeredBlockImportDispatcher::new( + block_importer, + parentchain_block_import_queue, + parentchain_event_import_queue, + ); + Arc::new(TargetAParentchainBlockImportDispatcher::new_triggered_dispatcher(Arc::new( + triggered_dispatcher, + ))) +} + +pub(crate) fn create_sidechain_triggered_import_dispatcher_for_target_b( + block_importer: TargetBParentchainBlockImporter, +) -> Arc { + let parentchain_block_import_queue = EnclaveParentchainBlockImportQueue::default(); + let parentchain_event_import_queue = EnclaveParentchainEventImportQueue::default(); + let triggered_dispatcher = TargetBParentchainTriggeredBlockImportDispatcher::new( + block_importer, + parentchain_block_import_queue, + parentchain_event_import_queue, + ); + Arc::new(TargetBParentchainBlockImportDispatcher::new_triggered_dispatcher(Arc::new( + triggered_dispatcher, + ))) +} diff --git a/enclave-runtime/src/initialization/parentchain/integritee_parachain.rs b/enclave-runtime/src/initialization/parentchain/integritee_parachain.rs index f13961aa8a..393397df02 100644 --- a/enclave-runtime/src/initialization/parentchain/integritee_parachain.rs +++ b/enclave-runtime/src/initialization/parentchain/integritee_parachain.rs @@ -19,17 +19,18 @@ use crate::{ error::Result, initialization::{ global_components::{ - EnclaveExtrinsicsFactory, EnclaveNodeMetadataRepository, EnclaveOCallApi, - EnclaveStfExecutor, EnclaveValidatorAccessor, + EnclaveNodeMetadataRepository, EnclaveOCallApi, EnclaveStfExecutor, + EnclaveValidatorAccessor, IntegriteeExtrinsicsFactory, IntegriteeParentchainBlockImportDispatcher, GLOBAL_INTEGRITEE_PARENTCHAIN_LIGHT_CLIENT_SEAL, GLOBAL_INTEGRITEE_PARENTCHAIN_NONCE_CACHE, GLOBAL_OCALL_API_COMPONENT, GLOBAL_STATE_HANDLER_COMPONENT, }, parentchain::common::{ - create_extrinsics_factory, create_integritee_offchain_immediate_import_dispatcher, + create_integritee_extrinsics_factory, + create_integritee_offchain_immediate_import_dispatcher, create_integritee_parentchain_block_importer, - create_sidechain_triggered_import_dispatcher, + create_sidechain_triggered_import_dispatcher_for_integritee, }, }, }; @@ -47,7 +48,7 @@ pub struct IntegriteeParachainHandler { pub node_metadata_repository: Arc, pub stf_executor: Arc, pub validator_accessor: Arc, - pub extrinsics_factory: Arc, + pub extrinsics_factory: Arc, pub import_dispatcher: Arc, } @@ -74,7 +75,7 @@ impl IntegriteeParachainHandler { let genesis_hash = validator_accessor.execute_on_validator(|v| v.genesis_hash())?; - let extrinsics_factory = create_extrinsics_factory( + let extrinsics_factory = create_integritee_extrinsics_factory( genesis_hash, GLOBAL_INTEGRITEE_PARENTCHAIN_NONCE_CACHE.clone(), node_metadata_repository.clone(), @@ -100,7 +101,8 @@ impl IntegriteeParachainHandler { validator_accessor.clone(), extrinsics_factory.clone(), )?, - WorkerMode::Sidechain => create_sidechain_triggered_import_dispatcher(block_importer), + WorkerMode::Sidechain => + create_sidechain_triggered_import_dispatcher_for_integritee(block_importer), WorkerMode::Teeracle => Arc::new(IntegriteeParentchainBlockImportDispatcher::new_empty_dispatcher()), }; diff --git a/enclave-runtime/src/initialization/parentchain/integritee_solochain.rs b/enclave-runtime/src/initialization/parentchain/integritee_solochain.rs index d84624f0e6..87dab85bf9 100644 --- a/enclave-runtime/src/initialization/parentchain/integritee_solochain.rs +++ b/enclave-runtime/src/initialization/parentchain/integritee_solochain.rs @@ -19,17 +19,18 @@ use crate::{ error::Result, initialization::{ global_components::{ - EnclaveExtrinsicsFactory, EnclaveNodeMetadataRepository, EnclaveOCallApi, - EnclaveStfExecutor, EnclaveValidatorAccessor, + EnclaveNodeMetadataRepository, EnclaveOCallApi, EnclaveStfExecutor, + EnclaveValidatorAccessor, IntegriteeExtrinsicsFactory, IntegriteeParentchainBlockImportDispatcher, GLOBAL_INTEGRITEE_PARENTCHAIN_LIGHT_CLIENT_SEAL, GLOBAL_INTEGRITEE_PARENTCHAIN_NONCE_CACHE, GLOBAL_OCALL_API_COMPONENT, GLOBAL_STATE_HANDLER_COMPONENT, }, parentchain::common::{ - create_extrinsics_factory, create_integritee_offchain_immediate_import_dispatcher, + create_integritee_extrinsics_factory, + create_integritee_offchain_immediate_import_dispatcher, create_integritee_parentchain_block_importer, - create_sidechain_triggered_import_dispatcher, + create_sidechain_triggered_import_dispatcher_for_integritee, }, }, }; @@ -46,7 +47,7 @@ pub struct IntegriteeSolochainHandler { pub node_metadata_repository: Arc, pub stf_executor: Arc, pub validator_accessor: Arc, - pub extrinsics_factory: Arc, + pub extrinsics_factory: Arc, pub import_dispatcher: Arc, } @@ -73,7 +74,7 @@ impl IntegriteeSolochainHandler { let genesis_hash = validator_accessor.execute_on_validator(|v| v.genesis_hash())?; - let extrinsics_factory = create_extrinsics_factory( + let extrinsics_factory = create_integritee_extrinsics_factory( genesis_hash, GLOBAL_INTEGRITEE_PARENTCHAIN_NONCE_CACHE.clone(), node_metadata_repository.clone(), @@ -99,7 +100,8 @@ impl IntegriteeSolochainHandler { validator_accessor.clone(), extrinsics_factory.clone(), )?, - WorkerMode::Sidechain => create_sidechain_triggered_import_dispatcher(block_importer), + WorkerMode::Sidechain => + create_sidechain_triggered_import_dispatcher_for_integritee(block_importer), WorkerMode::Teeracle => Arc::new(IntegriteeParentchainBlockImportDispatcher::new_empty_dispatcher()), }; diff --git a/enclave-runtime/src/initialization/parentchain/target_a_parachain.rs b/enclave-runtime/src/initialization/parentchain/target_a_parachain.rs index 56bb011919..bc5bed3130 100644 --- a/enclave-runtime/src/initialization/parentchain/target_a_parachain.rs +++ b/enclave-runtime/src/initialization/parentchain/target_a_parachain.rs @@ -25,13 +25,16 @@ use crate::{ error::Result, initialization::{ global_components::{ - EnclaveExtrinsicsFactory, EnclaveNodeMetadataRepository, EnclaveOCallApi, - EnclaveStfExecutor, EnclaveValidatorAccessor, TargetAParentchainBlockImportDispatcher, - GLOBAL_OCALL_API_COMPONENT, GLOBAL_STATE_HANDLER_COMPONENT, - GLOBAL_TARGET_A_PARENTCHAIN_LIGHT_CLIENT_SEAL, GLOBAL_TARGET_A_PARENTCHAIN_NONCE_CACHE, + EnclaveNodeMetadataRepository, EnclaveOCallApi, EnclaveStfExecutor, + EnclaveValidatorAccessor, TargetAExtrinsicsFactory, + TargetAParentchainBlockImportDispatcher, GLOBAL_OCALL_API_COMPONENT, + GLOBAL_STATE_HANDLER_COMPONENT, GLOBAL_TARGET_A_PARENTCHAIN_LIGHT_CLIENT_SEAL, + GLOBAL_TARGET_A_PARENTCHAIN_NONCE_CACHE, }, parentchain::common::{ - create_extrinsics_factory, create_target_a_offchain_immediate_import_dispatcher, + create_sidechain_triggered_import_dispatcher_for_target_a, + create_target_a_extrinsics_factory, + create_target_a_offchain_immediate_import_dispatcher, create_target_a_parentchain_block_importer, }, }, @@ -50,7 +53,7 @@ pub struct TargetAParachainHandler { pub node_metadata_repository: Arc, pub stf_executor: Arc, pub validator_accessor: Arc, - pub extrinsics_factory: Arc, + pub extrinsics_factory: Arc, pub import_dispatcher: Arc, } @@ -76,7 +79,7 @@ impl TargetAParachainHandler { let genesis_hash = validator_accessor.execute_on_validator(|v| v.genesis_hash())?; - let extrinsics_factory = create_extrinsics_factory( + let extrinsics_factory = create_target_a_extrinsics_factory( genesis_hash, GLOBAL_TARGET_A_PARENTCHAIN_NONCE_CACHE.clone(), node_metadata_repository.clone(), @@ -103,7 +106,7 @@ impl TargetAParachainHandler { extrinsics_factory.clone(), )?, WorkerMode::Sidechain => - unimplemented!("Can't run target a chain in sidechain mode yet."), + create_sidechain_triggered_import_dispatcher_for_target_a(block_importer), WorkerMode::Teeracle => Arc::new(TargetAParentchainBlockImportDispatcher::new_empty_dispatcher()), }; diff --git a/enclave-runtime/src/initialization/parentchain/target_a_solochain.rs b/enclave-runtime/src/initialization/parentchain/target_a_solochain.rs index 60259eedbe..1434564654 100644 --- a/enclave-runtime/src/initialization/parentchain/target_a_solochain.rs +++ b/enclave-runtime/src/initialization/parentchain/target_a_solochain.rs @@ -19,31 +19,33 @@ use crate::{ error::Result, initialization::{ global_components::{ - EnclaveExtrinsicsFactory, EnclaveNodeMetadataRepository, EnclaveOCallApi, - EnclaveStfExecutor, EnclaveValidatorAccessor, TargetAParentchainBlockImportDispatcher, - GLOBAL_OCALL_API_COMPONENT, GLOBAL_STATE_HANDLER_COMPONENT, - GLOBAL_TARGET_A_PARENTCHAIN_LIGHT_CLIENT_SEAL, GLOBAL_TARGET_A_PARENTCHAIN_NONCE_CACHE, + EnclaveNodeMetadataRepository, EnclaveOCallApi, EnclaveStfExecutor, + EnclaveValidatorAccessor, TargetAExtrinsicsFactory, + TargetAParentchainBlockImportDispatcher, GLOBAL_OCALL_API_COMPONENT, + GLOBAL_STATE_HANDLER_COMPONENT, GLOBAL_TARGET_A_PARENTCHAIN_LIGHT_CLIENT_SEAL, + GLOBAL_TARGET_A_PARENTCHAIN_NONCE_CACHE, }, parentchain::common::{ - create_extrinsics_factory, create_target_a_offchain_immediate_import_dispatcher, + create_sidechain_triggered_import_dispatcher_for_target_a, + create_target_a_extrinsics_factory, + create_target_a_offchain_immediate_import_dispatcher, create_target_a_parentchain_block_importer, }, }, }; use itc_parentchain::light_client::{concurrent_access::ValidatorAccess, LightClientState}; +pub use itc_parentchain::primitives::{SolochainBlock, SolochainHeader, SolochainParams}; use itp_component_container::ComponentGetter; use itp_settings::worker_mode::{ProvideWorkerMode, WorkerMode}; use itp_types::parentchain::ParentchainId; use std::{path::PathBuf, sync::Arc}; -pub use itc_parentchain::primitives::{SolochainBlock, SolochainHeader, SolochainParams}; - pub struct TargetASolochainHandler { pub genesis_header: SolochainHeader, pub node_metadata_repository: Arc, pub stf_executor: Arc, pub validator_accessor: Arc, - pub extrinsics_factory: Arc, + pub extrinsics_factory: Arc, pub import_dispatcher: Arc, } @@ -69,7 +71,7 @@ impl TargetASolochainHandler { let genesis_hash = validator_accessor.execute_on_validator(|v| v.genesis_hash())?; - let extrinsics_factory = create_extrinsics_factory( + let extrinsics_factory = create_target_a_extrinsics_factory( genesis_hash, GLOBAL_TARGET_A_PARENTCHAIN_NONCE_CACHE.clone(), node_metadata_repository.clone(), @@ -96,7 +98,7 @@ impl TargetASolochainHandler { extrinsics_factory.clone(), )?, WorkerMode::Sidechain => - unimplemented!("Can't run target a chain in sidechain mode yet."), + create_sidechain_triggered_import_dispatcher_for_target_a(block_importer), WorkerMode::Teeracle => Arc::new(TargetAParentchainBlockImportDispatcher::new_empty_dispatcher()), }; diff --git a/enclave-runtime/src/initialization/parentchain/target_b_parachain.rs b/enclave-runtime/src/initialization/parentchain/target_b_parachain.rs index bd1b628b06..1153bb17f3 100644 --- a/enclave-runtime/src/initialization/parentchain/target_b_parachain.rs +++ b/enclave-runtime/src/initialization/parentchain/target_b_parachain.rs @@ -25,32 +25,34 @@ use crate::{ error::Result, initialization::{ global_components::{ - EnclaveExtrinsicsFactory, EnclaveNodeMetadataRepository, EnclaveOCallApi, - EnclaveStfExecutor, EnclaveValidatorAccessor, TargetBParentchainBlockImportDispatcher, - GLOBAL_OCALL_API_COMPONENT, GLOBAL_STATE_HANDLER_COMPONENT, - GLOBAL_TARGET_B_PARENTCHAIN_LIGHT_CLIENT_SEAL, GLOBAL_TARGET_B_PARENTCHAIN_NONCE_CACHE, + EnclaveNodeMetadataRepository, EnclaveOCallApi, EnclaveStfExecutor, + EnclaveValidatorAccessor, TargetBExtrinsicsFactory, + TargetBParentchainBlockImportDispatcher, GLOBAL_OCALL_API_COMPONENT, + GLOBAL_STATE_HANDLER_COMPONENT, GLOBAL_TARGET_B_PARENTCHAIN_LIGHT_CLIENT_SEAL, + GLOBAL_TARGET_B_PARENTCHAIN_NONCE_CACHE, }, parentchain::common::{ - create_extrinsics_factory, create_target_b_offchain_immediate_import_dispatcher, + create_sidechain_triggered_import_dispatcher_for_target_b, + create_target_b_extrinsics_factory, + create_target_b_offchain_immediate_import_dispatcher, create_target_b_parentchain_block_importer, }, }, }; use itc_parentchain::light_client::{concurrent_access::ValidatorAccess, LightClientState}; +pub use itc_parentchain::primitives::{ParachainBlock, ParachainHeader, ParachainParams}; use itp_component_container::ComponentGetter; use itp_settings::worker_mode::{ProvideWorkerMode, WorkerMode}; use itp_types::parentchain::ParentchainId; use std::{path::PathBuf, sync::Arc}; -pub use itc_parentchain::primitives::{ParachainBlock, ParachainHeader, ParachainParams}; - #[derive(Clone)] pub struct TargetBParachainHandler { pub genesis_header: ParachainHeader, pub node_metadata_repository: Arc, pub stf_executor: Arc, pub validator_accessor: Arc, - pub extrinsics_factory: Arc, + pub extrinsics_factory: Arc, pub import_dispatcher: Arc, } @@ -76,7 +78,7 @@ impl TargetBParachainHandler { let genesis_hash = validator_accessor.execute_on_validator(|v| v.genesis_hash())?; - let extrinsics_factory = create_extrinsics_factory( + let extrinsics_factory = create_target_b_extrinsics_factory( genesis_hash, GLOBAL_TARGET_B_PARENTCHAIN_NONCE_CACHE.clone(), node_metadata_repository.clone(), @@ -103,7 +105,7 @@ impl TargetBParachainHandler { extrinsics_factory.clone(), )?, WorkerMode::Sidechain => - unimplemented!("Can't run target B chain in sidechain mode yet."), + create_sidechain_triggered_import_dispatcher_for_target_b(block_importer), WorkerMode::Teeracle => Arc::new(TargetBParentchainBlockImportDispatcher::new_empty_dispatcher()), }; diff --git a/enclave-runtime/src/initialization/parentchain/target_b_solochain.rs b/enclave-runtime/src/initialization/parentchain/target_b_solochain.rs index d3ec66beae..4807610193 100644 --- a/enclave-runtime/src/initialization/parentchain/target_b_solochain.rs +++ b/enclave-runtime/src/initialization/parentchain/target_b_solochain.rs @@ -19,31 +19,33 @@ use crate::{ error::Result, initialization::{ global_components::{ - EnclaveExtrinsicsFactory, EnclaveNodeMetadataRepository, EnclaveOCallApi, - EnclaveStfExecutor, EnclaveValidatorAccessor, TargetBParentchainBlockImportDispatcher, - GLOBAL_OCALL_API_COMPONENT, GLOBAL_STATE_HANDLER_COMPONENT, - GLOBAL_TARGET_B_PARENTCHAIN_LIGHT_CLIENT_SEAL, GLOBAL_TARGET_B_PARENTCHAIN_NONCE_CACHE, + EnclaveNodeMetadataRepository, EnclaveOCallApi, EnclaveStfExecutor, + EnclaveValidatorAccessor, TargetBExtrinsicsFactory, + TargetBParentchainBlockImportDispatcher, GLOBAL_OCALL_API_COMPONENT, + GLOBAL_STATE_HANDLER_COMPONENT, GLOBAL_TARGET_B_PARENTCHAIN_LIGHT_CLIENT_SEAL, + GLOBAL_TARGET_B_PARENTCHAIN_NONCE_CACHE, }, parentchain::common::{ - create_extrinsics_factory, create_target_b_offchain_immediate_import_dispatcher, + create_sidechain_triggered_import_dispatcher_for_target_b, + create_target_b_extrinsics_factory, + create_target_b_offchain_immediate_import_dispatcher, create_target_b_parentchain_block_importer, }, }, }; use itc_parentchain::light_client::{concurrent_access::ValidatorAccess, LightClientState}; +pub use itc_parentchain::primitives::{SolochainBlock, SolochainHeader, SolochainParams}; use itp_component_container::ComponentGetter; use itp_settings::worker_mode::{ProvideWorkerMode, WorkerMode}; use itp_types::parentchain::ParentchainId; use std::{path::PathBuf, sync::Arc}; -pub use itc_parentchain::primitives::{SolochainBlock, SolochainHeader, SolochainParams}; - pub struct TargetBSolochainHandler { pub genesis_header: SolochainHeader, pub node_metadata_repository: Arc, pub stf_executor: Arc, pub validator_accessor: Arc, - pub extrinsics_factory: Arc, + pub extrinsics_factory: Arc, pub import_dispatcher: Arc, } @@ -69,7 +71,7 @@ impl TargetBSolochainHandler { let genesis_hash = validator_accessor.execute_on_validator(|v| v.genesis_hash())?; - let extrinsics_factory = create_extrinsics_factory( + let extrinsics_factory = create_target_b_extrinsics_factory( genesis_hash, GLOBAL_TARGET_B_PARENTCHAIN_NONCE_CACHE.clone(), node_metadata_repository.clone(), @@ -96,7 +98,7 @@ impl TargetBSolochainHandler { extrinsics_factory.clone(), )?, WorkerMode::Sidechain => - unimplemented!("Can't run target B chain in sidechain mode yet."), + create_sidechain_triggered_import_dispatcher_for_target_b(block_importer), WorkerMode::Teeracle => Arc::new(TargetBParentchainBlockImportDispatcher::new_empty_dispatcher()), }; diff --git a/enclave-runtime/src/shard_vault.rs b/enclave-runtime/src/shard_vault.rs index 860f2ef56d..17c661b62a 100644 --- a/enclave-runtime/src/shard_vault.rs +++ b/enclave-runtime/src/shard_vault.rs @@ -138,7 +138,7 @@ pub(crate) fn init_proxied_shard_vault_internal(shard: ShardIdentifier) -> Encla )); info!("vault funding call: 0x{}", hex::encode(call.0.clone())); - let xts = enclave_extrinsics_factory.create_extrinsics(&[call], None)?; + let xts = enclave_extrinsics_factory.create_extrinsics(&[call])?; //this extrinsic must be included in a block before we can move on. otherwise the next will fail ocall_api.send_to_parentchain(xts, &ParentchainId::Integritee, true)?; @@ -161,7 +161,7 @@ pub(crate) fn init_proxied_shard_vault_internal(shard: ShardIdentifier) -> Encla )); info!("add proxy call: 0x{}", hex::encode(call.0.clone())); - let xts = vault_extrinsics_factory.create_extrinsics(&[call], None)?; + let xts = vault_extrinsics_factory.create_extrinsics(&[call])?; ocall_api.send_to_parentchain(xts, &ParentchainId::Integritee, false)?; Ok(()) @@ -201,7 +201,7 @@ pub(crate) fn add_shard_vault_proxy( )); info!("proxied add proxy call: 0x{}", hex::encode(call.0.clone())); - let xts = enclave_extrinsics_factory.create_extrinsics(&[call], None)?; + let xts = enclave_extrinsics_factory.create_extrinsics(&[call])?; ocall_api.send_to_parentchain(xts, &ParentchainId::Integritee, false)?; Ok(()) diff --git a/enclave-runtime/src/teeracle/mod.rs b/enclave-runtime/src/teeracle/mod.rs index 75f378c9a0..6894927f7e 100644 --- a/enclave-runtime/src/teeracle/mod.rs +++ b/enclave-runtime/src/teeracle/mod.rs @@ -59,7 +59,7 @@ fn update_weather_data_internal(weather_info: WeatherInfo) -> Result Result> { +) -> Result> { let extrinsics_factory = if let Ok(solochain_handler) = GLOBAL_INTEGRITEE_SOLOCHAIN_HANDLER_COMPONENT.get() { solochain_handler.extrinsics_factory.clone() diff --git a/service/Cargo.toml b/service/Cargo.toml index 482ff433fe..4e8e01156a 100644 --- a/service/Cargo.toml +++ b/service/Cargo.toml @@ -39,6 +39,7 @@ sgx_crypto_helper = { branch = "master", git = "https://github.com/apache/teacla sgx_types = { branch = "master", git = "https://github.com/apache/teaclave-sgx-sdk.git" } # local +ita-parentchain-interface = { path = "../app-libs/parentchain-interface" } itc-parentchain = { path = "../core/parentchain/parentchain-crate" } itc-rest-client = { path = "../core/rest-client" } itc-rpc-client = { path = "../core/rpc-client" } diff --git a/service/src/account_funding.rs b/service/src/account_funding.rs index 787072fd60..83da4950dd 100644 --- a/service/src/account_funding.rs +++ b/service/src/account_funding.rs @@ -16,20 +16,23 @@ */ use crate::error::{Error, ServiceResult}; -use itp_node_api::api_client::{AccountApi, ParentchainApi}; +use codec::Encode; +use itp_api_client_types::ParentchainUncheckedExtrinsic; +use itp_node_api::api_client::{AccountApi, ChainApi, UncheckedExtrinsicV4}; use itp_settings::worker::{ EXISTENTIAL_DEPOSIT_FACTOR_FOR_INIT_FUNDS, REGISTERING_FEE_FACTOR_FOR_INIT_FUNDS, }; -use itp_types::parentchain::Balance; +use itp_types::parentchain::{AccountId, Address, Balance, Hash, Index, Signature}; use log::*; use sp_core::{ crypto::{AccountId32, Ss58Codec}, - Pair, + sr25519, Pair, }; use sp_keyring::AccountKeyring; -use sp_runtime::MultiAddress; +use sp_runtime::{MultiAddress, OpaqueExtrinsic}; use substrate_api_client::{ - extrinsic::BalancesExtrinsics, GetBalance, GetTransactionPayment, SubmitAndWatch, XtStatus, + extrinsic::{balances::TransferAllowDeathCall, BalancesExtrinsics}, + GetBalance, GetTransactionPayment, SubmitAndWatch, XtStatus, }; /// Information about the enclave on-chain account. @@ -37,29 +40,50 @@ pub trait EnclaveAccountInfo { fn free_balance(&self) -> ServiceResult; } -pub struct EnclaveAccountInfoProvider { +pub struct EnclaveAccountInfoProvider { node_api: ParentchainApi, account_id: AccountId32, } -impl EnclaveAccountInfo for EnclaveAccountInfoProvider { +impl EnclaveAccountInfo for EnclaveAccountInfoProvider +where + ParentchainApi: AccountApi, +{ fn free_balance(&self) -> ServiceResult { self.node_api.get_free_balance(&self.account_id).map_err(|e| e.into()) } } -impl EnclaveAccountInfoProvider { +impl EnclaveAccountInfoProvider { pub fn new(node_api: ParentchainApi, account_id: AccountId32) -> Self { - EnclaveAccountInfoProvider { node_api, account_id } + Self { node_api, account_id } } } -pub fn setup_account_funding( +pub fn setup_account_funding( api: &ParentchainApi, accountid: &AccountId32, encoded_extrinsic: Vec, is_development_mode: bool, -) -> ServiceResult<()> { +) -> ServiceResult<()> +where + ParentchainApi: AccountApi + + GetBalance + + GetTransactionPayment + + BalancesExtrinsics< + Address = Address, + Balance = Balance, + Extrinsic> = UncheckedExtrinsicV4< + Address, + TransferAllowDeathCall, + ::Signature, + ::SignedExtra, + >, + > + SubmitAndWatch + + ChainApi, + ParentchainApi::Signature: Encode, + ParentchainApi::SignedExtra: Encode, +{ // Account funds if is_development_mode { // Development mode, the faucet will ensure that the enclave has enough funds @@ -91,7 +115,27 @@ pub fn setup_account_funding( } // Alice plays the faucet and sends some funds to the account if balance is low -fn ensure_account_has_funds(api: &ParentchainApi, accountid: &AccountId32) -> Result<(), Error> { +fn ensure_account_has_funds( + api: &ParentchainApi, + accountid: &AccountId32, +) -> Result<(), Error> +where + ParentchainApi: AccountApi + + GetBalance + + BalancesExtrinsics< + Address = Address, + Balance = Balance, + Extrinsic> = UncheckedExtrinsicV4< + Address, + TransferAllowDeathCall, + ::Signature, + ::SignedExtra, + >, + > + SubmitAndWatch + + ChainApi, + ParentchainApi::Signature: Encode, + ParentchainApi::SignedExtra: Encode, +{ // check account balance let free_balance = api.get_free_balance(accountid)?; info!("TEE's free balance = {:?} (Account: {})", free_balance, accountid); @@ -110,7 +154,7 @@ fn ensure_account_has_funds(api: &ParentchainApi, accountid: &AccountId32) -> Re Ok(()) } -fn enclave_registration_fees( +fn enclave_registration_fees>( api: &ParentchainApi, encoded_extrinsic: Vec, ) -> Result { @@ -128,11 +172,27 @@ fn enclave_registration_fees( } // Alice sends some funds to the account -fn bootstrap_funds_from_alice( +fn bootstrap_funds_from_alice( api: &ParentchainApi, accountid: &AccountId32, funding_amount: u128, -) -> Result<(), Error> { +) -> Result<(), Error> +where + ParentchainApi: BalancesExtrinsics< + Address = Address, + Balance = Balance, + Extrinsic> = UncheckedExtrinsicV4< + Address, + TransferAllowDeathCall, + ::Signature, + ::SignedExtra, + >, + > + SubmitAndWatch + + AccountApi + + ChainApi, + ParentchainApi::Signature: Encode, + ParentchainApi::SignedExtra: Encode, +{ let alice = AccountKeyring::Alice.pair(); let alice_acc = AccountId32::from(*alice.public().as_array_ref()); @@ -153,8 +213,8 @@ fn bootstrap_funds_from_alice( alice_signer_api.set_signer(alice.into()); println!("[+] send extrinsic: bootstrap funding Enclave from Alice's funds"); - let xt = alice_signer_api - .balance_transfer_allow_death(MultiAddress::Id(accountid.clone()), funding_amount); + let xt = + alice_signer_api.balance_transfer_allow_death(accountid.clone().into(), funding_amount); let xt_report = alice_signer_api.submit_and_watch_extrinsic_until(xt, XtStatus::InBlock)?; info!( "[<] L1 extrinsic success. extrinsic hash: {:?} / status: {:?}", diff --git a/service/src/main.rs b/service/src/main.rs index 2f9961ccb5..8d561180ea 100644 --- a/service/src/main.rs +++ b/service/src/main.rs @@ -25,6 +25,7 @@ mod error; mod globals; mod initialized_service; mod ocall_bridge; +mod parentchain_config; mod parentchain_handler; mod prometheus_metrics; mod setup; diff --git a/service/src/main_impl.rs b/service/src/main_impl.rs index 5c1c0beb2c..2b8c8b2f7a 100644 --- a/service/src/main_impl.rs +++ b/service/src/main_impl.rs @@ -19,6 +19,7 @@ use crate::{ ocall_bridge::{ bridge_api::Bridge as OCallBridge, component_factory::OCallBridgeComponentFactory, }, + parentchain_config::{IntegriteeParentchainApi, TargetAParentchainApi, TargetBParentchainApi}, parentchain_handler::{HandleParentchain, ParentchainHandler}, prometheus_metrics::{start_metrics_server, EnclaveMetricsReceiver, MetricsHandler}, setup, @@ -40,7 +41,7 @@ use itp_enclave_api::{ teeracle_api::TeeracleApi, }; use itp_node_api::{ - api_client::{AccountApi, PalletTeerexApi, ParentchainApi}, + api_client::{AccountApi, PalletTeerexApi}, metadata::NodeMetadata, node_api_factory::{CreateNodeApi, NodeApiFactory}, }; @@ -51,12 +52,12 @@ use its_peer_fetch::{ use its_primitives::types::block::SignedBlock as SignedSidechainBlock; use its_storage::{interface::FetchBlocks, BlockPruner, SidechainStorageLock}; use log::*; -use my_node_runtime::{Hash, Header, RuntimeEvent}; +use my_node_runtime::RuntimeEvent; use sgx_types::*; use sp_runtime::traits::Header as HeaderT; use substrate_api_client::{ - api::XtStatus, rpc::HandleSubscription, GetChainInfo, SubmitAndWatch, SubscribeChain, - SubscribeEvents, + api::XtStatus, rpc::HandleSubscription, GetBalance, GetChainInfo, GetTransactionPayment, + SubmitAndWatch, SubscribeChain, SubscribeEvents, }; use teerex_primitives::AnySigner; @@ -66,18 +67,28 @@ use sgx_verify::extract_tcb_info_from_raw_dcap_quote; use itp_enclave_api::Enclave; +use crate::parentchain_config::{ + IntegriteeParentchainApiWrapper, TargetAParentchainApiWrapper, TargetBParentchainApiWrapper, +}; use enclave_bridge_primitives::ShardIdentifier; use itc_parentchain::primitives::ParentchainId; +use itp_node_api::api_client::ChainApi; +use itp_types::parentchain::{Hash, Header}; use sp_core::crypto::{AccountId32, Ss58Codec}; use sp_keyring::AccountKeyring; use sp_runtime::MultiSigner; use std::{str, sync::Arc, thread, time::Duration}; +use substrate_api_client::extrinsic::BalancesExtrinsics; const VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg(feature = "link-binary")] -pub type EnclaveWorker = - Worker>; +pub type EnclaveWorker = Worker< + Config, + NodeApiFactory, + Enclave, + InitializationHandler, +>; pub type Event = substrate_api_client::ac_node_api::EventRecord; pub(crate) fn main() { @@ -113,7 +124,7 @@ pub(crate) fn main() { ) .unwrap(), ); - let node_api_factory = Arc::new(NodeApiFactory::new( + let node_api_factory = Arc::new(NodeApiFactory::::new( config.integritee_rpc_endpoint(), AccountKeyring::Alice.pair(), )); @@ -134,13 +145,21 @@ pub(crate) fn main() { Arc::new(BlockFetcher::::new(untrusted_peer_fetcher)); let enclave_metrics_receiver = Arc::new(EnclaveMetricsReceiver {}); - let maybe_target_a_parentchain_api_factory = config - .target_a_parentchain_rpc_endpoint() - .map(|url| Arc::new(NodeApiFactory::new(url, AccountKeyring::Alice.pair()))); + let maybe_target_a_parentchain_api_factory = + config.target_a_parentchain_rpc_endpoint().map(|url| { + Arc::new(NodeApiFactory::::new( + url, + AccountKeyring::Alice.pair(), + )) + }); - let maybe_target_b_parentchain_api_factory = config - .target_b_parentchain_rpc_endpoint() - .map(|url| Arc::new(NodeApiFactory::new(url, AccountKeyring::Alice.pair()))); + let maybe_target_b_parentchain_api_factory = + config.target_b_parentchain_rpc_endpoint().map(|url| { + Arc::new(NodeApiFactory::::new( + url, + AccountKeyring::Alice.pair(), + )) + }); // initialize o-call bridge with a concrete factory implementation OCallBridge::initialize(Arc::new(OCallBridgeComponentFactory::new( @@ -275,7 +294,7 @@ fn start_worker( shard: &ShardIdentifier, enclave: Arc, sidechain_storage: Arc, - integritee_rpc_api: ParentchainApi, + integritee_rpc_api: IntegriteeParentchainApi, tokio_handle_getter: Arc, initialization_handler: Arc, quoting_enclave_target_info: Option, @@ -429,7 +448,7 @@ fn start_worker( // Init parentchain specific stuff. Needed for parentchain communication. let (parentchain_handler, last_synced_header) = - init_parentchain(&enclave, &integritee_rpc_api, &tee_accountid, ParentchainId::Integritee); + init_integritee_parentchain(&enclave, &integritee_rpc_api, &tee_accountid); #[cfg(feature = "dcap")] register_collateral( @@ -477,7 +496,12 @@ fn start_worker( let tee_accountid_clone = tee_accountid.clone(); let send_register_xt = move || { println!("[+] Send register enclave extrinsic"); - send_extrinsic(register_xt(), &node_api2, &tee_accountid_clone, is_development_mode) + send_integritee_extrinsic( + register_xt(), + &node_api2, + &tee_accountid_clone, + is_development_mode, + ) }; // Todo: Can't unwrap here because the extrinsic is for some reason not found in the block @@ -584,11 +608,28 @@ fn start_worker( spawn_worker_for_shard_polling(shard, integritee_rpc_api.clone(), initialization_handler); } + let maybe_target_a_parentchain_api_factory = + config.target_a_parentchain_rpc_endpoint().map(|url| { + Arc::new(NodeApiFactory::::new( + url, + AccountKeyring::Alice.pair(), + )) + }); + + let maybe_target_b_parentchain_api_factory = + config.target_b_parentchain_rpc_endpoint().map(|url| { + Arc::new(NodeApiFactory::::new( + url, + AccountKeyring::Alice.pair(), + )) + }); + if let Some(url) = config.target_a_parentchain_rpc_endpoint() { init_target_parentchain( &enclave, &tee_accountid, - url, + maybe_target_a_parentchain_api_factory + .expect("api factory for target a must be present at this point"), ParentchainId::TargetA, is_development_mode, ) @@ -598,7 +639,8 @@ fn start_worker( init_target_parentchain( &enclave, &tee_accountid, - url, + maybe_target_b_parentchain_api_factory + .expect("api factory for target b must be present at this point"), ParentchainId::TargetB, is_development_mode, ) @@ -616,17 +658,24 @@ fn start_worker( } } -fn init_target_parentchain( +fn init_target_parentchain( enclave: &Arc, tee_account_id: &AccountId32, - url: String, + api_factory: ApiFactory, parentchain_id: ParentchainId, is_development_mode: bool, ) where E: EnclaveBase + Sidechain, + ApiFactory: CreateNodeApi, + ApiFactory::Api: ChainApi + + AccountApi + + GetTransactionPayment + + GetBalance + + BalancesExtrinsics + + SubmitAndWatch, { - println!("Initializing parentchain {:?} with url: {}", parentchain_id, url); - let node_api = NodeApiFactory::new(url, AccountKeyring::Alice.pair()) + println!("Initializing parentchain {:?}", parentchain_id); + let node_api = api_factory .create_api() .unwrap_or_else(|_| panic!("[{:?}] Failed to create parentchain node API", parentchain_id)); @@ -681,15 +730,62 @@ fn init_target_parentchain( .unwrap(); } -fn init_parentchain( +fn init_parentchain( enclave: &Arc, node_api: &ParentchainApi, tee_account_id: &AccountId32, parentchain_id: ParentchainId, ) -> (Arc>, Header) +where + E: EnclaveBase + Sidechain, + ParentchainApi: ChainApi + + AccountApi + + GetTransactionPayment + + GetBalance + + BalancesExtrinsics + + SubmitAndWatch, +{ + let parentchain_handler = Arc::new( + ParentchainHandler::new_with_automatic_light_client_allocation( + node_api.clone(), + enclave.clone(), + parentchain_id, + ) + .unwrap(), + ); + let last_synced_header = parentchain_handler.init_parentchain_components().unwrap(); + println!("[{:?}] last synced parentchain block: {}", parentchain_id, last_synced_header.number); + + let nonce = node_api.get_nonce_of(tee_account_id).unwrap(); + info!("[{:?}] Enclave nonce = {:?}", parentchain_id, nonce); + enclave.set_nonce(nonce, parentchain_id).unwrap_or_else(|_| { + panic!("[{:?}] Could not set nonce of enclave. Returning here...", parentchain_id) + }); + + let metadata = node_api.metadata().clone(); + let runtime_spec_version = node_api.runtime_version().spec_version; + let runtime_transaction_version = node_api.runtime_version().transaction_version; + enclave + .set_node_metadata( + NodeMetadata::new(metadata, runtime_spec_version, runtime_transaction_version).encode(), + parentchain_id, + ) + .unwrap_or_else(|_| { + panic!("[{:?}] Could not set the node metadata in the enclave", parentchain_id) + }); + + (parentchain_handler, last_synced_header) +} + +fn init_integritee_parentchain( + enclave: &Arc, + node_api: &IntegriteeParentchainApi, + tee_account_id: &AccountId32, +) -> (Arc>, Header) where E: EnclaveBase + Sidechain, { + let parentchain_id = ParentchainId::Integritee; let parentchain_handler = Arc::new( ParentchainHandler::new_with_automatic_light_client_allocation( node_api.clone(), @@ -728,7 +824,7 @@ where /// considered initialized and ready for the next worker to start. fn spawn_worker_for_shard_polling( shard: &ShardIdentifier, - node_api: ParentchainApi, + node_api: IntegriteeParentchainApi, initialization_handler: Arc, ) where InitializationHandler: TrackInitialization + Sync + Send + 'static, @@ -963,7 +1059,7 @@ fn register_quotes_from_marblerun( for quote in quotes { match enclave.generate_dcap_ra_extrinsic_from_quote(url.clone(), "e) { Ok(xt) => { - send_extrinsic(xt, api, accountid, is_development_mode); + send_integritee_extrinsic(xt, api, accountid, is_development_mode); }, Err(e) => { error!("Extracting information from quote failed: {}", e) @@ -973,7 +1069,7 @@ fn register_quotes_from_marblerun( } #[cfg(feature = "dcap")] fn register_collateral( - api: &ParentchainApi, + api: &IntegriteeParentchainApi, enclave: &dyn RemoteAttestation, accountid: &AccountId32, is_development_mode: bool, @@ -985,17 +1081,17 @@ fn register_collateral( let (fmspc, _tcb_info) = extract_tcb_info_from_raw_dcap_quote(&dcap_quote).unwrap(); println!("[>] DCAP setup: register QE collateral"); let uxt = enclave.generate_register_quoting_enclave_extrinsic(fmspc).unwrap(); - send_extrinsic(uxt, api, accountid, is_development_mode); + send_integritee_extrinsic(uxt, api, accountid, is_development_mode); println!("[>] DCAP setup: register TCB info"); let uxt = enclave.generate_register_tcb_info_extrinsic(fmspc).unwrap(); - send_extrinsic(uxt, api, accountid, is_development_mode); + send_integritee_extrinsic(uxt, api, accountid, is_development_mode); } } -fn send_extrinsic( +fn send_integritee_extrinsic( extrinsic: Vec, - api: &ParentchainApi, + api: &IntegriteeParentchainApi, fee_payer: &AccountId32, is_development_mode: bool, ) -> Option { @@ -1028,10 +1124,13 @@ fn send_extrinsic( /// Subscribe to the node API finalized heads stream and trigger a parent chain sync /// upon receiving a new header. -fn subscribe_to_parentchain_new_headers( +fn subscribe_to_parentchain_new_headers( parentchain_handler: Arc>, mut last_synced_header: Header, -) -> Result<(), Error> { +) -> Result<(), Error> +where + ParentchainApi: ChainApi, +{ // TODO: this should be implemented by parentchain_handler directly, and not via // exposed parentchain_api let mut subscription = parentchain_handler @@ -1063,7 +1162,7 @@ fn enclave_account(enclave_api: &E) -> AccountId32 { /// Checks if we are the first validateer to register on the parentchain. fn we_are_primary_worker( - node_api: &ParentchainApi, + node_api: &IntegriteeParentchainApi, shard: &ShardIdentifier, enclave_account: &AccountId32, ) -> Result { diff --git a/service/src/ocall_bridge/component_factory.rs b/service/src/ocall_bridge/component_factory.rs index 12631a42a5..869f7bdea4 100644 --- a/service/src/ocall_bridge/component_factory.rs +++ b/service/src/ocall_bridge/component_factory.rs @@ -29,22 +29,26 @@ use crate::{ sidechain_ocall::SidechainOCall, worker_on_chain_ocall::WorkerOnChainOCall, }, + parentchain_config::{ + IntegriteeParentchainApiWrapper, TargetAParentchainApiWrapper, TargetBParentchainApiWrapper, + }, prometheus_metrics::ReceiveEnclaveMetrics, sync_block_broadcaster::BroadcastBlocks, worker_peers_updater::UpdateWorkerPeers, }; use itp_enclave_api::remote_attestation::RemoteAttestationCallBacks; -use itp_node_api::node_api_factory::CreateNodeApi; +use itp_node_api::node_api_factory::{CreateNodeApi, NodeApiFactory}; +use itp_types::parentchain::Hash; use its_peer_fetch::FetchBlocksFromPeer; use its_primitives::types::block::SignedBlock as SignedSidechainBlock; use its_storage::BlockStorage; use std::sync::Arc; +use substrate_api_client::{GetStorage, SubmitAndWatch, SubmitExtrinsic}; /// Concrete implementation, should be moved out of the OCall Bridge, into the worker /// since the OCall bridge itself should not know any concrete types to ensure /// our dependency graph is worker -> ocall bridge pub struct OCallBridgeComponentFactory< - NodeApi, Broadcaster, EnclaveApi, Storage, @@ -53,9 +57,9 @@ pub struct OCallBridgeComponentFactory< TokioHandle, MetricsReceiver, > { - integritee_rpc_api_factory: Arc, - target_a_parentchain_rpc_api_factory: Option>, - target_b_parentchain_rpc_api_factory: Option>, + integritee_rpc_api_factory: Arc>, + target_a_parentchain_rpc_api_factory: Option>>, + target_b_parentchain_rpc_api_factory: Option>>, block_broadcaster: Arc, enclave_api: Arc, block_storage: Arc, @@ -66,7 +70,6 @@ pub struct OCallBridgeComponentFactory< } impl< - NodeApi, Broadcaster, EnclaveApi, Storage, @@ -76,7 +79,6 @@ impl< MetricsReceiver, > OCallBridgeComponentFactory< - NodeApi, Broadcaster, EnclaveApi, Storage, @@ -88,9 +90,13 @@ impl< { #[allow(clippy::too_many_arguments)] pub fn new( - integritee_rpc_api_factory: Arc, - target_a_parentchain_rpc_api_factory: Option>, - target_b_parentchain_rpc_api_factory: Option>, + integritee_rpc_api_factory: Arc>, + target_a_parentchain_rpc_api_factory: Option< + Arc>, + >, + target_b_parentchain_rpc_api_factory: Option< + Arc>, + >, block_broadcaster: Arc, enclave_api: Arc, block_storage: Arc, @@ -115,7 +121,6 @@ impl< } impl< - NodeApi, Broadcaster, EnclaveApi, Storage, @@ -125,7 +130,6 @@ impl< MetricsReceiver, > GetOCallBridgeComponents for OCallBridgeComponentFactory< - NodeApi, Broadcaster, EnclaveApi, Storage, @@ -134,7 +138,6 @@ impl< TokioHandle, MetricsReceiver, > where - NodeApi: CreateNodeApi + 'static, Broadcaster: BroadcastBlocks + 'static, EnclaveApi: RemoteAttestationCallBacks + 'static, Storage: BlockStorage + 'static, diff --git a/service/src/ocall_bridge/worker_on_chain_ocall.rs b/service/src/ocall_bridge/worker_on_chain_ocall.rs index f322c6337f..6fc667c7aa 100644 --- a/service/src/ocall_bridge/worker_on_chain_ocall.rs +++ b/service/src/ocall_bridge/worker_on_chain_ocall.rs @@ -16,11 +16,20 @@ */ -use crate::ocall_bridge::bridge_api::{OCallBridgeError, OCallBridgeResult, WorkerOnChainBridge}; +use crate::{ + ocall_bridge::bridge_api::{OCallBridgeError, OCallBridgeResult, WorkerOnChainBridge}, + parentchain_config::{ + IntegriteeParentchainApi, IntegriteeParentchainApiWrapper, ParentchainApiLocal, + TargetAParentchainApi, TargetAParentchainApiWrapper, TargetBParentchainApi, + TargetBParentchainApiWrapper, + }, +}; use codec::{Decode, Encode}; -use itp_api_client_types::ParentchainApi; -use itp_node_api::node_api_factory::CreateNodeApi; -use itp_types::{parentchain::ParentchainId, WorkerRequest, WorkerResponse}; +use itp_node_api::node_api_factory::{CreateNodeApi, NodeApiFactory}; +use itp_types::{ + parentchain::{Hash, ParentchainId}, + WorkerRequest, WorkerResponse, +}; use log::*; use sp_runtime::OpaqueExtrinsic; use std::{sync::Arc, vec::Vec}; @@ -28,17 +37,17 @@ use substrate_api_client::{ ac_primitives::serde_impls::StorageKey, GetStorage, SubmitAndWatch, SubmitExtrinsic, XtStatus, }; -pub struct WorkerOnChainOCall { - integritee_api_factory: Arc, - target_a_parentchain_api_factory: Option>, - target_b_parentchain_api_factory: Option>, +pub struct WorkerOnChainOCall { + integritee_api_factory: Arc>, + target_a_parentchain_api_factory: Option>>, + target_b_parentchain_api_factory: Option>>, } -impl WorkerOnChainOCall { +impl WorkerOnChainOCall { pub fn new( - integritee_api_factory: Arc, - target_a_parentchain_api_factory: Option>, - target_b_parentchain_api_factory: Option>, + integritee_api_factory: Arc>, + target_a_parentchain_api_factory: Option>>, + target_b_parentchain_api_factory: Option>>, ) -> Self { WorkerOnChainOCall { integritee_api_factory, @@ -48,28 +57,31 @@ impl WorkerOnChainOCall { } } -impl WorkerOnChainOCall { - pub fn create_api(&self, parentchain_id: ParentchainId) -> OCallBridgeResult { +impl WorkerOnChainOCall { + pub fn create_api( + &self, + parentchain_id: ParentchainId, + ) -> OCallBridgeResult { Ok(match parentchain_id { - ParentchainId::Integritee => self.integritee_api_factory.create_api()?, - ParentchainId::TargetA => self - .target_a_parentchain_api_factory - .as_ref() - .ok_or(OCallBridgeError::TargetAParentchainNotInitialized) - .and_then(|f| f.create_api().map_err(Into::into))?, - ParentchainId::TargetB => self - .target_b_parentchain_api_factory - .as_ref() - .ok_or(OCallBridgeError::TargetBParentchainNotInitialized) - .and_then(|f| f.create_api().map_err(Into::into))?, + ParentchainId::Integritee => + ParentchainApiLocal::Integritee(self.integritee_api_factory.create_api()?), + ParentchainId::TargetA => ParentchainApiLocal::TargetA( + self.target_a_parentchain_api_factory + .as_ref() + .ok_or(OCallBridgeError::TargetAParentchainNotInitialized) + .and_then(|f| f.create_api().map_err(Into::into))?, + ), + ParentchainId::TargetB => ParentchainApiLocal::TargetB( + self.target_b_parentchain_api_factory + .as_ref() + .ok_or(OCallBridgeError::TargetBParentchainNotInitialized) + .and_then(|f| f.create_api().map_err(Into::into))?, + ), }) } } -impl WorkerOnChainBridge for WorkerOnChainOCall -where - F: CreateNodeApi, -{ +impl WorkerOnChainBridge for WorkerOnChainOCall { fn worker_request( &self, request: Vec, diff --git a/service/src/parentchain_config.rs b/service/src/parentchain_config.rs new file mode 100644 index 0000000000..03aa855655 --- /dev/null +++ b/service/src/parentchain_config.rs @@ -0,0 +1,140 @@ +/* + Copyright 2021 Integritee AG + Copyright (C) 2017-2019 Baidu, Inc. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ +use ita_parentchain_interface::{integritee, target_a, target_b}; +use itc_parentchain::primitives::ParentchainId; +use itp_node_api::{ + api_client::{Api, ApiClientError, ApiResult, AssetRuntimeConfig, StorageKey}, + node_api_factory::{NodeApiFactory, NodeApiFactoryError, ParentchainApiWrapper}, +}; +use itp_types::parentchain::Hash; +use sp_core::sr25519; +use substrate_api_client::{ + ac_primitives::{Bytes, WithExtrinsicParams}, + rpc::{Request, TungsteniteRpcClient}, + ExtrinsicReport, GetStorage, ReadProof, SubmitAndWatch, SubmitExtrinsic, XtStatus, +}; + +/// Standard runtime config for Substrate and Polkadot nodes. +pub type IntegriteeRuntimeConfig = + WithExtrinsicParams; + +/// runtime config for chains like Asset Hub or Encointer +pub type TargetARuntimeConfig = + WithExtrinsicParams; + +/// Standard runtime config for Substrate and Polkadot nodes. +pub type TargetBRuntimeConfig = + WithExtrinsicParams; + +pub enum ParentchainApiLocal { + Integritee(IntegriteeParentchainApi), + TargetA(TargetAParentchainApi), + TargetB(TargetBParentchainApi), +} + +impl ParentchainApiLocal { + pub fn get_opaque_storage_by_key( + &self, + storage_key: StorageKey, + at_block: Option, + ) -> ApiResult>> { + match self { + Self::Integritee(api) => api.get_opaque_storage_by_key(storage_key, at_block), + Self::TargetA(api) => api.get_opaque_storage_by_key(storage_key, at_block), + Self::TargetB(api) => api.get_opaque_storage_by_key(storage_key, at_block), + } + } + pub fn get_storage_proof_by_keys( + &self, + storage_keys: Vec, + at_block: Option, + ) -> ApiResult>> { + match self { + Self::Integritee(api) => api.get_storage_proof_by_keys(storage_keys, at_block), + Self::TargetA(api) => api.get_storage_proof_by_keys(storage_keys, at_block), + Self::TargetB(api) => api.get_storage_proof_by_keys(storage_keys, at_block), + } + } + pub fn submit_and_watch_opaque_extrinsic_until( + &self, + encoded_extrinsic: &Bytes, + watch_until: XtStatus, + ) -> ApiResult> { + match self { + Self::Integritee(api) => + api.submit_and_watch_opaque_extrinsic_until(encoded_extrinsic, watch_until), + Self::TargetA(api) => + api.submit_and_watch_opaque_extrinsic_until(encoded_extrinsic, watch_until), + Self::TargetB(api) => + api.submit_and_watch_opaque_extrinsic_until(encoded_extrinsic, watch_until), + } + } + pub fn submit_opaque_extrinsic(&self, encoded_extrinsic: &Bytes) -> ApiResult { + match self { + Self::Integritee(api) => api.submit_opaque_extrinsic(encoded_extrinsic), + Self::TargetA(api) => api.submit_opaque_extrinsic(encoded_extrinsic), + Self::TargetB(api) => api.submit_opaque_extrinsic(encoded_extrinsic), + } + } +} + +pub type IntegriteeParentchainApi = Api; +pub type TargetAParentchainApi = Api; +pub type TargetBParentchainApi = Api; + +pub struct IntegriteeParentchainApiWrapper(Api); + +// fixme: this is an ugly hack because api-client's 'new()' isn't part of any trait we could implement therefore we can't use the fn new() on generic api types +impl ParentchainApiWrapper for IntegriteeParentchainApiWrapper { + type Api = IntegriteeParentchainApi; + type Client = TungsteniteRpcClient; + fn new_api( + client: Self::Client, + signer: sr25519::Pair, + ) -> Result { + let mut api = Self::Api::new(client).map_err(NodeApiFactoryError::FailedToCreateNodeApi)?; + api.set_signer(signer.into()); + Ok(api) + } +} +pub struct TargetAParentchainApiWrapper(Api); +impl ParentchainApiWrapper for TargetAParentchainApiWrapper { + type Api = TargetAParentchainApi; + type Client = TungsteniteRpcClient; + fn new_api( + client: Self::Client, + signer: sr25519::Pair, + ) -> Result { + let mut api = Self::Api::new(client).map_err(NodeApiFactoryError::FailedToCreateNodeApi)?; + api.set_signer(signer.into()); + Ok(api) + } +} +pub struct TargetBParentchainApiWrapper(Api); +impl ParentchainApiWrapper for TargetBParentchainApiWrapper { + type Api = TargetBParentchainApi; + type Client = TungsteniteRpcClient; + fn new_api( + client: Self::Client, + signer: sr25519::Pair, + ) -> Result { + let mut api = Self::Api::new(client).map_err(NodeApiFactoryError::FailedToCreateNodeApi)?; + api.set_signer(signer.into()); + Ok(api) + } +} diff --git a/service/src/parentchain_handler.rs b/service/src/parentchain_handler.rs index f27b603337..9aba1968d9 100644 --- a/service/src/parentchain_handler.rs +++ b/service/src/parentchain_handler.rs @@ -16,13 +16,15 @@ */ -use crate::error::{Error, ServiceResult}; +use crate::{ + error::{Error, ServiceResult}, + parentchain_config::IntegriteeParentchainApi, +}; use codec::{Decode, Encode}; use itc_parentchain::{ light_client::light_client_init_params::{GrandpaParams, SimpleParams}, primitives::{ParentchainId, ParentchainInitParams}, }; -use itp_api_client_types::ParentchainApi; use itp_enclave_api::{enclave_base::EnclaveBase, sidechain::Sidechain}; use itp_node_api::api_client::ChainApi; use itp_storage::StorageProof; @@ -65,12 +67,12 @@ pub(crate) struct ParentchainHandler { // #TODO: #1451: Reintroduce `ParentchainApi: ChainApi` once there is no trait bound conflict // any more with the api-clients own trait definitions. -impl ParentchainHandler +impl ParentchainHandler where EnclaveApi: EnclaveBase, { pub fn new( - parentchain_api: ParentchainApi, + parentchain_api: IntegriteeParentchainApi, enclave_api: Arc, parentchain_init_params: ParentchainInitParams, ) -> Self { @@ -79,7 +81,7 @@ where // FIXME: Necessary in the future? Fix with #1080 pub fn new_with_automatic_light_client_allocation( - parentchain_api: ParentchainApi, + parentchain_api: IntegriteeParentchainApi, enclave_api: Arc, id: ParentchainId, ) -> ServiceResult { @@ -121,7 +123,7 @@ where Ok(Self::new(parentchain_api, enclave_api, parentchain_init_params)) } - pub fn parentchain_api(&self) -> &ParentchainApi { + pub fn parentchain_api(&self) -> &IntegriteeParentchainApi { &self.parentchain_api } @@ -130,7 +132,7 @@ where } } -impl HandleParentchain for ParentchainHandler +impl HandleParentchain for ParentchainHandler where EnclaveApi: Sidechain + EnclaveBase, { diff --git a/sidechain/consensus/common/src/block_import_confirmation_handler.rs b/sidechain/consensus/common/src/block_import_confirmation_handler.rs index be93feb51c..a4bbbf33a1 100644 --- a/sidechain/consensus/common/src/block_import_confirmation_handler.rs +++ b/sidechain/consensus/common/src/block_import_confirmation_handler.rs @@ -117,7 +117,7 @@ impl< let xts = self .extrinsics_factory - .create_extrinsics(&[opaque_call], None) + .create_extrinsics(&[opaque_call]) .map_err(|e| Error::Other(e.into()))?; debug!("Sending sidechain block import confirmation extrinsic..");