diff --git a/Cargo.lock b/Cargo.lock index 0f2d80d4f3..fdc2aa9855 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2794,6 +2794,7 @@ dependencies = [ "sgx_tstd", "sp-core", "sp-runtime", + "sp-version", "substrate-api-client", ] @@ -3267,6 +3268,7 @@ dependencies = [ "itp-node-api", "itp-nonce-cache", "itp-types", + "log 0.4.22", "parity-scale-codec", "sgx_tstd", "sgx_types", diff --git a/app-libs/parentchain-interface/Cargo.toml b/app-libs/parentchain-interface/Cargo.toml index 547db7dbf8..2ac630a82a 100644 --- a/app-libs/parentchain-interface/Cargo.toml +++ b/app-libs/parentchain-interface/Cargo.toml @@ -25,11 +25,12 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = log = { version = "0.4", default-features = false } regex = { optional = true, version = "1.9.5" } -substrate-api-client = { optional = true, default-features = false, features = ["std", "sync-api"], git = "https://github.com/encointer/substrate-api-client.git", branch = "v0.9.42-tag-v0.14.0-retracted-check-metadata-hash" } +substrate-api-client = { default-features = false, git = "https://github.com/encointer/substrate-api-client.git", branch = "v0.9.42-tag-v0.14.0-retracted-check-metadata-hash" } # substrate dep 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" } +sp-version = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } [dev-dependencies] env_logger = "0.9.0" @@ -62,7 +63,8 @@ std = [ "regex", "sp-core/std", "sp-runtime/std", - "substrate-api-client", + "substrate-api-client/std", + "substrate-api-client/sync-api", ] sgx = [ "sgx_tstd", diff --git a/app-libs/parentchain-interface/src/event_subscriber.rs b/app-libs/parentchain-interface/src/event_subscriber.rs index c4f662c28e..c5de86d700 100644 --- a/app-libs/parentchain-interface/src/event_subscriber.rs +++ b/app-libs/parentchain-interface/src/event_subscriber.rs @@ -17,13 +17,23 @@ extern crate alloc; use alloc::sync::Arc; use core::sync::atomic::{AtomicBool, Ordering}; -use itp_api_client_types::ParentchainApi; -use itp_types::parentchain::{AddedSgxEnclave, BalanceTransfer, ExtrinsicFailed, ParentchainId}; +use itp_node_api::api_client::AccountApi; +use itp_types::parentchain::{ + AddedSgxEnclave, BalanceTransfer, BlockNumber, ExtrinsicFailed, Hash, ParentchainId, +}; use log::{debug, warn}; +use sp_core::crypto::AccountId32; use sp_runtime::DispatchError; -use substrate_api_client::{ac_primitives::Header, GetChainInfo, SubscribeEvents}; +use substrate_api_client::{ + ac_primitives::{BlakeTwo256, Header, SubstrateHeader}, + GetChainInfo, SubscribeEvents, +}; -pub fn subscribe_to_parentchain_events( +pub fn subscribe_to_parentchain_events< + ParentchainApi: AccountApi + + SubscribeEvents + + GetChainInfo
>, +>( api: &ParentchainApi, parentchain_id: ParentchainId, shutdown_flag: Arc, diff --git a/app-libs/parentchain-interface/src/integritee/api_client_types.rs b/app-libs/parentchain-interface/src/integritee/api_client_types.rs new file mode 100644 index 0000000000..fd33738fb5 --- /dev/null +++ b/app-libs/parentchain-interface/src/integritee/api_client_types.rs @@ -0,0 +1,66 @@ +/* + Copyright 2021 Integritee AG and Supercomputing Systems AG + + 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. + +*/ + +//! Contains semi-generic type definitions to talk to the node without depending on an implementation of Runtime. +//! +//! You need to update this if you have a signed extension in your node that +//! is different from the integritee-node, e.g., if you use the `pallet_asset_tx_payment`. + +use crate::{ + GenericAdditionalParams, GenericExtrinsicParams, GenericSignedExtra, ParentchainRuntimeConfig, + PlainTip, UncheckedExtrinsicV4, +}; +use itp_types::parentchain::Header; +pub use itp_types::parentchain::{ + AccountData, AccountId, AccountInfo, Address, Balance, Hash, Index, Signature as PairSignature, +}; +use sp_runtime::generic; + +pub type IntegriteeRuntimeConfig = ParentchainRuntimeConfig; + +// Configuration for the ExtrinsicParams. +pub type IntegriteeTip = PlainTip; +pub type IntegriteeExtrinsicParams = GenericExtrinsicParams; +pub type IntegriteeAdditionalParams = GenericAdditionalParams; + +pub type IntegriteeSignedExtra = GenericSignedExtra; +pub type IntegriteeSignature = Signature; + +pub type IntegriteeUncheckedExtrinsic = + UncheckedExtrinsicV4; + +/// Signature type of the [UncheckedExtrinsicV4]. +pub type Signature = Option<(Address, PairSignature, SignedExtra)>; + +pub type Block = generic::Block>; + +#[cfg(feature = "std")] +pub use api::*; + +#[cfg(feature = "std")] +mod api { + use crate::ParentchainRuntimeConfig; + use itp_api_client_types::PlainTip; + use itp_types::parentchain::Balance; + pub use substrate_api_client::{ + api::Error as ApiClientError, + rpc::{tungstenite_client::TungsteniteRpcClient, Error as RpcClientError}, + Api, + }; + + pub type IntegriteeApi = Api>, TungsteniteRpcClient>; +} diff --git a/app-libs/parentchain-interface/src/integritee/api_factory.rs b/app-libs/parentchain-interface/src/integritee/api_factory.rs new file mode 100644 index 0000000000..325551da3e --- /dev/null +++ b/app-libs/parentchain-interface/src/integritee/api_factory.rs @@ -0,0 +1,49 @@ +/* + Copyright 2021 Integritee AG and Supercomputing Systems 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 super::api_client_types::IntegriteeTip; +use crate::ParentchainRuntimeConfig; +use itp_api_client_types::{Api, TungsteniteRpcClient}; +use itp_node_api::node_api_factory::{CreateNodeApi, NodeApiFactoryError, Result}; +use sp_core::sr25519; + +/// Node API factory implementation. +pub struct IntegriteeNodeApiFactory { + node_url: String, + signer: sr25519::Pair, +} + +impl IntegriteeNodeApiFactory { + pub fn new(url: String, signer: sr25519::Pair) -> Self { + Self { node_url: url, signer } + } +} + +impl CreateNodeApi, TungsteniteRpcClient> + for IntegriteeNodeApiFactory +{ + fn create_api( + &self, + ) -> Result, TungsteniteRpcClient>> { + let rpc_client = TungsteniteRpcClient::new(self.node_url.as_str(), 5) + .map_err(NodeApiFactoryError::FailedToCreateRpcClient)?; + let mut api = Api::new(rpc_client).map_err(NodeApiFactoryError::FailedToCreateNodeApi)?; + api.set_signer(self.signer.clone().into()); + Ok(api) + } +} diff --git a/app-libs/parentchain-interface/src/integritee/mod.rs b/app-libs/parentchain-interface/src/integritee/mod.rs index 00c350cf20..3859a7808f 100644 --- a/app-libs/parentchain-interface/src/integritee/mod.rs +++ b/app-libs/parentchain-interface/src/integritee/mod.rs @@ -15,6 +15,9 @@ */ +pub mod api_client_types; +#[cfg(feature = "std")] +pub mod api_factory; mod event_filter; mod event_handler; diff --git a/app-libs/parentchain-interface/src/lib.rs b/app-libs/parentchain-interface/src/lib.rs index e2e0582bf7..ac33abd913 100644 --- a/app-libs/parentchain-interface/src/lib.rs +++ b/app-libs/parentchain-interface/src/lib.rs @@ -22,6 +22,31 @@ extern crate sgx_tstd as std; use codec::{Decode, Encode}; +use core::{fmt::Debug, marker::PhantomData}; +use itp_types::parentchain::Hash; +use sp_core::{crypto::AccountId32, sr25519}; +use sp_runtime::{MultiAddress, MultiSignature}; +use substrate_api_client::ac_primitives::{ + BlakeTwo256, ExtrinsicSigner, SubstrateBlock, SubstrateHeader, SubstrateOpaqueExtrinsic, +}; + +pub use substrate_api_client::{ + ac_node_api::{ + metadata::{InvalidMetadataError, Metadata, MetadataError}, + EventDetails, Events, StaticEvent, + }, + ac_primitives::{ + config::Config, + extrinsics::{ + AssetTip, CallIndex, ExtrinsicParams, GenericAdditionalParams, GenericAdditionalSigned, + GenericExtrinsicParams, GenericSignedExtra, PlainTip, UncheckedExtrinsicV4, + }, + serde_impls::StorageKey, + signer::{SignExtrinsic, StaticExtrinsicSigner}, + }, + rpc::Request, + storage_key, Api, +}; #[cfg(feature = "std")] pub mod event_subscriber; @@ -54,3 +79,34 @@ pub fn decode_and_log_error(encoded: &mut &[u8]) -> Option { }, } } + +/// Config matching the specs of the typical polkadot chains. +/// We can define some more if we realize that we need more +/// granular control than the tip. +#[derive(Decode, Encode, Clone, Eq, PartialEq, Debug)] +pub struct ParentchainRuntimeConfig { + _phantom: PhantomData, +} + +impl Config for ParentchainRuntimeConfig +where + u128: From, + Tip: Copy + Default + Encode + Debug, +{ + type Index = u32; + type BlockNumber = u32; + type Hash = Hash; + type AccountId = AccountId32; + type Address = MultiAddress; + type Signature = MultiSignature; + type Hasher = BlakeTwo256; + type Header = SubstrateHeader; + type AccountData = itp_types::AccountData; + type ExtrinsicParams = GenericExtrinsicParams; + type CryptoKey = sr25519::Pair; + type ExtrinsicSigner = ExtrinsicSigner; + type Block = SubstrateBlock; + type Balance = itp_types::Balance; + type ContractCurrency = u128; + type StakingBalance = u128; +} diff --git a/app-libs/parentchain-interface/src/target_a/api_client_types.rs b/app-libs/parentchain-interface/src/target_a/api_client_types.rs new file mode 100644 index 0000000000..259c4ff118 --- /dev/null +++ b/app-libs/parentchain-interface/src/target_a/api_client_types.rs @@ -0,0 +1,64 @@ +/* + Copyright 2021 Integritee AG and Supercomputing Systems AG + + 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. + +*/ + +//! Contains semi-generic type definitions to talk to the node without depending on an implementation of Runtime. +//! +//! You need to update this if you have a signed extension in your node that +//! is different from the integritee-node, e.g., if you use the `pallet_asset_tx_payment`. + +use crate::{ + GenericAdditionalParams, GenericExtrinsicParams, GenericSignedExtra, ParentchainRuntimeConfig, + PlainTip, UncheckedExtrinsicV4, +}; +pub use itp_types::parentchain::{ + AccountData, AccountId, AccountInfo, Address, Balance, Hash, Index, Signature as PairSignature, +}; + +pub type TargetARuntimeConfig = ParentchainRuntimeConfig; + +// Configuration for the ExtrinsicParams. + +pub type TargetATip = PlainTip; +pub type TargetAExtrinsicParams = GenericExtrinsicParams; +pub type TargetAAdditionalParams = GenericAdditionalParams; + +pub type TargetASignedExtra = GenericSignedExtra; +pub type TargetASignature = Signature; + +pub type TargetAUncheckedExtrinsic = + UncheckedExtrinsicV4; + +/// Signature type of the [UncheckedExtrinsicV4]. +pub type Signature = Option<(Address, PairSignature, SignedExtra)>; + +#[cfg(feature = "std")] +pub use api::*; + +#[cfg(feature = "std")] +mod api { + use crate::ParentchainRuntimeConfig; + use itp_api_client_types::PlainTip; + use itp_types::parentchain::Balance; + pub use substrate_api_client::{ + api::Error as ApiClientError, + rpc::{tungstenite_client::TungsteniteRpcClient, Error as RpcClientError}, + Api, + }; + + pub type TargetANodeConfig = ParentchainRuntimeConfig>; + pub type TargetAApi = Api; +} diff --git a/app-libs/parentchain-interface/src/target_a/api_factory.rs b/app-libs/parentchain-interface/src/target_a/api_factory.rs new file mode 100644 index 0000000000..3871003124 --- /dev/null +++ b/app-libs/parentchain-interface/src/target_a/api_factory.rs @@ -0,0 +1,49 @@ +/* + Copyright 2021 Integritee AG and Supercomputing Systems 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 super::api_client_types::TargetATip; +use crate::ParentchainRuntimeConfig; +use itp_api_client_types::{Api, TungsteniteRpcClient}; +use itp_node_api::node_api_factory::{CreateNodeApi, NodeApiFactoryError, Result}; +use sp_core::sr25519; + +/// Node API factory implementation. +pub struct TargetANodeApiFactory { + node_url: String, + signer: sr25519::Pair, +} + +impl TargetANodeApiFactory { + pub fn new(url: String, signer: sr25519::Pair) -> Self { + Self { node_url: url, signer } + } +} + +impl CreateNodeApi, TungsteniteRpcClient> + for TargetANodeApiFactory +{ + fn create_api( + &self, + ) -> Result, TungsteniteRpcClient>> { + let rpc_client = TungsteniteRpcClient::new(self.node_url.as_str(), 5) + .map_err(NodeApiFactoryError::FailedToCreateRpcClient)?; + let mut api = Api::new(rpc_client).map_err(NodeApiFactoryError::FailedToCreateNodeApi)?; + api.set_signer(self.signer.clone().into()); + Ok(api) + } +} diff --git a/app-libs/parentchain-interface/src/target_a/mod.rs b/app-libs/parentchain-interface/src/target_a/mod.rs index d8d804d42f..ee7df47e30 100644 --- a/app-libs/parentchain-interface/src/target_a/mod.rs +++ b/app-libs/parentchain-interface/src/target_a/mod.rs @@ -14,6 +14,10 @@ limitations under the License. */ + +pub mod api_client_types; +#[cfg(feature = "std")] +pub mod api_factory; mod event_filter; mod event_handler; @@ -23,6 +27,7 @@ use crate::{ indirect_calls::timestamp_set::TimestampSetArgs, TargetA, }; +use api_client_types::TargetASignedExtra; use codec::{Decode, Encode}; pub use event_filter::FilterableEvents; pub use event_handler::ParentchainEventHandler; @@ -32,13 +37,12 @@ use itc_parentchain_indirect_calls_executor::{ filter_metadata::FilterIntoDataFrom, IndirectDispatch, }; -use itp_api_client_types::ParentchainSignedExtra; use itp_node_api::metadata::pallet_timestamp::TimestampCallIndexes; use itp_stf_primitives::traits::IndirectExecutor; use log::*; /// Parses the extrinsics corresponding to the parentchain. -pub type ParentchainExtrinsicParser = ExtrinsicParser; +pub type TargetAExtrinsicParser = ExtrinsicParser; /// The default indirect call (extrinsic-triggered) of the Target-A-Parachain. #[derive(Debug, Clone, Encode, Decode, Eq, PartialEq)] @@ -61,7 +65,7 @@ pub struct ExtrinsicFilter {} impl FilterIntoDataFrom for ExtrinsicFilter { type Output = IndirectCall; - type ParseParentchainMetadata = ParentchainExtrinsicParser; + type ParseParentchainMetadata = TargetAExtrinsicParser; fn filter_into_from_metadata( encoded_data: &[u8], diff --git a/app-libs/parentchain-interface/src/target_b/api_client_types.rs b/app-libs/parentchain-interface/src/target_b/api_client_types.rs new file mode 100644 index 0000000000..414b6211c6 --- /dev/null +++ b/app-libs/parentchain-interface/src/target_b/api_client_types.rs @@ -0,0 +1,62 @@ +/* + Copyright 2021 Integritee AG and Supercomputing Systems AG + + 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. + +*/ + +//! Contains semi-generic type definitions to talk to the node without depending on an implementation of Runtime. +//! +//! You need to update this if you have a signed extension in your node that +//! is different from the integritee-node, e.g., if you use the `pallet_asset_tx_payment`. + +use crate::{ + AssetTip, GenericAdditionalParams, GenericExtrinsicParams, GenericSignedExtra, + ParentchainRuntimeConfig, UncheckedExtrinsicV4, +}; +pub use itp_types::parentchain::{ + AccountData, AccountId, AccountInfo, Address, Balance, Hash, Index, Signature as PairSignature, +}; + +pub type TargetBRuntimeConfig = ParentchainRuntimeConfig; + +// Configuration for the ExtrinsicParams. + +// Using the AssetTip, as we assume that TargetB uses the `pallet_asset_tx_payment`. +pub type TargetBTip = AssetTip; +pub type TargetBExtrinsicParams = GenericExtrinsicParams; +pub type TargetBAdditionalParams = GenericAdditionalParams; + +pub type TargetBSignedExtra = GenericSignedExtra; +pub type TargetBSignature = Signature; + +pub type TargetBUncheckedExtrinsic = + UncheckedExtrinsicV4; + +/// Signature type of the [UncheckedExtrinsicV4]. +pub type Signature = Option<(Address, PairSignature, SignedExtra)>; + +#[cfg(feature = "std")] +pub use api::*; + +#[cfg(feature = "std")] +mod api { + use super::TargetBRuntimeConfig; + use substrate_api_client::Api; + pub use substrate_api_client::{ + api::Error as ApiClientError, + rpc::{tungstenite_client::TungsteniteRpcClient, Error as RpcClientError}, + }; + + pub type TargetBApi = Api; +} diff --git a/app-libs/parentchain-interface/src/target_b/api_factory.rs b/app-libs/parentchain-interface/src/target_b/api_factory.rs new file mode 100644 index 0000000000..90e75bfdd2 --- /dev/null +++ b/app-libs/parentchain-interface/src/target_b/api_factory.rs @@ -0,0 +1,49 @@ +/* + Copyright 2021 Integritee AG and Supercomputing Systems 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 super::api_client_types::TargetBTip; +use crate::ParentchainRuntimeConfig; +use itp_api_client_types::{Api, TungsteniteRpcClient}; +use itp_node_api::node_api_factory::{CreateNodeApi, NodeApiFactoryError, Result}; +use sp_core::sr25519; + +/// Node API factory implementation. +pub struct TargetBNodeApiFactory { + node_url: String, + signer: sr25519::Pair, +} + +impl TargetBNodeApiFactory { + pub fn new(url: String, signer: sr25519::Pair) -> Self { + Self { node_url: url, signer } + } +} + +impl CreateNodeApi, TungsteniteRpcClient> + for TargetBNodeApiFactory +{ + fn create_api( + &self, + ) -> Result, TungsteniteRpcClient>> { + let rpc_client = TungsteniteRpcClient::new(self.node_url.as_str(), 5) + .map_err(NodeApiFactoryError::FailedToCreateRpcClient)?; + let mut api = Api::new(rpc_client).map_err(NodeApiFactoryError::FailedToCreateNodeApi)?; + api.set_signer(self.signer.clone().into()); + Ok(api) + } +} diff --git a/app-libs/parentchain-interface/src/target_b/event_handler.rs b/app-libs/parentchain-interface/src/target_b/event_handler.rs index b4218eb9e5..ace4fedc7a 100644 --- a/app-libs/parentchain-interface/src/target_b/event_handler.rs +++ b/app-libs/parentchain-interface/src/target_b/event_handler.rs @@ -14,10 +14,8 @@ limitations under the License. */ - use codec::Encode; -pub use ita_sgx_runtime::{Balance, Index}; - +use ita_sgx_runtime::Balance; use ita_stf::{Getter, TrustedCall, TrustedCallSigned}; use itc_parentchain_indirect_calls_executor::error::Error; use itp_stf_primitives::{traits::IndirectExecutor, types::TrustedOperation}; diff --git a/app-libs/parentchain-interface/src/target_b/mod.rs b/app-libs/parentchain-interface/src/target_b/mod.rs index c21bbe6654..e4eeeb4ade 100644 --- a/app-libs/parentchain-interface/src/target_b/mod.rs +++ b/app-libs/parentchain-interface/src/target_b/mod.rs @@ -15,6 +15,9 @@ */ +pub mod api_client_types; +#[cfg(feature = "std")] +pub mod api_factory; mod event_filter; mod event_handler; @@ -24,6 +27,7 @@ use crate::{ indirect_calls::timestamp_set::TimestampSetArgs, TargetB, }; +use api_client_types::TargetBSignedExtra; use codec::{Decode, Encode}; pub use event_filter::FilterableEvents; pub use event_handler::ParentchainEventHandler; @@ -33,13 +37,12 @@ use itc_parentchain_indirect_calls_executor::{ filter_metadata::FilterIntoDataFrom, IndirectDispatch, }; -use itp_api_client_types::ParentchainSignedExtra; use itp_node_api::metadata::pallet_timestamp::TimestampCallIndexes; use itp_stf_primitives::traits::IndirectExecutor; use log::*; /// Parses the extrinsics corresponding to the parentchain. -pub type ParentchainExtrinsicParser = ExtrinsicParser; +pub type TargetBExtrinsicParser = ExtrinsicParser; /// The default indirect call (extrinsic-triggered) of the Target-A-Parachain. #[derive(Debug, Clone, Encode, Decode, Eq, PartialEq)] @@ -62,7 +65,7 @@ pub struct ExtrinsicFilter {} impl FilterIntoDataFrom for ExtrinsicFilter { type Output = IndirectCall; - type ParseParentchainMetadata = ParentchainExtrinsicParser; + type ParseParentchainMetadata = TargetBExtrinsicParser; fn filter_into_from_metadata( encoded_data: &[u8], diff --git a/cli/src/base_cli/commands/balance.rs b/cli/src/base_cli/commands/balance.rs index fe55bb24ad..8457f5978a 100644 --- a/cli/src/base_cli/commands/balance.rs +++ b/cli/src/base_cli/commands/balance.rs @@ -19,7 +19,7 @@ use crate::{ Cli, CliResult, CliResultOk, }; use log::info; -use substrate_api_client::{ac_primitives::AccountData, GetAccountInformation}; +use substrate_api_client::GetAccountInformation; #[derive(Parser)] pub struct BalanceCommand { @@ -31,11 +31,7 @@ impl BalanceCommand { pub(crate) fn run(&self, cli: &Cli) -> CliResult { let api = get_chain_api(cli); let accountid = get_accountid_from_str(&self.account); - let account_data = if let Some(data) = api.get_account_data(&accountid).unwrap() { - data - } else { - AccountData::default() - }; + let account_data = api.get_account_data(&accountid).unwrap().unwrap_or_default(); info!("{:?}", account_data); println!("{}", account_data.free); Ok(CliResultOk::Balance { balance: account_data.free }) diff --git a/cli/src/command_utils.rs b/cli/src/command_utils.rs index f4af81efab..988353e7cf 100644 --- a/cli/src/command_utils.rs +++ b/cli/src/command_utils.rs @@ -18,9 +18,11 @@ use crate::Cli; use base58::FromBase58; use chrono::{DateTime, Local, NaiveDateTime}; -use ita_parentchain_interface::integritee::{AccountId, Signature}; +use ita_parentchain_interface::integritee::{ + api_client_types::IntegriteeApi, AccountId, Signature, +}; use itc_rpc_client::direct_client::{DirectApi, DirectClient as DirectWorkerApi}; -use itp_node_api::api_client::{ParentchainApi, TungsteniteRpcClient}; +use itp_node_api::api_client::TungsteniteRpcClient; use itp_types::Moment; use log::*; use sgx_crypto_helper::rsa3072::Rsa3072PubKey; @@ -39,10 +41,10 @@ pub(crate) fn get_shielding_key(cli: &Cli) -> Result { worker_api_direct.get_rsa_pubkey().map_err(|e| e.to_string()) } -pub(crate) fn get_chain_api(cli: &Cli) -> ParentchainApi { +pub(crate) fn get_chain_api(cli: &Cli) -> IntegriteeApi { let url = format!("{}:{}", cli.node_url, cli.node_port); info!("connecting to {}", url); - ParentchainApi::new(TungsteniteRpcClient::new(&url, 5).unwrap()).unwrap() + IntegriteeApi::new(TungsteniteRpcClient::new(&url, 5).unwrap()).unwrap() } pub(crate) fn get_accountid_from_str(account: &str) -> AccountId { diff --git a/cli/src/oracle/commands/listen_to_exchange.rs b/cli/src/oracle/commands/listen_to_exchange.rs index f301ee9c1b..a794563c27 100644 --- a/cli/src/oracle/commands/listen_to_exchange.rs +++ b/cli/src/oracle/commands/listen_to_exchange.rs @@ -16,7 +16,7 @@ */ use crate::{command_utils::get_chain_api, Cli}; -use itp_node_api::api_client::ParentchainApi; +use ita_parentchain_interface::integritee::api_client_types::IntegriteeApi; use itp_time_utils::{duration_now, remaining_time}; use itp_types::parentchain::ExchangeRateUpdated; use log::*; @@ -42,7 +42,7 @@ impl ListenToExchangeRateEventsCmd { } } -pub fn count_exchange_rate_update_events(api: &ParentchainApi, duration: Duration) -> u32 { +pub fn count_exchange_rate_update_events(api: &IntegriteeApi, duration: Duration) -> u32 { let stop = duration_now() + duration; //subscribe to events diff --git a/cli/src/oracle/commands/listen_to_oracle.rs b/cli/src/oracle/commands/listen_to_oracle.rs index dfbb874356..38096e9810 100644 --- a/cli/src/oracle/commands/listen_to_oracle.rs +++ b/cli/src/oracle/commands/listen_to_oracle.rs @@ -16,7 +16,7 @@ */ use crate::{command_utils::get_chain_api, Cli}; -use itp_node_api::api_client::ParentchainApi; +use ita_parentchain_interface::integritee::api_client_types::IntegriteeApi; use itp_time_utils::{duration_now, remaining_time}; use itp_types::parentchain::OracleUpdated; use log::*; @@ -41,7 +41,7 @@ impl ListenToOracleEventsCmd { } } -fn count_oracle_update_events(api: &ParentchainApi, duration: Duration) -> EventCount { +fn count_oracle_update_events(api: &IntegriteeApi, duration: Duration) -> EventCount { let stop = duration_now() + duration; //subscribe to events diff --git a/core-primitives/extrinsics-factory/Cargo.toml b/core-primitives/extrinsics-factory/Cargo.toml index 03b46495b9..1b3a2eb8d2 100644 --- a/core-primitives/extrinsics-factory/Cargo.toml +++ b/core-primitives/extrinsics-factory/Cargo.toml @@ -5,6 +5,8 @@ authors = ["Integritee AG "] edition = "2021" [dependencies] +log = { version = "0.4", default-features = false } + # sgx dependencies sgx_tstd = { branch = "master", git = "https://github.com/apache/teaclave-sgx-sdk.git", optional = true } sgx_types = { branch = "master", git = "https://github.com/apache/teaclave-sgx-sdk.git" } diff --git a/core-primitives/extrinsics-factory/src/lib.rs b/core-primitives/extrinsics-factory/src/lib.rs index 89b5909a29..4fdd6a46cc 100644 --- a/core-primitives/extrinsics-factory/src/lib.rs +++ b/core-primitives/extrinsics-factory/src/lib.rs @@ -20,6 +20,7 @@ #[cfg(all(feature = "std", feature = "sgx"))] compile_error!("feature \"std\" and feature \"sgx\" cannot be enabled at the same time"); +extern crate core; #[cfg(all(not(feature = "std"), feature = "sgx"))] extern crate sgx_tstd as std; @@ -30,11 +31,10 @@ pub mod sgx_reexport_prelude { } use codec::Encode; +use core::{fmt::Debug, marker::PhantomData}; use error::Result; use itp_node_api::{ - api_client::{ - ExtrinsicParams, ParentchainAdditionalParams, ParentchainExtrinsicParams, SignExtrinsic, - }, + api_client::{ExtrinsicParams, GenericAdditionalParams, GenericExtrinsicParams, SignExtrinsic}, metadata::{provider::AccessNodeMetadata, NodeMetadata}, }; use itp_nonce_cache::{MutateNonce, Nonce}; @@ -45,7 +45,7 @@ use itp_types::{ use sp_core::H256; use sp_runtime::OpaqueExtrinsic; use std::{sync::Arc, vec::Vec}; -use substrate_api_client::ac_compose_macros::compose_extrinsic_offline; +use substrate_api_client::{ac_compose_macros::compose_extrinsic_offline, ac_primitives::Config}; pub mod error; @@ -56,32 +56,33 @@ pub mod mock; /// /// Also increases the nonce counter for each extrinsic that is created. pub trait CreateExtrinsics { + type Config: Config; + type ExtrinsicParams: ExtrinsicParams< + ::Index, + ::Hash, + >; + fn create_extrinsics( &self, calls: &[(OpaqueCall, GenericMortality)], - extrinsics_params: Option, + extrinsics_params: Option>, ) -> Result>; } +pub type AdditionalParamsOf = + ::Index, ::Hash>>::AdditionalParams; + /// Extrinsics factory -pub struct ExtrinsicsFactory -where - Signer: SignExtrinsic, - NonceCache: MutateNonce, - NodeMetadataRepository: AccessNodeMetadata, -{ +pub struct ExtrinsicsFactory { genesis_hash: H256, signer: Signer, nonce_cache: Arc, pub node_metadata_repository: Arc, + _phantom: PhantomData<(NodeRuntimeConfig, Tip)>, } -impl - ExtrinsicsFactory -where - Signer: SignExtrinsic, - NonceCache: MutateNonce, - NodeMetadataRepository: AccessNodeMetadata, +impl + ExtrinsicsFactory { pub fn new( genesis_hash: H256, @@ -89,7 +90,13 @@ where nonce_cache: Arc, node_metadata_repository: Arc, ) -> Self { - ExtrinsicsFactory { genesis_hash, signer, nonce_cache, node_metadata_repository } + ExtrinsicsFactory { + genesis_hash, + signer, + nonce_cache, + node_metadata_repository, + _phantom: Default::default(), + } } pub fn with_signer(&self, signer: Signer, nonce_cache: Arc) -> Self { @@ -98,21 +105,29 @@ where signer, nonce_cache, node_metadata_repository: self.node_metadata_repository.clone(), + _phantom: Default::default(), } } } -impl CreateExtrinsics - for ExtrinsicsFactory +impl CreateExtrinsics + for ExtrinsicsFactory where Signer: SignExtrinsic, NonceCache: MutateNonce, NodeMetadataRepository: AccessNodeMetadata, + NodeRuntimeConfig: Config, + u128: From, + Tip: Copy + Default + Encode + Debug, { + type Config = NodeRuntimeConfig; + + type ExtrinsicParams = GenericExtrinsicParams; + fn create_extrinsics( &self, calls: &[(OpaqueCall, GenericMortality)], - extrinsics_params: Option, + extrinsics_params: Option>, ) -> Result> { let mut nonce_lock = self.nonce_cache.load_for_mutation()?; let mut nonce_value = nonce_lock.0; @@ -126,20 +141,28 @@ where .iter() .map(|(call, mortality)| { let additional_extrinsic_params = extrinsics_params.unwrap_or_else(|| { - ParentchainAdditionalParams::new() - .era( - mortality.era, - mortality.mortality_checkpoint.unwrap_or(self.genesis_hash), - ) - .tip(0) + GenericAdditionalParams::new().era( + mortality.era, + mortality.mortality_checkpoint.unwrap_or(self.genesis_hash), + ) }); - let extrinsic_params = ParentchainExtrinsicParams::new( + let extrinsic_params = GenericExtrinsicParams::::new( runtime_spec_version, runtime_transaction_version, - nonce_value, + nonce_value.into(), self.genesis_hash, additional_extrinsic_params, ); + + log::trace!( + "[ExtrinsicsFactory] SignedExtra: {:?}", + extrinsic_params.signed_extra() + ); + log::trace!( + "[ExtrinsicsFactory] AdditionalParams: {:?}", + extrinsic_params.additional_signed() + ); + let xt = compose_extrinsic_offline!(&self.signer, call, extrinsic_params).encode(); nonce_value += 1; xt @@ -161,18 +184,17 @@ pub mod tests { use super::*; use itp_node_api::{ - api_client::{PairSignature, StaticExtrinsicSigner}, + api_client::{AssetRuntimeConfig, PairSignature, StaticExtrinsicSigner}, metadata::provider::NodeMetadataRepository, }; use itp_nonce_cache::{GetNonce, Nonce, NonceCache, NonceValue}; use sp_core::{ed25519, Pair}; - //use substrate_api_client::extrinsic::xt_primitives::UncheckedExtrinsicV4; #[test] pub fn creating_xts_increases_nonce_for_each_xt() { let nonce_cache = Arc::new(NonceCache::default()); let node_metadata_repo = Arc::new(NodeMetadataRepository::new(NodeMetadata::default())); - let extrinsics_factory = ExtrinsicsFactory::new( + let extrinsics_factory = ExtrinsicsFactory::<_, _, _, AssetRuntimeConfig, u128>::new( test_genesis_hash(), StaticExtrinsicSigner::<_, PairSignature>::new(test_account()), nonce_cache.clone(), @@ -195,7 +217,7 @@ pub mod tests { *nonce_cache1.load_for_mutation().unwrap() = Nonce(42); let node_metadata_repo = Arc::new(NodeMetadataRepository::new(NodeMetadata::default())); - let extrinsics_factory = ExtrinsicsFactory::new( + let extrinsics_factory = ExtrinsicsFactory::<_, _, _, AssetRuntimeConfig, u128>::new( test_genesis_hash(), StaticExtrinsicSigner::<_, PairSignature>::new(test_account()), nonce_cache1.clone(), diff --git a/core-primitives/extrinsics-factory/src/mock.rs b/core-primitives/extrinsics-factory/src/mock.rs index dfa6017a86..840efddf66 100644 --- a/core-primitives/extrinsics-factory/src/mock.rs +++ b/core-primitives/extrinsics-factory/src/mock.rs @@ -14,24 +14,40 @@ limitations under the License. */ - -use crate::{error::Result, CreateExtrinsics}; -use itp_node_api::api_client::ParentchainAdditionalParams; -use itp_types::{parentchain::GenericMortality, OpaqueCall}; +use crate::{error::Result, AdditionalParamsOf, CreateExtrinsics}; +use core::marker::PhantomData; +use itp_types::{parentchain::GenericMortality, Balance, OpaqueCall}; use sp_runtime::OpaqueExtrinsic; use std::vec::Vec; +pub use itp_node_api::api_client::{ + Config, GenericExtrinsicParams, ParentchainRuntimeConfig, PlainTip, +}; + /// Mock of an extrinsics factory. To be used in unit tests. /// /// Returns an empty extrinsic. -#[derive(Default, Clone)] -pub struct ExtrinsicsFactoryMock; +#[derive(Clone)] +pub struct ExtrinsicsFactoryMock { + _phantom: PhantomData, +} + +impl Default for ExtrinsicsFactoryMock { + fn default() -> Self { + Self { _phantom: Default::default() } + } +} + +impl CreateExtrinsics for ExtrinsicsFactoryMock { + type Config = ParentchainRuntimeConfig; + type ExtrinsicParams = GenericExtrinsicParams>; -impl CreateExtrinsics for ExtrinsicsFactoryMock { fn create_extrinsics( &self, _calls: &[(OpaqueCall, GenericMortality)], - _additional_params: Option, + _additional_params: Option< + AdditionalParamsOf, + >, ) -> 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). 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..62f289a3e3 100644 --- a/core-primitives/node-api/api-client-extensions/src/account.rs +++ b/core-primitives/node-api/api-client-extensions/src/account.rs @@ -14,11 +14,8 @@ limitations under the License. */ - use crate::ApiResult; -use itp_api_client_types::{ - traits::GetAccountInformation, Api, Config, ParentchainRuntimeConfig, Request, -}; +use itp_api_client_types::{traits::GetAccountInformation, Api, Config, Request}; /// ApiClient extension that contains some convenience methods around accounts. // Todo: make generic over `Config` type instead? @@ -31,9 +28,11 @@ pub trait AccountApi { fn get_free_balance(&self, who: &Self::AccountId) -> ApiResult; } -impl AccountApi for Api +impl AccountApi for Api where Client: Request, + ParentchainRuntimeConfig: + Config, { type AccountId = ::AccountId; type Index = ::Index; 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 b82b0c376b..acae748757 100644 --- a/core-primitives/node-api/api-client-types/src/lib.rs +++ b/core-primitives/node-api/api-client-types/src/lib.rs @@ -45,7 +45,10 @@ pub use substrate_api_client::{ // traits from the api-client pub mod traits { - pub use substrate_api_client::{GetAccountInformation, GetChainInfo, GetStorage}; + pub use substrate_api_client::{ + rpc::{Request, Subscribe}, + GetAccountInformation, GetChainInfo, GetStorage, + }; } pub type ParentchainPlainTip = PlainTip; @@ -74,17 +77,7 @@ pub type ParentchainSignature = Signature; pub type Signature = Option<(Address, PairSignature, SignedExtra)>; #[cfg(feature = "std")] -pub use api::*; - -#[cfg(feature = "std")] -mod api { - use super::ParentchainRuntimeConfig; - use substrate_api_client::Api; - - pub use substrate_api_client::{ - api::Error as ApiClientError, - rpc::{tungstenite_client::TungsteniteRpcClient, Error as RpcClientError}, - }; - - pub type ParentchainApi = Api; -} +pub use substrate_api_client::{ + api::Error as ApiClientError, + rpc::{tungstenite_client::TungsteniteRpcClient, Error as RpcClientError}, +}; diff --git a/core-primitives/node-api/factory/src/lib.rs b/core-primitives/node-api/factory/src/lib.rs index 2a98e07a1c..69d1d4c907 100644 --- a/core-primitives/node-api/factory/src/lib.rs +++ b/core-primitives/node-api/factory/src/lib.rs @@ -15,13 +15,16 @@ limitations under the License. */ - -use itp_api_client_types::{ParentchainApi, TungsteniteRpcClient}; use sp_core::sr25519; +use std::marker::PhantomData; + +pub use itp_api_client_types::{ + traits::Request, Api, AssetRuntimeConfig, Config, DefaultRuntimeConfig, TungsteniteRpcClient, +}; /// Trait to create a node API, based on a node URL and signer. -pub trait CreateNodeApi { - fn create_api(&self) -> Result; +pub trait CreateNodeApi { + fn create_api(&self) -> Result>; } /// Node API factory error. @@ -50,23 +53,27 @@ impl From for NodeApiFactoryError { pub type Result = std::result::Result; /// Node API factory implementation. -pub struct NodeApiFactory { - node_url: String, +pub struct NodeApiFactory { + pub node_url: String, signer: sr25519::Pair, + _phantom: PhantomData<(NodeConfig, Client)>, } -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 + ::ExtrinsicSigner: From, +{ + 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)?; + let mut api = Api::new(rpc_client).map_err(NodeApiFactoryError::FailedToCreateNodeApi)?; api.set_signer(self.signer.clone().into()); Ok(api) } diff --git a/core-primitives/stf-executor/src/executor.rs b/core-primitives/stf-executor/src/executor.rs index a15a238ea0..e956fd5d7e 100644 --- a/core-primitives/stf-executor/src/executor.rs +++ b/core-primitives/stf-executor/src/executor.rs @@ -208,7 +208,7 @@ where ParentchainId::TargetA => Stf::update_parentchain_target_a_block(&mut state, header.clone()), ParentchainId::TargetB => - Stf::update_parentchain_target_a_block(&mut state, header.clone()), + Stf::update_parentchain_target_b_block(&mut state, header.clone()), }?; self.state_handler.write_after_mutation(state, state_lock, &shard_id)?; } diff --git a/core/offchain-worker-executor/src/executor.rs b/core/offchain-worker-executor/src/executor.rs index f07b2cc33c..4d4f412951 100644 --- a/core/offchain-worker-executor/src/executor.rs +++ b/core/offchain-worker-executor/src/executor.rs @@ -246,7 +246,7 @@ mod tests { use super::*; use codec::{Decode, Encode}; use itc_parentchain_light_client::mocks::validator_access_mock::ValidatorAccessMock; - use itp_extrinsics_factory::mock::ExtrinsicsFactoryMock; + use itp_extrinsics_factory::mock::{ExtrinsicsFactoryMock, ParentchainRuntimeConfig}; use itp_sgx_externalities::SgxExternalitiesTrait; use itp_stf_executor::mocks::StfExecutorMock; @@ -266,7 +266,7 @@ mod tests { type TestTopPoolAuthor = AuthorApiMock; type TestStfExecutor = StfExecutorMock; type TestValidatorAccess = ValidatorAccessMock; - type TestExtrinsicsFactory = ExtrinsicsFactoryMock; + type TestExtrinsicsFactory = ExtrinsicsFactoryMock; type TestExecutor = Executor< ParentchainBlock, TestTopPoolAuthor, diff --git a/core/parentchain/block-importer/src/block_importer.rs b/core/parentchain/block-importer/src/block_importer.rs index f22d06fd59..61696fb88a 100644 --- a/core/parentchain/block-importer/src/block_importer.rs +++ b/core/parentchain/block-importer/src/block_importer.rs @@ -145,6 +145,7 @@ impl< } // check if we can fast-sync + trace!("Shard creation info {:?}", self.shard_creation_info); if let Some(creation_block) = self.shard_creation_info.for_parentchain(id) { if signed_block.block.header().number < creation_block.number { trace!( diff --git a/core/parentchain/indirect-calls-executor/src/executor.rs b/core/parentchain/indirect-calls-executor/src/executor.rs index 23e94baf65..989fba0bd3 100644 --- a/core/parentchain/indirect-calls-executor/src/executor.rs +++ b/core/parentchain/indirect-calls-executor/src/executor.rs @@ -168,6 +168,7 @@ impl< Error::Other(format!("Error when shielding for privacy sidechain {:?}", e).into()) })?; trace!("xt_statuses:: {:?}", xt_statuses); + trace!("extrinsic count :: {:?}", block.extrinsics().len()); let shard = self.get_default_shard(); if let Ok((vault, _parentchain_id)) = self.stf_enclave_signer.get_shard_vault(&shard) { diff --git a/enclave-runtime/Cargo.lock b/enclave-runtime/Cargo.lock index 4d75ab75c9..aceaf19051 100644 --- a/enclave-runtime/Cargo.lock +++ b/enclave-runtime/Cargo.lock @@ -1682,6 +1682,8 @@ dependencies = [ "sgx_tstd", "sp-core", "sp-runtime", + "sp-version", + "substrate-api-client", ] [[package]] @@ -2022,6 +2024,7 @@ dependencies = [ "itp-node-api", "itp-nonce-cache", "itp-types", + "log", "parity-scale-codec", "sgx_tstd", "sgx_types", diff --git a/enclave-runtime/src/initialization/global_components.rs b/enclave-runtime/src/initialization/global_components.rs index ac378c8597..6adf0c5258 100644 --- a/enclave-runtime/src/initialization/global_components.rs +++ b/enclave-runtime/src/initialization/global_components.rs @@ -30,7 +30,14 @@ use crate::{ rpc::rpc_response_channel::RpcResponseChannel, tls_ra::seal_handler::SealHandler, }; -use ita_parentchain_interface::{integritee, target_a, target_b}; +use ita_parentchain_interface::{ + integritee, + integritee::api_client_types::{IntegriteeRuntimeConfig, IntegriteeTip}, + target_a, + target_a::api_client_types::{TargetARuntimeConfig, TargetATip}, + target_b, + target_b::api_client_types::{TargetBRuntimeConfig, TargetBTip}, +}; use ita_sgx_runtime::Runtime; use ita_stf::{Getter, State as StfState, Stf, TrustedCallSigned}; use itc_direct_rpc_server::{ @@ -144,8 +151,36 @@ pub type EnclaveSidechainApi = SidechainApi>; -pub type EnclaveExtrinsicsFactory = - ExtrinsicsFactory; + +pub type EnclaveExtrinsicsFactory = ExtrinsicsFactory< + EnclaveParentchainSigner, + NonceCache, + EnclaveNodeMetadataRepository, + NodeRuntimeConfig, + Tip, +>; + +pub type IntegriteeEnclaveExtrinsicsFactory = ExtrinsicsFactory< + EnclaveParentchainSigner, + NonceCache, + EnclaveNodeMetadataRepository, + IntegriteeRuntimeConfig, + IntegriteeTip, +>; +pub type TargetAEnclaveExtrinsicsFactory = ExtrinsicsFactory< + EnclaveParentchainSigner, + NonceCache, + EnclaveNodeMetadataRepository, + TargetARuntimeConfig, + TargetATip, +>; +pub type TargetBEnclaveExtrinsicsFactory = ExtrinsicsFactory< + EnclaveParentchainSigner, + NonceCache, + EnclaveNodeMetadataRepository, + TargetBRuntimeConfig, + TargetBTip, +>; pub type EnclaveValidatorAccessor = ValidatorAccessor< LightValidation, @@ -182,7 +217,7 @@ pub type IntegriteeParentchainBlockImporter = ParentchainBlockImporter< ParentchainBlock, EnclaveValidatorAccessor, EnclaveStfExecutor, - EnclaveExtrinsicsFactory, + IntegriteeEnclaveExtrinsicsFactory, IntegriteeParentchainIndirectCallsExecutor, >; @@ -224,7 +259,7 @@ pub type TargetAParentchainBlockImporter = ParentchainBlockImporter< ParentchainBlock, EnclaveValidatorAccessor, EnclaveStfExecutor, - EnclaveExtrinsicsFactory, + TargetAEnclaveExtrinsicsFactory, TargetAParentchainIndirectCallsExecutor, >; @@ -266,7 +301,7 @@ pub type TargetBParentchainBlockImporter = ParentchainBlockImporter< ParentchainBlock, EnclaveValidatorAccessor, EnclaveStfExecutor, - EnclaveExtrinsicsFactory, + TargetBEnclaveExtrinsicsFactory, TargetBParentchainIndirectCallsExecutor, >; @@ -320,7 +355,7 @@ pub type EnclaveBlockImportConfirmationHandler = BlockImportConfirmationHandler< ParentchainBlock, <::Block as SidechainBlockTrait>::HeaderType, EnclaveNodeMetadataRepository, - EnclaveExtrinsicsFactory, + IntegriteeEnclaveExtrinsicsFactory, EnclaveValidatorAccessor, >; pub type EnclaveSidechainBlockSyncer = PeerBlockSync< @@ -342,17 +377,19 @@ pub type EnclaveSealHandler = SealHandler< EnclaveStateHandler, EnclaveLightClientSeal, >; -pub type EnclaveOffchainWorkerExecutor = itc_offchain_worker_executor::executor::Executor< - ParentchainBlock, - EnclaveTopPoolAuthor, - EnclaveStfExecutor, - EnclaveStateHandler, - EnclaveValidatorAccessor, - EnclaveExtrinsicsFactory, - EnclaveStf, - EnclaveTrustedCallSigned, - EnclaveGetter, ->; + +pub type EnclaveOffchainWorkerExecutor = + itc_offchain_worker_executor::executor::Executor< + ParentchainBlock, + EnclaveTopPoolAuthor, + EnclaveStfExecutor, + EnclaveStateHandler, + EnclaveValidatorAccessor, + ExtrinsicsFactory, + EnclaveStf, + EnclaveTrustedCallSigned, + EnclaveGetter, + >; // Base component instances //------------------------------------------------------------------------------------------------- diff --git a/enclave-runtime/src/initialization/parentchain/common.rs b/enclave-runtime/src/initialization/parentchain/common.rs index 01832132a0..05093bf953 100644 --- a/enclave-runtime/src/initialization/parentchain/common.rs +++ b/enclave-runtime/src/initialization/parentchain/common.rs @@ -21,16 +21,17 @@ use crate::{ global_components::{ EnclaveExtrinsicsFactory, EnclaveNodeMetadataRepository, EnclaveOffchainWorkerExecutor, EnclaveParentchainSigner, EnclaveStfExecutor, EnclaveValidatorAccessor, - IntegriteeParentchainBlockImportDispatcher, IntegriteeParentchainBlockImportQueue, - IntegriteeParentchainBlockImporter, IntegriteeParentchainEventImportQueue, + IntegriteeEnclaveExtrinsicsFactory, IntegriteeParentchainBlockImportDispatcher, + IntegriteeParentchainBlockImportQueue, IntegriteeParentchainBlockImporter, + IntegriteeParentchainEventImportQueue, IntegriteeParentchainImmediateBlockImportDispatcher, IntegriteeParentchainIndirectCallsExecutor, - IntegriteeParentchainTriggeredBlockImportDispatcher, + IntegriteeParentchainTriggeredBlockImportDispatcher, TargetAEnclaveExtrinsicsFactory, TargetAParentchainBlockImportDispatcher, TargetAParentchainBlockImportQueue, TargetAParentchainBlockImporter, TargetAParentchainEventImportQueue, TargetAParentchainImmediateBlockImportDispatcher, TargetAParentchainIndirectCallsExecutor, - TargetAParentchainTriggeredBlockImportDispatcher, + TargetAParentchainTriggeredBlockImportDispatcher, TargetBEnclaveExtrinsicsFactory, TargetBParentchainBlockImportDispatcher, TargetBParentchainBlockImportQueue, TargetBParentchainBlockImporter, TargetBParentchainEventImportQueue, TargetBParentchainImmediateBlockImportDispatcher, @@ -43,6 +44,7 @@ use crate::{ EnclaveStfEnclaveSigner, }, }; +use ita_parentchain_interface::Config; use itp_component_container::ComponentGetter; use itp_nonce_cache::NonceCache; use itp_sgx_crypto::key_repository::AccessKey; @@ -55,7 +57,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, shard_creation_info: ShardCreationInfo, ) -> Result { @@ -90,7 +92,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, shard_creation_info: ShardCreationInfo, ) -> Result { @@ -125,7 +127,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, shard_creation_info: ShardCreationInfo, ) -> Result { @@ -157,11 +159,11 @@ pub(crate) fn create_target_b_parentchain_block_importer( )) } -pub(crate) fn create_extrinsics_factory( +pub(crate) fn create_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( @@ -176,7 +178,7 @@ 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()?; @@ -206,7 +208,7 @@ 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()?; @@ -236,7 +238,7 @@ 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()?; diff --git a/enclave-runtime/src/initialization/parentchain/integritee_parachain.rs b/enclave-runtime/src/initialization/parentchain/integritee_parachain.rs index d6264c2ea4..5f55a2ff52 100644 --- a/enclave-runtime/src/initialization/parentchain/integritee_parachain.rs +++ b/enclave-runtime/src/initialization/parentchain/integritee_parachain.rs @@ -19,9 +19,8 @@ use crate::{ error::Result, initialization::{ global_components::{ - EnclaveExtrinsicsFactory, EnclaveNodeMetadataRepository, EnclaveOCallApi, - EnclaveStfExecutor, EnclaveValidatorAccessor, - IntegriteeParentchainBlockImportDispatcher, + EnclaveNodeMetadataRepository, EnclaveOCallApi, EnclaveStfExecutor, + EnclaveValidatorAccessor, IntegriteeParentchainBlockImportDispatcher, GLOBAL_INTEGRITEE_PARENTCHAIN_LIGHT_CLIENT_SEAL, GLOBAL_INTEGRITEE_PARENTCHAIN_NONCE_CACHE, GLOBAL_OCALL_API_COMPONENT, GLOBAL_STATE_HANDLER_COMPONENT, @@ -39,6 +38,7 @@ use itp_settings::worker_mode::{ProvideWorkerMode, WorkerMode}; use itp_types::parentchain::ParentchainId; use std::{path::PathBuf, sync::Arc}; +use crate::initialization::global_components::IntegriteeEnclaveExtrinsicsFactory; pub use itc_parentchain::primitives::{ParachainBlock, ParachainHeader, ParachainParams}; use itp_stf_interface::ShardCreationInfo; @@ -48,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, } diff --git a/enclave-runtime/src/initialization/parentchain/integritee_solochain.rs b/enclave-runtime/src/initialization/parentchain/integritee_solochain.rs index 37b95135e5..c3727debc4 100644 --- a/enclave-runtime/src/initialization/parentchain/integritee_solochain.rs +++ b/enclave-runtime/src/initialization/parentchain/integritee_solochain.rs @@ -19,9 +19,8 @@ use crate::{ error::Result, initialization::{ global_components::{ - EnclaveExtrinsicsFactory, EnclaveNodeMetadataRepository, EnclaveOCallApi, - EnclaveStfExecutor, EnclaveValidatorAccessor, - IntegriteeParentchainBlockImportDispatcher, + EnclaveNodeMetadataRepository, EnclaveOCallApi, EnclaveStfExecutor, + EnclaveValidatorAccessor, IntegriteeParentchainBlockImportDispatcher, GLOBAL_INTEGRITEE_PARENTCHAIN_LIGHT_CLIENT_SEAL, GLOBAL_INTEGRITEE_PARENTCHAIN_NONCE_CACHE, GLOBAL_OCALL_API_COMPONENT, GLOBAL_STATE_HANDLER_COMPONENT, @@ -39,6 +38,7 @@ use itp_settings::worker_mode::{ProvideWorkerMode, WorkerMode}; use itp_types::parentchain::ParentchainId; use std::{path::PathBuf, sync::Arc}; +use crate::initialization::global_components::IntegriteeEnclaveExtrinsicsFactory; pub use itc_parentchain::primitives::{SolochainBlock, SolochainHeader, SolochainParams}; use itp_stf_interface::ShardCreationInfo; @@ -47,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, } diff --git a/enclave-runtime/src/initialization/parentchain/target_a_parachain.rs b/enclave-runtime/src/initialization/parentchain/target_a_parachain.rs index 31799d636a..6f56f47c93 100644 --- a/enclave-runtime/src/initialization/parentchain/target_a_parachain.rs +++ b/enclave-runtime/src/initialization/parentchain/target_a_parachain.rs @@ -25,10 +25,11 @@ 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, TargetAEnclaveExtrinsicsFactory, + 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_sidechain_triggered_import_dispatcher_for_target_a, @@ -51,7 +52,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, } diff --git a/enclave-runtime/src/initialization/parentchain/target_a_solochain.rs b/enclave-runtime/src/initialization/parentchain/target_a_solochain.rs index 4348dc8e19..87e4e0b03f 100644 --- a/enclave-runtime/src/initialization/parentchain/target_a_solochain.rs +++ b/enclave-runtime/src/initialization/parentchain/target_a_solochain.rs @@ -19,10 +19,11 @@ 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, TargetAEnclaveExtrinsicsFactory, + 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_sidechain_triggered_import_dispatcher_for_target_a, @@ -44,7 +45,7 @@ pub struct TargetASolochainHandler { 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, } diff --git a/enclave-runtime/src/initialization/parentchain/target_b_parachain.rs b/enclave-runtime/src/initialization/parentchain/target_b_parachain.rs index 113103ee87..e04ddbc90e 100644 --- a/enclave-runtime/src/initialization/parentchain/target_b_parachain.rs +++ b/enclave-runtime/src/initialization/parentchain/target_b_parachain.rs @@ -25,10 +25,11 @@ 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, TargetBEnclaveExtrinsicsFactory, + 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_sidechain_triggered_import_dispatcher_for_target_b, @@ -51,7 +52,7 @@ pub struct TargetBParachainHandler { 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, } diff --git a/enclave-runtime/src/initialization/parentchain/target_b_solochain.rs b/enclave-runtime/src/initialization/parentchain/target_b_solochain.rs index edab731e6d..e609782ec4 100644 --- a/enclave-runtime/src/initialization/parentchain/target_b_solochain.rs +++ b/enclave-runtime/src/initialization/parentchain/target_b_solochain.rs @@ -19,10 +19,11 @@ 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, TargetBEnclaveExtrinsicsFactory, + 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_sidechain_triggered_import_dispatcher_for_target_b, @@ -44,7 +45,7 @@ pub struct TargetBSolochainHandler { 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, } diff --git a/enclave-runtime/src/shard_creation_info.rs b/enclave-runtime/src/shard_creation_info.rs index b79c0726a5..4994cea6b8 100644 --- a/enclave-runtime/src/shard_creation_info.rs +++ b/enclave-runtime/src/shard_creation_info.rs @@ -36,7 +36,7 @@ use itp_types::{ parentchain::{Hash, Header, IdentifyParentchain, ParentchainId}, ShardIdentifier, }; -use itp_utils::write_slice_and_whitespace_pad; +use itp_utils::{hex::hex_encode, write_slice_and_whitespace_pad}; use log::*; use sgx_types::sgx_status_t; use std::slice; @@ -94,7 +94,12 @@ fn init_shard_creation_parentchain_header_internal( .into(), )) } - debug!("initializing shard creation header: {:?}", parentchain_id); + debug!( + "[{:?}] initializing shard creation header: number: {} hash: {}", + parentchain_id, + header.number, + hex_encode(header.hash().encode().as_ref()) + ); let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; if !state_handler diff --git a/enclave-runtime/src/shard_vault.rs b/enclave-runtime/src/shard_vault.rs index 8598f8726a..0a37e7635c 100644 --- a/enclave-runtime/src/shard_vault.rs +++ b/enclave-runtime/src/shard_vault.rs @@ -16,7 +16,8 @@ use crate::{ error::{Error, Result as EnclaveResult}, initialization::global_components::{ - EnclaveStf, GLOBAL_OCALL_API_COMPONENT, GLOBAL_SIGNING_KEY_REPOSITORY_COMPONENT, + EnclaveExtrinsicsFactory, EnclaveNodeMetadataRepository, EnclaveStf, + GLOBAL_OCALL_API_COMPONENT, GLOBAL_SIGNING_KEY_REPOSITORY_COMPONENT, GLOBAL_STATE_HANDLER_COMPONENT, }, std::string::ToString, @@ -30,10 +31,11 @@ use crate::{ }, }; use codec::{Compact, Decode, Encode}; +use core::fmt::Debug; use itp_component_container::ComponentGetter; use itp_extrinsics_factory::CreateExtrinsics; use itp_node_api::{ - api_client::{PairSignature, StaticExtrinsicSigner}, + api_client::{Config, PairSignature, StaticExtrinsicSigner}, metadata::provider::{AccessNodeMetadata, Error as MetadataProviderError}, }; use itp_node_api_metadata::pallet_proxy::ProxyCallIndexes; @@ -47,6 +49,7 @@ use itp_types::{ OpaqueCall, ShardIdentifier, }; use log::*; +use primitive_types::H256; use sgx_types::sgx_status_t; use sp_core::crypto::{DeriveJunction, Pair}; use std::{slice, sync::Arc}; @@ -130,6 +133,61 @@ pub(crate) fn init_proxied_shard_vault_internal( parentchain_id: ParentchainId, funding_balance: Balance, ) -> EnclaveResult<()> { + match parentchain_id { + ParentchainId::Integritee => { + let enclave_extrinsics_factory = + get_extrinsic_factory_from_integritee_solo_or_parachain()?; + let node_metadata_repo = + get_node_metadata_repository_from_integritee_solo_or_parachain()?; + init_shard( + shard, + parentchain_id, + funding_balance, + enclave_extrinsics_factory, + node_metadata_repo, + ) + }, + ParentchainId::TargetA => { + let enclave_extrinsics_factory = + get_extrinsic_factory_from_target_a_solo_or_parachain()?; + let node_metadata_repo = + get_node_metadata_repository_from_target_a_solo_or_parachain()?; + init_shard( + shard, + parentchain_id, + funding_balance, + enclave_extrinsics_factory, + node_metadata_repo, + ) + }, + ParentchainId::TargetB => { + let enclave_extrinsics_factory = + get_extrinsic_factory_from_target_b_solo_or_parachain()?; + let node_metadata_repo = + get_node_metadata_repository_from_target_b_solo_or_parachain()?; + init_shard( + shard, + parentchain_id, + funding_balance, + enclave_extrinsics_factory, + node_metadata_repo, + ) + }, + } +} + +fn init_shard( + shard: ShardIdentifier, + parentchain_id: ParentchainId, + funding_balance: Balance, + enclave_extrinsics_factory: Arc>, + node_metadata_repository: Arc, +) -> EnclaveResult<()> +where + NodeRuntimeConfig: Config, + u128: From, + Tip: Copy + Default + Encode + Debug, +{ let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; if !state_handler .shard_exists(&shard) @@ -150,35 +208,12 @@ pub(crate) fn init_proxied_shard_vault_internal( EnclaveStf::init_shard_vault_account(&mut state, vault.public().into(), parentchain_id) .map_err(|e| Error::Stf(e.to_string()))?; state_handler.write_after_mutation(state, state_lock, &shard)?; - let (enclave_extrinsics_factory, node_metadata_repo) = match parentchain_id { - ParentchainId::Integritee => { - let enclave_extrinsics_factory = - get_extrinsic_factory_from_integritee_solo_or_parachain()?; - let node_metadata_repo = - get_node_metadata_repository_from_integritee_solo_or_parachain()?; - (enclave_extrinsics_factory, node_metadata_repo) - }, - ParentchainId::TargetA => { - let enclave_extrinsics_factory = - get_extrinsic_factory_from_target_a_solo_or_parachain()?; - let node_metadata_repo = - get_node_metadata_repository_from_target_a_solo_or_parachain()?; - (enclave_extrinsics_factory, node_metadata_repo) - }, - ParentchainId::TargetB => { - let enclave_extrinsics_factory = - get_extrinsic_factory_from_target_b_solo_or_parachain()?; - let node_metadata_repo = - get_node_metadata_repository_from_target_b_solo_or_parachain()?; - (enclave_extrinsics_factory, node_metadata_repo) - }, - }; info!( "[{:?}] send existential funds from enclave account to vault account: {:?}", parentchain_id, funding_balance ); - let call_ids = node_metadata_repo + let call_ids = node_metadata_repository .get_from_metadata(|m| m.call_indexes("Balances", "transfer_keep_alive"))? .map_err(MetadataProviderError::MetadataError)?; @@ -201,7 +236,7 @@ pub(crate) fn init_proxied_shard_vault_internal( .with_signer(StaticExtrinsicSigner::<_, PairSignature>::new(vault), nonce_cache); info!("[{:?}] register enclave signer as proxy for shard vault", parentchain_id); - let call_ids = node_metadata_repo + let call_ids = node_metadata_repository .get_from_metadata(|m| m.call_indexes("Proxy", "add_proxy"))? .map_err(MetadataProviderError::MetadataError)?; @@ -216,7 +251,8 @@ pub(crate) fn init_proxied_shard_vault_internal( let mortality = try_mortality(64, &ocall_api, parentchain_id); let xts = vault_extrinsics_factory.create_extrinsics(&[(call, mortality)], None)?; - ocall_api.send_to_parentchain(xts, &parentchain_id, false)?; + ocall_api.send_to_parentchain(xts, &parentchain_id, true)?; + info!("[{:?}] add proxy call got included", parentchain_id); Ok(()) } @@ -224,6 +260,67 @@ pub(crate) fn add_shard_vault_proxy( shard: ShardIdentifier, proxy: &AccountId, ) -> EnclaveResult<()> { + let (vault, parentchain_id) = get_shard_vault_internal(shard)?; + + match parentchain_id { + ParentchainId::Integritee => { + let enclave_extrinsics_factory = + get_extrinsic_factory_from_integritee_solo_or_parachain()?; + let node_metadata_repo = + get_node_metadata_repository_from_integritee_solo_or_parachain()?; + add_shard_vault_proxy_int( + shard, + proxy, + vault, + parentchain_id, + enclave_extrinsics_factory, + node_metadata_repo, + ) + }, + ParentchainId::TargetA => { + let enclave_extrinsics_factory = + get_extrinsic_factory_from_target_a_solo_or_parachain()?; + let node_metadata_repo = + get_node_metadata_repository_from_target_a_solo_or_parachain()?; + add_shard_vault_proxy_int( + shard, + proxy, + vault, + parentchain_id, + enclave_extrinsics_factory, + node_metadata_repo, + ) + }, + ParentchainId::TargetB => { + let enclave_extrinsics_factory = + get_extrinsic_factory_from_target_b_solo_or_parachain()?; + let node_metadata_repo = + get_node_metadata_repository_from_target_b_solo_or_parachain()?; + add_shard_vault_proxy_int( + shard, + proxy, + vault, + parentchain_id, + enclave_extrinsics_factory, + node_metadata_repo, + ) + }, + } +} + +fn add_shard_vault_proxy_int( + shard: ShardIdentifier, + proxy: &AccountId, + vault: AccountId, + parentchain_id: ParentchainId, + enclave_extrinsics_factory: Arc>, + node_metadata_repository: Arc, +) -> EnclaveResult<()> +where + NodeRuntimeConfig: Config, + u128: From, + Tip: Copy + Default + Encode + Debug, +{ let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; if !state_handler .shard_exists(&shard) @@ -233,19 +330,6 @@ pub(crate) fn add_shard_vault_proxy( }; let ocall_api = GLOBAL_OCALL_API_COMPONENT.get()?; - let (vault, parentchain_id) = get_shard_vault_internal(shard)?; - - let enclave_extrinsics_factory = match parentchain_id { - ParentchainId::Integritee => get_extrinsic_factory_from_integritee_solo_or_parachain()?, - ParentchainId::TargetA => get_extrinsic_factory_from_target_a_solo_or_parachain()?, - ParentchainId::TargetB => get_extrinsic_factory_from_target_b_solo_or_parachain()?, - }; - let node_metadata_repo = match parentchain_id { - ParentchainId::Integritee => - get_node_metadata_repository_from_integritee_solo_or_parachain()?, - ParentchainId::TargetA => get_node_metadata_repository_from_target_a_solo_or_parachain()?, - ParentchainId::TargetB => get_node_metadata_repository_from_target_b_solo_or_parachain()?, - }; debug!( "adding proxy 0x{} to shard vault account 0x{} on {:?}", @@ -255,13 +339,13 @@ pub(crate) fn add_shard_vault_proxy( ); let add_proxy_call = OpaqueCall::from_tuple(&( - node_metadata_repo.get_from_metadata(|m| m.add_proxy_call_indexes())??, + node_metadata_repository.get_from_metadata(|m| m.add_proxy_call_indexes())??, Address::from(proxy.clone()), ProxyType::Any, 0u32, // delay )); let call = OpaqueCall::from_tuple(&( - node_metadata_repo.get_from_metadata(|m| m.proxy_call_indexes())??, + node_metadata_repository.get_from_metadata(|m| m.proxy_call_indexes())??, Address::from(vault), None::, add_proxy_call, diff --git a/enclave-runtime/src/utils.rs b/enclave-runtime/src/utils.rs index 0cc95d7729..81b38456e6 100644 --- a/enclave-runtime/src/utils.rs +++ b/enclave-runtime/src/utils.rs @@ -17,10 +17,10 @@ use crate::{ error::{Error, Result}, initialization::global_components::{ - EnclaveExtrinsicsFactory, EnclaveNodeMetadataRepository, EnclaveStfEnclaveSigner, - EnclaveStfExecutor, EnclaveValidatorAccessor, - IntegriteeParentchainTriggeredBlockImportDispatcher, - TargetAParentchainTriggeredBlockImportDispatcher, + EnclaveNodeMetadataRepository, EnclaveStfEnclaveSigner, EnclaveStfExecutor, + EnclaveValidatorAccessor, IntegriteeEnclaveExtrinsicsFactory, + IntegriteeParentchainTriggeredBlockImportDispatcher, TargetAEnclaveExtrinsicsFactory, + TargetAParentchainTriggeredBlockImportDispatcher, TargetBEnclaveExtrinsicsFactory, TargetBParentchainTriggeredBlockImportDispatcher, GLOBAL_INTEGRITEE_PARACHAIN_HANDLER_COMPONENT, GLOBAL_INTEGRITEE_PARENTCHAIN_NONCE_CACHE, GLOBAL_INTEGRITEE_SOLOCHAIN_HANDLER_COMPONENT, GLOBAL_OCALL_API_COMPONENT, @@ -206,7 +206,7 @@ pub(crate) fn get_node_metadata_repository_from_target_b_solo_or_parachain( } pub(crate) fn get_extrinsic_factory_from_integritee_solo_or_parachain( -) -> Result> { +) -> Result> { let extrinsics_factory = if let Ok(solochain_handler) = GLOBAL_INTEGRITEE_SOLOCHAIN_HANDLER_COMPONENT.get() { solochain_handler.extrinsics_factory.clone() @@ -219,7 +219,7 @@ pub(crate) fn get_extrinsic_factory_from_integritee_solo_or_parachain( } pub(crate) fn get_extrinsic_factory_from_target_a_solo_or_parachain( -) -> Result> { +) -> Result> { let extrinsics_factory = if let Ok(solochain_handler) = GLOBAL_TARGET_A_SOLOCHAIN_HANDLER_COMPONENT.get() { solochain_handler.extrinsics_factory.clone() @@ -232,7 +232,7 @@ pub(crate) fn get_extrinsic_factory_from_target_a_solo_or_parachain( } pub(crate) fn get_extrinsic_factory_from_target_b_solo_or_parachain( -) -> Result> { +) -> Result> { let extrinsics_factory = if let Ok(solochain_handler) = GLOBAL_TARGET_B_SOLOCHAIN_HANDLER_COMPONENT.get() { solochain_handler.extrinsics_factory.clone() diff --git a/service/src/account_funding.rs b/service/src/account_funding.rs index e184166bac..33e8b83bcf 100644 --- a/service/src/account_funding.rs +++ b/service/src/account_funding.rs @@ -17,11 +17,12 @@ use crate::error::{Error, ServiceResult}; use codec::Encode; -use itp_node_api::api_client::{AccountApi, ParentchainApi, TEEREX}; +use ita_parentchain_interface::{Config, ParentchainRuntimeConfig}; +use itp_node_api::api_client::{AccountApi, TEEREX}; use itp_settings::worker::REGISTERING_FEE_FACTOR_FOR_INIT_FUNDS; use itp_types::{ - parentchain::{AccountId, Balance, ParentchainId}, - Moment, + parentchain::{AccountId, Balance, Index, ParentchainId}, + AccountData, Moment, Nonce, }; use log::*; use sp_core::{ @@ -29,11 +30,18 @@ use sp_core::{ Pair, }; use sp_keyring::AccountKeyring; -use sp_runtime::{MultiAddress, Saturating}; -use std::{fmt::Display, thread, time::Duration}; +use sp_runtime::{traits::SignedExtension, MultiAddress, Saturating}; +use std::{ + fmt::{Debug, Display}, + thread, + time::Duration, +}; use substrate_api_client::{ - ac_compose_macros::compose_extrinsic, ac_primitives::Bytes, extrinsic::BalancesExtrinsics, - GetBalance, GetStorage, GetTransactionPayment, SubmitAndWatch, SystemApi, XtStatus, + ac_compose_macros::{compose_extrinsic, compose_extrinsic_with_nonce}, + ac_primitives::{Bytes, Config as ParentchainNodeConfig}, + extrinsic::BalancesExtrinsics, + rpc::{Request, Subscribe}, + Api, GetBalance, GetStorage, GetTransactionPayment, SubmitAndWatch, SystemApi, XtStatus, }; use teerex_primitives::SgxAttestationMethod; @@ -76,13 +84,23 @@ pub trait ParentchainAccountInfo { fn decimals(&self) -> ServiceResult; } -pub struct ParentchainAccountInfoProvider { +pub struct ParentchainAccountInfoProvider +where + u128: From, + Tip: Copy + Default + Encode + Debug, + Client: Request, +{ parentchain_id: ParentchainId, - node_api: ParentchainApi, + node_api: Api, Client>, account_and_role: AccountAndRole, } -impl ParentchainAccountInfo for ParentchainAccountInfoProvider { +impl ParentchainAccountInfo for ParentchainAccountInfoProvider +where + u128: From, + Tip: Copy + Default + Encode + Debug, + Client: Request, +{ fn free_balance(&self) -> ServiceResult { self.node_api .get_free_balance(&self.account_and_role.account_id()) @@ -107,10 +125,15 @@ impl ParentchainAccountInfo for ParentchainAccountInfoProvider { } } -impl ParentchainAccountInfoProvider { +impl ParentchainAccountInfoProvider +where + u128: From, + Tip: Copy + Default + Encode + Debug, + Client: Request, +{ pub fn new( parentchain_id: ParentchainId, - node_api: ParentchainApi, + node_api: Api, Client>, account_and_role: AccountAndRole, ) -> Self { ParentchainAccountInfoProvider { parentchain_id, node_api, account_and_role } @@ -120,14 +143,19 @@ impl ParentchainAccountInfoProvider { /// evaluate if the enclave should have more funds and how much more /// in --dev mode: let Alice pay for missing funds /// in production mode: wait for manual transfer before continuing -pub fn setup_reasonable_account_funding( - api: &ParentchainApi, +pub fn setup_reasonable_account_funding( + api: Api, Client>, accountid: &AccountId32, parentchain_id: ParentchainId, is_development_mode: bool, -) -> ServiceResult<()> { +) -> ServiceResult<()> +where + u128: From, + Tip: Copy + Default + Encode + Debug, + Client: Request + Subscribe + Clone, +{ loop { - let needed = estimate_funds_needed_to_run_for_a_while(api, accountid, parentchain_id)?; + let needed = estimate_funds_needed_to_run_for_a_while(&api, accountid, parentchain_id)?; let free = api.get_free_balance(accountid)?; let missing_funds = needed.saturating_sub(free); @@ -137,7 +165,7 @@ pub fn setup_reasonable_account_funding( if is_development_mode { info!("[{:?}] Alice will grant {:?} to {:?}", parentchain_id, missing_funds, accountid); - bootstrap_funds_from_alice(api, accountid, missing_funds)?; + bootstrap_funds_from_alice(api.clone(), accountid, missing_funds, parentchain_id)?; } else { error!( "[{:?}] Enclave account needs funding. please send at least {:?} to {:?}", @@ -148,26 +176,34 @@ pub fn setup_reasonable_account_funding( } } -fn estimate_funds_needed_to_run_for_a_while( - api: &ParentchainApi, +fn estimate_funds_needed_to_run_for_a_while( + api: &Api, Client>, accountid: &AccountId32, parentchain_id: ParentchainId, -) -> ServiceResult { +) -> ServiceResult +where + u128: From, + Tip: Copy + Default + Encode + Debug, + Client: Request, +{ let existential_deposit = api.get_existential_deposit()?; info!("[{:?}] Existential deposit is = {:?}", parentchain_id, existential_deposit); let mut min_required_funds: Balance = existential_deposit; - min_required_funds += shard_vault_initial_funds(api)?; + min_required_funds += shard_vault_initial_funds(api, parentchain_id)?; let transfer_fee = estimate_transfer_fee(api)?; info!("[{:?}] a single transfer costs {:?}", parentchain_id, transfer_fee); min_required_funds += 1000 * transfer_fee; - // Check if this is an integritee chain and Compose a register_sgx_enclave extrinsic + // // Check if this is an integritee chain and Compose a register_sgx_enclave extrinsic if let Ok(ra_renewal) = api.get_constant::("Teerex", "MaxAttestationRenewalPeriod") { info!("[{:?}] this chain has the teerex pallet. estimating RA fees", parentchain_id); - let encoded_xt: Bytes = compose_extrinsic!( + let nonce = api.get_nonce_of(accountid)?; + + let encoded_xt: Bytes = compose_extrinsic_with_nonce!( api, + nonce, TEEREX, "register_sgx_enclave", vec![0u8; SGX_RA_PROOF_MAX_LEN], @@ -198,7 +234,15 @@ fn estimate_funds_needed_to_run_for_a_while( Ok(min_required_funds) } -pub fn estimate_fee(api: &ParentchainApi, encoded_extrinsic: Vec) -> Result { +pub fn estimate_fee( + api: &Api, Client>, + encoded_extrinsic: Vec, +) -> Result +where + u128: From, + Tip: Copy + Default + Encode + Debug, + Client: Request, +{ let reg_fee_details = api.get_fee_details(&encoded_extrinsic.into(), None)?; match reg_fee_details { Some(details) => match details.inclusion_fee { @@ -213,62 +257,91 @@ pub fn estimate_fee(api: &ParentchainApi, encoded_extrinsic: Vec) -> Result< } /// Alice sends some funds to the account. only for dev chains testing -fn bootstrap_funds_from_alice( - api: &ParentchainApi, +fn bootstrap_funds_from_alice( + api: Api, Client>, accountid: &AccountId32, funding_amount: u128, -) -> Result<(), Error> { + parentchain_id: ParentchainId, +) -> Result<(), Error> +where + u128: From, + Tip: Copy + Default + Encode + Debug, + Client: Request + Subscribe, +{ + let mut api = api; + let alice = AccountKeyring::Alice.pair(); let alice_acc = AccountId32::from(*alice.public().as_array_ref()); let alice_free = api.get_free_balance(&alice_acc)?; - trace!(" Alice's free balance = {:?}", alice_free); + trace!("[{:?}] Alice's free balance = {:?}", parentchain_id, alice_free); let nonce = api.get_nonce_of(&alice_acc)?; - trace!(" Alice's Account Nonce is {}", nonce); + trace!("[{:?}] Alice's Account Nonce is {}", parentchain_id, nonce); if funding_amount > alice_free { println!( - "funding amount is too high: please change EXISTENTIAL_DEPOSIT_FACTOR_FOR_INIT_FUNDS ({:?})", + "[{:?}] funding amount is too high: please change EXISTENTIAL_DEPOSIT_FACTOR_FOR_INIT_FUNDS ({:?})", + parentchain_id, funding_amount ); return Err(Error::ApplicationSetup) } - let mut alice_signer_api = api.clone(); - alice_signer_api.set_signer(alice.into()); + 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_report = alice_signer_api.submit_and_watch_extrinsic_until(xt, XtStatus::InBlock)?; + println!("[{:?}] send extrinsic: bootstrap funding Enclave from Alice's funds", parentchain_id); + let xt = api.balance_transfer_allow_death(MultiAddress::Id(accountid.clone()), funding_amount); + let xt_report = api.submit_and_watch_extrinsic_until(xt, XtStatus::InBlock)?; info!( - "[<] L1 extrinsic success. extrinsic hash: {:?} / status: {:?}", - xt_report.extrinsic_hash, xt_report.status + "[{:?}] L1 extrinsic success. extrinsic hash: {:?} / status: {:?}", + parentchain_id, xt_report.extrinsic_hash, xt_report.status ); // Verify funds have arrived. - let free_balance = alice_signer_api.get_free_balance(accountid); - trace!("TEE's NEW free balance = {:?}", free_balance); + let free_balance = api.get_free_balance(accountid); + trace!("[{:?}] TEE's NEW free balance = {:?}", parentchain_id, free_balance); Ok(()) } /// precise estimation of necessary funds to register a hardcoded number of proxies -pub fn shard_vault_initial_funds(api: &ParentchainApi) -> Result { +pub fn shard_vault_initial_funds( + api: &Api, Client>, + parentchain_id: ParentchainId, +) -> Result +where + u128: From, + Tip: Copy + Default + Encode + Debug, + Client: Request, +{ let proxy_deposit_base: Balance = api.get_constant("Proxy", "ProxyDepositBase")?; let proxy_deposit_factor: Balance = api.get_constant("Proxy", "ProxyDepositFactor")?; let transfer_fee = estimate_transfer_fee(api)?; let existential_deposit = api.get_existential_deposit()?; - info!("Proxy Deposit is {:?} base + {:?} per proxy", proxy_deposit_base, proxy_deposit_factor); + info!( + "[{:?}] Proxy Deposit is {:?} base + {:?} per proxy", + parentchain_id, proxy_deposit_base, proxy_deposit_factor + ); Ok(proxy_deposit_base + 10 * proxy_deposit_factor + 500 * transfer_fee + existential_deposit) } /// precise estimation of a single transfer fee -pub fn estimate_transfer_fee(api: &ParentchainApi) -> Result { +pub fn estimate_transfer_fee( + api: &Api, Client>, +) -> Result +where + u128: From, + Tip: Copy + Default + Encode + Debug, + Client: Request, +{ let encoded_xt: Bytes = api .balance_transfer_allow_death(AccountId::from([0u8; 32]).into(), 1000000000000) .encode() .into(); - let tx_fee = api.get_fee_details(&encoded_xt, None).unwrap().unwrap().inclusion_fee.unwrap(); + let tx_fee = api + .get_fee_details(&encoded_xt, None)? + .expect("the node must understand our extrinsic encoding") + .inclusion_fee + .unwrap(); let transfer_fee = tx_fee.base_fee + tx_fee.len_fee + tx_fee.adjusted_weight_fee; Ok(transfer_fee) } diff --git a/service/src/main_impl.rs b/service/src/main_impl.rs index 6cec422441..a486a87c8c 100644 --- a/service/src/main_impl.rs +++ b/service/src/main_impl.rs @@ -39,7 +39,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}, }; @@ -54,8 +54,10 @@ use regex::Regex; use sgx_types::*; use sp_runtime::traits::{Header as HeaderT, IdentifyAccount}; use substrate_api_client::{ - api::XtStatus, rpc::HandleSubscription, GetAccountInformation, GetBalance, GetChainInfo, - SubmitAndWatch, SubscribeChain, SubscribeEvents, + api::XtStatus, + rpc::{HandleSubscription, Request, Subscribe}, + Api, GetAccountInformation, GetBalance, GetChainInfo, GetStorage, SubmitAndWatch, + SubscribeChain, SubscribeEvents, }; use teerex_primitives::{AnySigner, MultiEnclave}; @@ -72,8 +74,18 @@ use crate::{ sidechain_setup::ParentchainIntegriteeSidechainInfoProvider, }; use enclave_bridge_primitives::ShardIdentifier; +use ita_parentchain_interface::{ + integritee::{ + api_client_types::{IntegriteeApi, IntegriteeTip}, + api_factory::IntegriteeNodeApiFactory, + }, + target_a::api_client_types::{TargetAApi, TargetARuntimeConfig}, + target_b::api_client_types::{TargetBApi, TargetBRuntimeConfig}, + ParentchainRuntimeConfig, +}; use itc_parentchain::primitives::ParentchainId; -use itp_types::parentchain::{AccountId, Balance}; +use itp_node_api::api_client::ChainApi; +use itp_types::parentchain::{AccountId, Balance, Index}; use sp_core::crypto::{AccountId32, Ss58Codec}; use sp_keyring::AccountKeyring; use sp_runtime::MultiSigner; @@ -89,14 +101,21 @@ use std::{ thread, time::Duration, }; -use substrate_api_client::ac_node_api::{EventRecord, Phase::ApplyExtrinsic}; +use substrate_api_client::{ + ac_node_api::{EventRecord, Phase::ApplyExtrinsic}, + rpc::TungsteniteRpcClient, +}; use tokio::{runtime::Handle, task::JoinHandle, time::Instant}; const VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg(feature = "link-binary")] -pub type EnclaveWorker = - Worker>; +pub type EnclaveWorker = Worker< + Config, + ParentchainRuntimeConfig, + Enclave, + InitializationHandler, +>; pub(crate) fn main() { // Setup logging @@ -161,13 +180,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( @@ -294,7 +321,7 @@ fn start_worker( shard: &ShardIdentifier, enclave: Arc, sidechain_storage: Arc, - integritee_rpc_api: ParentchainApi, + integritee_rpc_api: IntegriteeApi, tokio_handle_getter: Arc, initialization_handler: Arc, quoting_enclave_target_info: Option, @@ -651,10 +678,17 @@ fn start_worker( } let maybe_target_a_rpc_api = if let Some(url) = config.target_a_parentchain_rpc_endpoint() { - let (api, mut handles) = init_target_parentchain( + println!("Initializing parentchain TargetA with url: {}", url); + let api = ita_parentchain_interface::target_a::api_factory::TargetANodeApiFactory::new( + url, + AccountKeyring::Alice.pair(), + ) + .create_api() + .unwrap_or_else(|_| panic!("[TargetA] Failed to create parentchain node API")); + let mut handles = init_target_parentchain( &enclave, &tee_accountid, - url, + api.clone(), shard, ParentchainId::TargetA, is_development_mode, @@ -667,10 +701,17 @@ fn start_worker( }; let maybe_target_b_rpc_api = if let Some(url) = config.target_b_parentchain_rpc_endpoint() { - let (api, mut handles) = init_target_parentchain( + println!("Initializing parentchain TargetB with url: {}", url); + let api = ita_parentchain_interface::target_b::api_factory::TargetBNodeApiFactory::new( + url, + AccountKeyring::Alice.pair(), + ) + .create_api() + .unwrap_or_else(|_| panic!("[TargetB] Failed to create parentchain node API")); + let mut handles = init_target_parentchain( &enclave, &tee_accountid, - url, + api.clone(), shard, ParentchainId::TargetB, is_development_mode, @@ -741,24 +782,56 @@ fn start_worker( fn init_provided_shard_vault( shard: &ShardIdentifier, enclave: &Arc, - integritee_rpc_api: ParentchainApi, - maybe_target_a_rpc_api: Option, - maybe_target_b_rpc_api: Option, + integritee_rpc_api: IntegriteeApi, + maybe_target_a_rpc_api: Option, + maybe_target_b_rpc_api: Option, shielding_target: Option, we_are_primary_validateer: bool, ) { let shielding_target = shielding_target.unwrap_or_default(); - let rpc_api = match shielding_target { - ParentchainId::Integritee => integritee_rpc_api, - ParentchainId::TargetA => maybe_target_a_rpc_api - .expect("target A must be initialized to be used as shielding target"), - ParentchainId::TargetB => maybe_target_b_rpc_api - .expect("target B must be initialized to be used as shielding target"), + match shielding_target { + ParentchainId::Integritee => init_vault( + shard, + enclave, + &integritee_rpc_api, + shielding_target, + we_are_primary_validateer, + ), + ParentchainId::TargetA => init_vault( + shard, + enclave, + &maybe_target_a_rpc_api + .expect("target A must be initialized to be used as shielding target"), + shielding_target, + we_are_primary_validateer, + ), + ParentchainId::TargetB => init_vault( + shard, + enclave, + &maybe_target_b_rpc_api + .expect("target B must be initialized to be used as shielding target"), + shielding_target, + we_are_primary_validateer, + ), }; - let funding_balance = shard_vault_initial_funds(&rpc_api).unwrap(); +} + +fn init_vault( + shard: &ShardIdentifier, + enclave: &Arc, + node_api: &Api, Client>, + shielding_target: ParentchainId, + we_are_primary_validateer: bool, +) where + E: EnclaveBase, + u128: From, + Tip: Copy + Default + Encode + Debug, + Client: Request, +{ + let funding_balance = shard_vault_initial_funds(&node_api, shielding_target).unwrap(); if let Ok(shard_vault) = enclave.get_ecc_vault_pubkey(shard) { // verify if proxy is set up on chain - let nonce = rpc_api.get_account_nonce(&AccountId::from(shard_vault)).unwrap(); + let nonce = node_api.get_account_nonce(&AccountId::from(shard_vault)).unwrap(); println!( "[{:?}] shard vault account is already initialized in state: {} with nonce {}", shielding_target, @@ -787,31 +860,29 @@ fn init_provided_shard_vault( } } -fn init_target_parentchain( +fn init_target_parentchain( enclave: &Arc, tee_account_id: &AccountId32, - url: String, + node_api: Api, Client>, shard: &ShardIdentifier, parentchain_id: ParentchainId, is_development_mode: bool, shutdown_flag: Arc, -) -> (ParentchainApi, Vec>) +) -> Vec> where E: EnclaveBase + Sidechain, + u128: From, + Tip: Copy + Default + Encode + Debug + Send + Sync + 'static, + Client: Request + Subscribe + Clone + Send + Sync + 'static, { - println!("Initializing parentchain {:?} with url: {}", parentchain_id, url); - let node_api = NodeApiFactory::new(url, AccountKeyring::Alice.pair()) - .create_api() - .unwrap_or_else(|_| panic!("[{:?}] Failed to create parentchain node API", parentchain_id)); - setup_reasonable_account_funding( - &node_api, + node_api.clone(), tee_account_id, parentchain_id, is_development_mode, ) - .unwrap_or_else(|_| { - panic!("[{:?}] Could not fund parentchain enclave account", parentchain_id) + .unwrap_or_else(|e| { + panic!("[{:?}] Could not fund parentchain enclave account: {:?}", parentchain_id, e) }); // we attempt to set shard creation for this parentchain in case it hasn't been done before @@ -861,18 +932,21 @@ where ) }) .unwrap(); - (node_api, handles) + handles } -fn init_parentchain( +fn init_parentchain( enclave: &Arc, - node_api: &ParentchainApi, + node_api: &Api, Client>, tee_account_id: &AccountId32, parentchain_id: ParentchainId, shard: &ShardIdentifier, -) -> (Arc>, Header) +) -> (Arc>, Header) where E: EnclaveBase + Sidechain, + u128: From, + Tip: Copy + Default + Encode + Debug, + Client: Request + Subscribe + Clone, { let parentchain_handler = Arc::new( ParentchainHandler::new_with_automatic_light_client_allocation( @@ -913,7 +987,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: IntegriteeApi, initialization_handler: Arc, ) where InitializationHandler: TrackInitialization + Sync + Send + 'static, @@ -942,7 +1016,7 @@ fn spawn_worker_for_shard_polling( #[cfg(feature = "attesteer")] fn fetch_marblerun_events_every_hour( - api: ParentchainApi, + api: IntegriteeApi, enclave: Arc, accountid: AccountId32, is_development_mode: bool, @@ -973,7 +1047,7 @@ fn fetch_marblerun_events_every_hour( } #[cfg(feature = "attesteer")] fn register_quotes_from_marblerun( - api: &ParentchainApi, + api: &IntegriteeApi, enclave: Arc, accountid: &AccountId32, is_development_mode: bool, @@ -981,7 +1055,7 @@ fn register_quotes_from_marblerun( marblerun_base_url: &str, ) { let enclave = enclave.as_ref(); - let events = prometheus_metrics::fetch_marblerun_events(marblerun_base_url) + let events = crate::prometheus_metrics::fetch_marblerun_events(marblerun_base_url) .map_err(|e| { info!("Fetching events from Marblerun failed with: {:?}, continuing with 0 events.", e); }) @@ -1002,7 +1076,7 @@ fn register_quotes_from_marblerun( } #[cfg(feature = "dcap")] fn register_collateral( - api: &ParentchainApi, + api: &IntegriteeApi, enclave: &dyn RemoteAttestation, accountid: &AccountId32, is_development_mode: bool, @@ -1022,12 +1096,17 @@ fn register_collateral( } } -fn send_integritee_extrinsic( +fn send_integritee_extrinsic( extrinsic: Vec, - api: &ParentchainApi, + api: &Api, Client>, fee_payer: &AccountId32, is_development_mode: bool, -) -> ServiceResult { +) -> ServiceResult +where + u128: From, + Tip: Copy + Default + Encode + Debug + Send + Sync + 'static, + Client: Request + Subscribe + Clone + Send + Sync + 'static, +{ let timeout = Duration::from_secs(5 * 60); let (sender, receiver) = mpsc::channel(); let local_fee_payer = fee_payer.clone(); @@ -1048,7 +1127,7 @@ fn send_integritee_extrinsic( if missing_funds > 0 { setup_reasonable_account_funding( - &local_api, + local_api.clone(), &local_fee_payer, ParentchainId::Integritee, is_development_mode, @@ -1089,12 +1168,18 @@ fn send_integritee_extrinsic( } } -fn start_parentchain_header_subscription_thread( +fn start_parentchain_header_subscription_thread( shutdown_flag: Arc, - parentchain_handler: Arc>, + parentchain_handler: Arc>, last_synced_header: Header, shard: ShardIdentifier, -) -> thread::JoinHandle<()> { +) -> thread::JoinHandle<()> +where + EnclaveApi: EnclaveBase + Sidechain, + u128: From, + Tip: Copy + Default + Encode + Debug + Send + Sync + 'static, + Client: Request + Subscribe + Send + Sync + 'static, +{ let parentchain_id = *parentchain_handler.parentchain_id(); thread::Builder::new() .name(format!("{:?}_parentchain_sync_loop", parentchain_id)) @@ -1117,12 +1202,18 @@ fn start_parentchain_header_subscription_thread( /// 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( shutdown_flag: Arc, - parentchain_handler: Arc>, + parentchain_handler: Arc>, mut last_synced_header: Header, shard: ShardIdentifier, -) -> Result<(), Error> { +) -> Result<(), Error> +where + EnclaveApi: EnclaveBase + Sidechain, + u128: From, + Tip: Copy + Default + Encode + Debug, + Client: Request + Subscribe, +{ // TODO: this should be implemented by parentchain_handler directly, and not via // exposed parentchain_api let mut subscription = parentchain_handler diff --git a/service/src/ocall_bridge/component_factory.rs b/service/src/ocall_bridge/component_factory.rs index 3448bea31b..6d36702e06 100644 --- a/service/src/ocall_bridge/component_factory.rs +++ b/service/src/ocall_bridge/component_factory.rs @@ -32,18 +32,23 @@ use crate::{ sync_block_broadcaster::BroadcastBlocks, worker_peers_updater::UpdateWorkerPeers, }; +use itp_api_client_types::{Config, Request}; 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::{AccountId, BlockHash, Nonce}; use its_peer_fetch::FetchBlocksFromPeer; use its_primitives::types::block::SignedBlock as SignedSidechainBlock; use its_storage::BlockStorage; use std::{path::Path, sync::Arc}; +use substrate_api_client::rpc::TungsteniteRpcClient; /// 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, + IntegriteeRuntimeConfig: Config, + TargetARuntimeConfig: Config, + TargetBRuntimeConfig: Config, Broadcaster, EnclaveApi, Storage, @@ -52,9 +57,11 @@ 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 +73,9 @@ pub struct OCallBridgeComponentFactory< } impl< - NodeApi, + IntegriteeRuntimeConfig: Config, + TargetARuntimeConfig: Config, + TargetBRuntimeConfig: Config, Broadcaster, EnclaveApi, Storage, @@ -76,7 +85,9 @@ impl< MetricsReceiver, > OCallBridgeComponentFactory< - NodeApi, + IntegriteeRuntimeConfig, + TargetARuntimeConfig, + TargetBRuntimeConfig, Broadcaster, EnclaveApi, Storage, @@ -88,9 +99,15 @@ 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< + NodeApiFactory, + >, + 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, @@ -117,7 +134,9 @@ impl< } impl< - NodeApi, + IntegriteeRuntimeConfig, + TargetARuntimeConfig, + TargetBRuntimeConfig, Broadcaster, EnclaveApi, Storage, @@ -127,7 +146,9 @@ impl< MetricsReceiver, > GetOCallBridgeComponents for OCallBridgeComponentFactory< - NodeApi, + IntegriteeRuntimeConfig, + TargetARuntimeConfig, + TargetBRuntimeConfig, Broadcaster, EnclaveApi, Storage, @@ -136,7 +157,13 @@ impl< TokioHandle, MetricsReceiver, > where - NodeApi: CreateNodeApi + 'static, + IntegriteeRuntimeConfig: + Config + 'static, + TargetARuntimeConfig: Config + 'static, + TargetBRuntimeConfig: Config + 'static, + ::ExtrinsicSigner: From, + ::ExtrinsicSigner: From, + ::ExtrinsicSigner: From, 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 927203b1ac..1fa280be12 100644 --- a/service/src/ocall_bridge/worker_on_chain_ocall.rs +++ b/service/src/ocall_bridge/worker_on_chain_ocall.rs @@ -19,11 +19,20 @@ use crate::ocall_bridge::bridge_api::{OCallBridgeError, OCallBridgeResult, WorkerOnChainBridge}; use chrono::Local; use codec::{Decode, Encode}; -use itp_api_client_types::ParentchainApi; -use itp_node_api::{api_client::AccountApi, node_api_factory::CreateNodeApi}; +use ita_parentchain_interface::{ + integritee::{api_client_types::IntegriteeApi, api_factory::IntegriteeNodeApiFactory}, + target_a::{api_client_types::TargetAApi, api_factory::TargetANodeApiFactory}, + target_b::{api_client_types::TargetBApi, api_factory::TargetBNodeApiFactory}, + ParentchainRuntimeConfig, +}; +use itp_api_client_types::Request; +use itp_node_api::{ + api_client::{AccountApi, Config}, + node_api_factory::{CreateNodeApi, NodeApiFactory}, +}; use itp_types::{ - parentchain::{Header as ParentchainHeader, ParentchainId}, - DigestItem, WorkerRequest, WorkerResponse, + parentchain::{AccountId, Header as ParentchainHeader, ParentchainId}, + BlockHash, DigestItem, Nonce, WorkerRequest, WorkerResponse, }; use log::*; use sp_core::blake2_256; @@ -38,21 +47,38 @@ use std::{ use substrate_api_client::{ ac_primitives, ac_primitives::{serde_impls::StorageKey, Header, SubstrateHeader}, - GetAccountInformation, GetChainInfo, GetStorage, SubmitAndWatch, SubmitExtrinsic, XtStatus, + rpc::TungsteniteRpcClient, + Api, GetAccountInformation, GetChainInfo, 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< + IntegriteeConfig: Config, + TargetAConfig: Config, + TargetBConfig: Config, + Client: Request, +> { + integritee_api_factory: Arc>, + target_a_parentchain_api_factory: Option>>, + target_b_parentchain_api_factory: Option>>, log_dir: Arc, } -impl WorkerOnChainOCall { +impl + WorkerOnChainOCall +where + ::ExtrinsicSigner: From, + ::ExtrinsicSigner: From, + ::ExtrinsicSigner: From, +{ 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< + Arc>, + >, + target_b_parentchain_api_factory: Option< + Arc>, + >, log_dir: Arc, ) -> Self { WorkerOnChainOCall { @@ -64,44 +90,48 @@ impl WorkerOnChainOCall { } } -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))?, - }) - } -} - -impl WorkerOnChainBridge for WorkerOnChainOCall +impl< + IntegriteeConfig: Config, + TargetAConfig: Config, + TargetBConfig: Config, + > WorkerOnChainOCall where - F: CreateNodeApi, + ::ExtrinsicSigner: From, + ::ExtrinsicSigner: From, + ::ExtrinsicSigner: From, { - fn worker_request( + pub fn create_integritee_api( &self, - request: Vec, - parentchain_id: Vec, - ) -> OCallBridgeResult> { - debug!("[{:?}] Entering ocall_worker_request", parentchain_id); + ) -> OCallBridgeResult> { + Ok(self.integritee_api_factory.create_api()?) + } - let requests: Vec = Decode::decode(&mut request.as_slice())?; - if requests.is_empty() { - debug!("requests is empty, returning empty vector"); - return Ok(Vec::::new().encode()) - } + pub fn create_target_a_api( + &self, + ) -> OCallBridgeResult> { + self.target_a_parentchain_api_factory + .as_ref() + .ok_or(OCallBridgeError::TargetAParentchainNotInitialized) + .and_then(|f| f.create_api().map_err(Into::into)) + } - let parentchain_id = ParentchainId::decode(&mut parentchain_id.as_slice())?; + pub fn create_target_b_api( + &self, + ) -> OCallBridgeResult> { + self.target_b_parentchain_api_factory + .as_ref() + .ok_or(OCallBridgeError::TargetBParentchainNotInitialized) + .and_then(|f| f.create_api().map_err(Into::into)) + } - let api = self.create_api(parentchain_id)?; + fn handle_requests< + Config: itp_api_client_types::Config, + >( + &self, + api: &Api, + requests: Vec, + parentchain_id: ParentchainId, + ) -> OCallBridgeResult>>> { let last_finalized = api.get_finalized_head().map_err(|_| OCallBridgeError::NodeApiError)?; let header = if let Some(header) = @@ -109,18 +139,9 @@ where { header } else { - warn!( - "[{:?}] failed to fetch parentchain header. can't answer WorkerRequest", - parentchain_id - ); - return Ok(Vec::::new().encode()) + warn!("failed to fetch parentchain header. can't answer WorkerRequest"); + return Ok(vec![]) }; - trace!( - "[{:?}] Last finalized header {} {:?}", - parentchain_id, - header.number, - header.hash() - ); let resp: Vec>> = requests .into_iter() .map(|req| match req { @@ -144,6 +165,106 @@ where }) .collect(); + Ok(resp) + } + + fn submit_extrinsics_to_parentchain< + Config: itp_api_client_types::Config, + >( + &self, + api: &Api, + extrinsics: Vec, + parentchain_id: ParentchainId, + await_each_inclusion: bool, + ) -> OCallBridgeResult<()> { + debug!( + "Enclave wants to send {} extrinsics to parentchain: {:?}. await each inclusion: {:?}", + extrinsics.len(), + parentchain_id, + await_each_inclusion + ); + log_extrinsics_to_file(self.log_dir.clone(), parentchain_id, extrinsics.clone()) + .map_err(|e| { + error!("Error logging extrinsic to disk: {}", e); + e + }) + .unwrap_or_default(); + + for call in extrinsics.into_iter() { + if await_each_inclusion { + if let Err(e) = api.submit_and_watch_opaque_extrinsic_until( + &call.encode().into(), + XtStatus::InBlock, + ) { + error!( + "Could not send extrinsic to {:?}: {:?}, error: {:?}", + parentchain_id, + serde_json::to_string(&call), + e + ); + } + } else if let Err(e) = api.submit_opaque_extrinsic(&call.encode().into()) { + error!( + "Could not send extrinsic to {:?}: {:?}, error: {:?}", + parentchain_id, + serde_json::to_string(&call), + e + ); + } + } + + Ok(()) + } +} + +impl< + IntegriteeConfig: Config, + TargetAConfig: Config, + TargetBConfig: Config, + > WorkerOnChainBridge + for WorkerOnChainOCall +where + ::ExtrinsicSigner: From, + ::ExtrinsicSigner: From, + ::ExtrinsicSigner: From, +{ + fn worker_request( + &self, + request: Vec, + parentchain_id: Vec, + ) -> OCallBridgeResult> { + let parentchain_id = ParentchainId::decode(&mut parentchain_id.as_slice())?; + debug!("[{:?}] Entering ocall_worker_request", parentchain_id); + + let requests: Vec = Decode::decode(&mut request.as_slice())?; + if requests.is_empty() { + debug!("requests is empty, returning empty vector"); + return Ok(Vec::::new().encode()) + } + + let resp = match parentchain_id { + ParentchainId::Integritee => { + let api = self.integritee_api_factory.create_api()?; + self.handle_requests(&api, requests, parentchain_id)? + }, + ParentchainId::TargetA => { + let api = self + .target_a_parentchain_api_factory + .as_ref() + .ok_or(OCallBridgeError::TargetAParentchainNotInitialized)? + .create_api()?; + self.handle_requests(&api, requests, parentchain_id)? + }, + ParentchainId::TargetB => { + let api = self + .target_b_parentchain_api_factory + .as_ref() + .ok_or(OCallBridgeError::TargetBParentchainNotInitialized)? + .create_api()?; + self.handle_requests(&api, requests, parentchain_id)? + }, + }; + let encoded_response: Vec = resp.encode(); Ok(encoded_response) @@ -153,60 +274,62 @@ where &self, extrinsics_encoded: Vec, parentchain_id: Vec, - await_each_inlcusion: bool, + await_each_inclusion: bool, ) -> OCallBridgeResult<()> { - // TODO: improve error handling, using a mut status is not good design? - let mut status: OCallBridgeResult<()> = Ok(()); - let extrinsics: Vec = match Decode::decode(&mut extrinsics_encoded.as_slice()) { Ok(calls) => calls, - Err(_) => { - status = Err(OCallBridgeError::SendExtrinsicsToParentchain( + Err(_) => + return Err(OCallBridgeError::SendExtrinsicsToParentchain( "Could not decode extrinsics".to_string(), - )); - Default::default() - }, + )), }; - if !extrinsics.is_empty() { - let parentchain_id = ParentchainId::decode(&mut parentchain_id.as_slice())?; - debug!( - "Enclave wants to send {} extrinsics to parentchain: {:?}. await each inclusion: {:?}", - extrinsics.len(), - parentchain_id, await_each_inlcusion - ); - log_extrinsics_to_file(self.log_dir.clone(), parentchain_id, extrinsics.clone()) - .map_err(|e| { - error!("Error logging extrinsic to disk: {}", e); - e - }) - .unwrap_or_default(); - let api = self.create_api(parentchain_id)?; - for call in extrinsics.into_iter() { - if await_each_inlcusion { - if let Err(e) = api.submit_and_watch_opaque_extrinsic_until( - &call.encode().into(), - XtStatus::InBlock, - ) { - error!( - "Could not send extrinsic to {:?}: {:?}, error: {:?}", - parentchain_id, - serde_json::to_string(&call), - e - ); - } - } else if let Err(e) = api.submit_opaque_extrinsic(&call.encode().into()) { - error!( - "Could not send extrinsic to {:?}: {:?}, error: {:?}", - parentchain_id, - serde_json::to_string(&call), - e - ); - } - } + if extrinsics.is_empty() { + return Ok(()) } - status + + let parentchain_id = ParentchainId::decode(&mut parentchain_id.as_slice())?; + + match parentchain_id { + ParentchainId::Integritee => { + let api = self.integritee_api_factory.create_api()?; + self.submit_extrinsics_to_parentchain( + &api, + extrinsics, + parentchain_id, + await_each_inclusion, + )? + }, + ParentchainId::TargetA => { + let api = self + .target_a_parentchain_api_factory + .as_ref() + .ok_or(OCallBridgeError::TargetAParentchainNotInitialized)? + .create_api()?; + self.submit_extrinsics_to_parentchain( + &api, + extrinsics, + parentchain_id, + await_each_inclusion, + )? + }, + ParentchainId::TargetB => { + let api = self + .target_b_parentchain_api_factory + .as_ref() + .ok_or(OCallBridgeError::TargetBParentchainNotInitialized)? + .create_api()?; + self.submit_extrinsics_to_parentchain( + &api, + extrinsics, + parentchain_id, + await_each_inclusion, + )? + }, + }; + + Ok(()) } } @@ -228,38 +351,3 @@ fn log_extrinsics_to_file( } Ok(()) } - -#[cfg(test)] -mod tests { - - use super::*; - use itp_node_api::{ - api_client::ParentchainApi, - node_api_factory::{CreateNodeApi, Result as NodeApiResult}, - }; - use itp_sgx_temp_dir::TempDir; - use mockall::mock; - - #[test] - fn given_empty_worker_request_when_submitting_then_return_empty_response() { - mock! { - NodeApiFactory {} - impl CreateNodeApi for NodeApiFactory { - fn create_api(&self) -> NodeApiResult; - } - } - - let mock_node_api_factory = Arc::new(MockNodeApiFactory::new()); - let temp_dir = TempDir::new().unwrap(); - let on_chain_ocall = - WorkerOnChainOCall::new(mock_node_api_factory, None, None, temp_dir.path().into()); - - let response = on_chain_ocall - .worker_request(Vec::::new().encode(), ParentchainId::Integritee.encode()) - .unwrap(); - - assert!(!response.is_empty()); // the encoded empty vector is not empty - let decoded_response: Vec = Decode::decode(&mut response.as_slice()).unwrap(); - assert!(decoded_response.is_empty()); // decode the response, and we get an empty vector again - } -} diff --git a/service/src/parentchain_handler.rs b/service/src/parentchain_handler.rs index 0bd65b362d..a03b19575b 100644 --- a/service/src/parentchain_handler.rs +++ b/service/src/parentchain_handler.rs @@ -18,13 +18,13 @@ use crate::error::{Error, ServiceResult}; use codec::{Decode, Encode}; +use core::fmt::Debug; use humantime::format_duration; -use ita_parentchain_interface::integritee::Header; +use ita_parentchain_interface::{integritee::Header, ParentchainRuntimeConfig}; 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; @@ -36,7 +36,8 @@ use sp_runtime::traits::Header as HeaderTrait; use std::{cmp::min, sync::Arc, time::Duration}; use substrate_api_client::{ ac_primitives::{Block, Header as HeaderT}, - GetChainInfo, + rpc::{Request, Subscribe}, + Api, GetChainInfo, }; const BLOCK_SYNC_BATCH_SIZE: u32 = 1000; @@ -66,20 +67,27 @@ pub trait HandleParentchain { } /// Handles the interaction between parentchain and enclave. -pub(crate) struct ParentchainHandler { - parentchain_api: ParentchainApi, +pub(crate) struct ParentchainHandler +where + u128: From, + Tip: Copy + Default + Encode + Debug, +{ + parentchain_api: Api, Client>, enclave_api: Arc, pub parentchain_init_params: ParentchainInitParams, } // #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, + u128: From, + Tip: Copy + Default + Encode + Debug, + Client: Request + Subscribe, { pub fn new( - parentchain_api: ParentchainApi, + parentchain_api: Api, Client>, enclave_api: Arc, parentchain_init_params: ParentchainInitParams, ) -> Self { @@ -88,7 +96,7 @@ where // FIXME: Necessary in the future? Fix with #1080 pub fn new_with_automatic_light_client_allocation( - parentchain_api: ParentchainApi, + parentchain_api: Api, Client>, enclave_api: Arc, id: ParentchainId, shard: ShardIdentifier, @@ -133,7 +141,7 @@ where Ok(Self::new(parentchain_api, enclave_api, parentchain_init_params)) } - pub fn parentchain_api(&self) -> &ParentchainApi { + pub fn parentchain_api(&self) -> &Api, Client> { &self.parentchain_api } @@ -142,9 +150,12 @@ where } } -impl HandleParentchain for ParentchainHandler +impl HandleParentchain for ParentchainHandler where EnclaveApi: Sidechain + EnclaveBase, + u128: From, + Tip: Copy + Default + Encode + Debug, + Client: Request + Subscribe, { fn init_parentchain_components(&self) -> ServiceResult
{ Ok(self diff --git a/service/src/prometheus_metrics.rs b/service/src/prometheus_metrics.rs index 80534a0353..77e7ae0672 100644 --- a/service/src/prometheus_metrics.rs +++ b/service/src/prometheus_metrics.rs @@ -34,13 +34,17 @@ use codec::{Decode, Encode}; use core::time::Duration; use enclave_bridge_primitives::ShardIdentifier; use frame_support::scale_info::TypeInfo; +use ita_parentchain_interface::{ + integritee::api_client_types::IntegriteeApi, target_a::api_client_types::TargetAApi, + target_b::api_client_types::TargetBApi, +}; #[cfg(feature = "attesteer")] use itc_rest_client::{ http_client::{DefaultSend, HttpClient}, rest_client::{RestClient, Url as URL}, RestGet, RestPath, }; -use itp_api_client_types::ParentchainApi; + use itp_enclave_api::{enclave_base::EnclaveBase, sidechain::Sidechain}; use itp_enclave_metrics::EnclaveMetric; use itp_types::{parentchain::ParentchainId, EnclaveFingerprint}; @@ -141,15 +145,20 @@ pub trait HandleMetrics { } /// Metrics handler implementation. This is for untrusted sources of metrics (non-enclave) -pub struct MetricsHandler { - wallets: Vec>, +pub struct MetricsHandler { + integritee_wallets: Vec>, + target_a_wallets: Vec>, + target_b_wallets: Vec>, sidechain: Arc, } #[async_trait] -impl HandleMetrics for MetricsHandler +impl HandleMetrics + for MetricsHandler where - Wallet: ParentchainAccountInfo + Send + Sync, + IntegriteeWallet: ParentchainAccountInfo + Send + Sync, + TargetAWallet: ParentchainAccountInfo + Send + Sync, + TargetBWallet: ParentchainAccountInfo + Send + Sync, Sidechain: ParentchainIntegriteeSidechainInfo + Send + Sync, { type ReplyType = String; @@ -170,24 +179,45 @@ where } } -impl MetricsHandler +impl + MetricsHandler where - Wallet: ParentchainAccountInfo + Send + Sync, + IntegriteeWallet: ParentchainAccountInfo + Send + Sync, + TargetAWallet: ParentchainAccountInfo + Send + Sync, + TargetBWallet: ParentchainAccountInfo + Send + Sync, Sidechain: ParentchainIntegriteeSidechainInfo + Send + Sync, { - pub fn new(wallets: Vec>, sidechain: Arc) -> Self { - MetricsHandler { wallets, sidechain } + pub fn new( + integritee_wallets: Vec>, + target_a_wallets: Vec>, + target_b_wallets: Vec>, + sidechain: Arc, + ) -> Self { + MetricsHandler { integritee_wallets, target_a_wallets, target_b_wallets, sidechain } } async fn update_all_account_metrics(&self) { - for wallet in &self.wallets { + for wallet in &self.integritee_wallets { + if let Err(e) = Self::update_wallet_metrics(wallet).await { + error!("Failed to update integritee wallet metrics: {:?}", e); + } + } + + for wallet in &self.target_a_wallets { + if let Err(e) = Self::update_wallet_metrics(wallet).await { + error!("Failed to update target a wallet metrics: {:?}", e); + } + } + for wallet in &self.target_b_wallets { if let Err(e) = Self::update_wallet_metrics(wallet).await { - error!("Failed to update wallet metrics: {:?}", e); + error!("Failed to update target b wallet metrics: {:?}", e); } } } - async fn update_wallet_metrics(wallet: &Wallet) -> ServiceResult<()> { + async fn update_wallet_metrics( + wallet: &Arc, + ) -> ServiceResult<()> { let balance = wallet.free_balance()?; let parentchain_id = wallet.parentchain_id()?; let account_and_role = wallet.account_and_role()?; @@ -354,17 +384,23 @@ pub fn start_prometheus_metrics_server( enclave: &Arc, tee_account_id: &AccountId32, shard: &ShardIdentifier, - integritee_rpc_api: ParentchainApi, - maybe_target_a_rpc_api: Option, - maybe_target_b_rpc_api: Option, + integritee_rpc_api: IntegriteeApi, + maybe_target_a_rpc_api: Option, + maybe_target_b_rpc_api: Option, shielding_target: Option, tokio_handle: &Handle, metrics_server_port: u16, ) where E: EnclaveBase + Sidechain, { - let mut account_info_providers: Vec> = vec![]; - account_info_providers.push(Arc::new(ParentchainAccountInfoProvider::new( + let mut integritee_account_info_providers: Vec>> = + vec![]; + let mut target_a_account_info_providers: Vec>> = + vec![]; + let mut target_b_account_info_providers: Vec>> = + vec![]; + + integritee_account_info_providers.push(Arc::new(ParentchainAccountInfoProvider::new( ParentchainId::Integritee, integritee_rpc_api.clone(), AccountAndRole::EnclaveSigner(tee_account_id.clone()), @@ -372,33 +408,56 @@ pub fn start_prometheus_metrics_server( let shielding_target = shielding_target.unwrap_or_default(); let shard_vault = enclave.get_ecc_vault_pubkey(shard).expect("shard vault must be defined by now"); - account_info_providers.push(Arc::new(ParentchainAccountInfoProvider::new( - shielding_target, - match shielding_target { - ParentchainId::Integritee => integritee_rpc_api.clone(), - ParentchainId::TargetA => maybe_target_a_rpc_api - .clone() - .expect("target A must be initialized to be used as shielding target"), - ParentchainId::TargetB => maybe_target_b_rpc_api - .clone() - .expect("target B must be initialized to be used as shielding target"), - }, - AccountAndRole::ShardVault( - enclave - .get_ecc_vault_pubkey(shard) - .expect("shard vault must be defined by now") - .into(), - ), - ))); + + match shielding_target { + ParentchainId::Integritee => + integritee_account_info_providers.push(Arc::new(ParentchainAccountInfoProvider::new( + shielding_target, + integritee_rpc_api.clone(), + AccountAndRole::ShardVault( + enclave + .get_ecc_vault_pubkey(shard) + .expect("shard vault must be defined by now") + .into(), + ), + ))), + ParentchainId::TargetA => + target_a_account_info_providers.push(Arc::new(ParentchainAccountInfoProvider::new( + shielding_target, + maybe_target_a_rpc_api + .clone() + .expect("target A must be initialized to be used as shielding target"), + AccountAndRole::ShardVault( + enclave + .get_ecc_vault_pubkey(shard) + .expect("shard vault must be defined by now") + .into(), + ), + ))), + ParentchainId::TargetB => + target_b_account_info_providers.push(Arc::new(ParentchainAccountInfoProvider::new( + shielding_target, + maybe_target_b_rpc_api + .clone() + .expect("target B must be initialized to be used as shielding target"), + AccountAndRole::ShardVault( + enclave + .get_ecc_vault_pubkey(shard) + .expect("shard vault must be defined by now") + .into(), + ), + ))), + }; + if let Some(api) = maybe_target_a_rpc_api { - account_info_providers.push(Arc::new(ParentchainAccountInfoProvider::new( + target_a_account_info_providers.push(Arc::new(ParentchainAccountInfoProvider::new( ParentchainId::TargetA, api, AccountAndRole::EnclaveSigner(tee_account_id.clone()), ))) }; if let Some(api) = maybe_target_b_rpc_api { - account_info_providers.push(Arc::new(ParentchainAccountInfoProvider::new( + target_b_account_info_providers.push(Arc::new(ParentchainAccountInfoProvider::new( ParentchainId::TargetB, api, AccountAndRole::EnclaveSigner(tee_account_id.clone()), @@ -407,8 +466,12 @@ pub fn start_prometheus_metrics_server( let sidechain_info_provider = Arc::new(ParentchainIntegriteeSidechainInfoProvider::new(integritee_rpc_api, *shard)); - let metrics_handler = - Arc::new(MetricsHandler::new(account_info_providers, sidechain_info_provider)); + let metrics_handler = Arc::new(MetricsHandler::new( + integritee_account_info_providers, + target_a_account_info_providers, + target_b_account_info_providers, + sidechain_info_provider, + )); tokio_handle.spawn(async move { if let Err(e) = start_metrics_server(metrics_handler, metrics_server_port).await { diff --git a/service/src/sidechain_setup.rs b/service/src/sidechain_setup.rs index 52a19afe10..ac99e80ed4 100644 --- a/service/src/sidechain_setup.rs +++ b/service/src/sidechain_setup.rs @@ -22,7 +22,7 @@ use crate::{ parentchain_handler::HandleParentchain, }; use futures::executor::block_on; -use itp_api_client_types::ParentchainApi; +use ita_parentchain_interface::integritee::api_client_types::IntegriteeApi; use itp_enclave_api::{enclave_base::EnclaveBase, sidechain::Sidechain}; use itp_node_api::api_client::{pallet_sidechain::PalletSidechainApi, PalletTeerexApi}; use itp_settings::{ @@ -53,7 +53,7 @@ pub trait ParentchainIntegriteeSidechainInfo { } pub struct ParentchainIntegriteeSidechainInfoProvider { - node_api: ParentchainApi, + node_api: IntegriteeApi, shard: ShardIdentifier, } @@ -91,7 +91,7 @@ impl ParentchainIntegriteeSidechainInfo for ParentchainIntegriteeSidechainInfoPr } impl ParentchainIntegriteeSidechainInfoProvider { - pub fn new(node_api: ParentchainApi, shard: ShardIdentifier) -> Self { + pub fn new(node_api: IntegriteeApi, shard: ShardIdentifier) -> Self { ParentchainIntegriteeSidechainInfoProvider { node_api, shard } } } diff --git a/service/src/teeracle/mod.rs b/service/src/teeracle/mod.rs index 910d45043f..e150635fae 100644 --- a/service/src/teeracle/mod.rs +++ b/service/src/teeracle/mod.rs @@ -17,8 +17,8 @@ use crate::{error::ServiceResult, teeracle::schedule_periodic::schedule_periodic}; use codec::{Decode, Encode}; +use ita_parentchain_interface::integritee::api_client_types::IntegriteeApi; use itp_enclave_api::teeracle_api::TeeracleApi; -use itp_node_api::api_client::ParentchainApi; use itp_types::parentchain::Hash; use itp_utils::hex::hex_encode; use log::*; @@ -69,7 +69,7 @@ pub(crate) fn schedule_periodic_reregistration_thread( /// /// Note: Puts the current thread to sleep for `period`. pub(crate) fn start_periodic_market_update( - api: &ParentchainApi, + api: &IntegriteeApi, period: Duration, enclave_api: &E, tokio_handle: &Handle, @@ -97,7 +97,7 @@ pub(crate) fn start_periodic_market_update( } fn execute_oracle_update( - node_api: &ParentchainApi, + node_api: &IntegriteeApi, tokio_handle: &Handle, get_oracle_xt: F, ) -> ServiceResult<()> diff --git a/service/src/worker.rs b/service/src/worker.rs index 97bb56be83..09f0057b75 100644 --- a/service/src/worker.rs +++ b/service/src/worker.rs @@ -14,7 +14,6 @@ limitations under the License. */ - ///! Integritee worker. Inspiration for this design came from parity's substrate Client. /// /// This should serve as a proof of concept for a potential refactoring design. Ultimately, everything @@ -23,7 +22,11 @@ use crate::{config::Config, error::Error, initialized_service::TrackInitialization}; use async_trait::async_trait; use itc_rpc_client::direct_client::{DirectApi, DirectClient as DirectWorkerApi}; -use itp_node_api::{api_client::PalletTeerexApi, node_api_factory::CreateNodeApi}; +use itp_api_client_types::{Config as NodeRuntimeConfig, Request}; +use itp_node_api::{ + api_client::PalletTeerexApi, + node_api_factory::{CreateNodeApi, NodeApiFactory}, +}; use itp_types::ShardIdentifier; use itp_utils::ToHexPrefixed; use its_primitives::types::SignedBlock as SignedSidechainBlock; @@ -33,28 +36,32 @@ use jsonrpsee::{ ws_client::WsClientBuilder, }; use log::*; -use std::sync::{Arc, RwLock}; +use std::{ + marker::PhantomData, + sync::{Arc, RwLock}, +}; +use substrate_api_client::rpc::TungsteniteRpcClient; use teerex_primitives::MultiEnclave; use url::Url as UrlType; pub type WorkerResult = Result; pub type Url = String; -pub struct Worker { +pub struct Worker { _config: Config, // unused yet, but will be used when more methods are migrated to the worker _enclave_api: Arc, - node_api_factory: Arc, + node_api_factory: Arc>, initialization_handler: Arc, peers: RwLock>, } -impl - Worker +impl + Worker { pub fn new( config: Config, enclave_api: Arc, - node_api_factory: Arc, + node_api_factory: Arc>, initialization_handler: Arc, peers: Vec, ) -> Self { @@ -75,10 +82,10 @@ pub trait AsyncBlockBroadcaster { } #[async_trait] -impl AsyncBlockBroadcaster - for Worker +impl AsyncBlockBroadcaster + for Worker where - NodeApiFactory: CreateNodeApi + Send + Sync, + NodeConfig: NodeRuntimeConfig + Send + Sync, Enclave: Send + Sync, InitializationHandler: TrackInitialization + Send + Sync, { @@ -136,10 +143,11 @@ pub trait UpdatePeers { } } -impl UpdatePeers - for Worker +impl UpdatePeers + for Worker where - NodeApiFactory: CreateNodeApi + Send + Sync, + NodeConfig: NodeRuntimeConfig, + ::ExtrinsicSigner: From, { fn search_peers(&self, shard: ShardIdentifier) -> WorkerResult> { let node_api = self @@ -189,6 +197,7 @@ mod tests { worker::{AsyncBlockBroadcaster, Worker}, }; use frame_support::assert_ok; + use ita_parentchain_interface::integritee::api_client_types::IntegriteeRuntimeConfig; use itp_node_api::node_api_factory::NodeApiFactory; use its_primitives::types::block::SignedBlock as SignedSidechainBlock; use its_test::sidechain_block_builder::{SidechainBlockBuilder, SidechainBlockBuilderTrait}; @@ -227,7 +236,7 @@ mod tests { let untrusted_worker_port = "4000".to_string(); let peers = vec![format!("ws://{}", W1_URL), format!("ws://{}", W2_URL)]; - let worker = Worker::new( + let worker = Worker::<_, IntegriteeRuntimeConfig, _, _>::new( local_worker_config(W1_URL.into(), untrusted_worker_port.clone(), "30".to_string()), Arc::new(()), Arc::new(NodeApiFactory::new( diff --git a/sidechain/consensus/aura/src/lib.rs b/sidechain/consensus/aura/src/lib.rs index ad6690c1c9..dc12651879 100644 --- a/sidechain/consensus/aura/src/lib.rs +++ b/sidechain/consensus/aura/src/lib.rs @@ -29,13 +29,11 @@ compile_error!("feature \"std\" and feature \"sgx\" cannot be enabled at the sam #[macro_use] extern crate sgx_tstd as std; -use codec::Encode; use core::marker::PhantomData; use itc_parentchain_block_import_dispatcher::triggered_dispatcher::TriggerParentchainBlockImport; use itp_ocall_api::EnclaveOnChainOCallApi; use itp_time_utils::duration_now; -use itp_utils::hex::hex_encode; use its_block_verification::slot::slot_author; use its_consensus_common::{Environment, Error as ConsensusError, Proposer}; use its_consensus_slots::{SimpleSlotWorker, Slot, SlotInfo}; @@ -252,14 +250,13 @@ impl< fn import_integritee_parentchain_blocks_until( &self, - parentchain_header_hash: &::Hash, + parentchain_header: &ParentchainBlock::Header, ) -> Result, ConsensusError> { - log::trace!(target: self.logging_target(), "import Integritee blocks until {}", hex_encode(parentchain_header_hash.encode().as_ref())); + let hash = parentchain_header.hash(); + log::trace!(target: self.logging_target(), "import Integritee blocks until {:?}: {:?}", parentchain_header.number(), hash); let maybe_parentchain_block = self .parentchain_integritee_import_trigger - .import_until(|parentchain_block| { - parentchain_block.block.hash() == *parentchain_header_hash - }) + .import_until(|parentchain_block| parentchain_block.block.hash() == hash) .map_err(|e| ConsensusError::Other(e.into()))?; Ok(maybe_parentchain_block.map(|b| b.block.header().clone())) @@ -267,16 +264,15 @@ impl< fn import_target_a_parentchain_blocks_until( &self, - parentchain_header_hash: &::Hash, + parentchain_header: &ParentchainBlock::Header, ) -> Result, ConsensusError> { - log::trace!(target: self.logging_target(), "import TargetA blocks until {}", hex_encode(parentchain_header_hash.encode().as_ref())); + let hash = parentchain_header.hash(); + log::trace!(target: self.logging_target(), "import TargetA blocks until {:?}: {:?}", parentchain_header.number(), hash); let maybe_parentchain_block = self .maybe_parentchain_target_a_import_trigger .clone() .ok_or_else(|| ConsensusError::Other("no target_a assigned".into()))? - .import_until(|parentchain_block| { - parentchain_block.block.hash() == *parentchain_header_hash - }) + .import_until(|parentchain_block| parentchain_block.block.hash() == hash) .map_err(|e| ConsensusError::Other(e.into()))?; Ok(maybe_parentchain_block.map(|b| b.block.header().clone())) @@ -284,16 +280,15 @@ impl< fn import_target_b_parentchain_blocks_until( &self, - parentchain_header_hash: &::Hash, + parentchain_header: &ParentchainBlock::Header, ) -> Result, ConsensusError> { - log::trace!(target: self.logging_target(), "import TargetB blocks until {}", hex_encode(parentchain_header_hash.encode().as_ref())); + let hash = parentchain_header.hash(); + log::trace!(target: self.logging_target(), "import TargetB blocks until {:?}: {:?}", parentchain_header.number(), hash); let maybe_parentchain_block = self .maybe_parentchain_target_b_import_trigger .clone() .ok_or_else(|| ConsensusError::Other("no target_b assigned".into()))? - .import_until(|parentchain_block| { - parentchain_block.block.hash() == *parentchain_header_hash - }) + .import_until(|parentchain_block| parentchain_block.block.hash() == hash) .map_err(|e| ConsensusError::Other(e.into()))?; Ok(maybe_parentchain_block.map(|b| b.block.header().clone())) diff --git a/sidechain/consensus/slots/src/lib.rs b/sidechain/consensus/slots/src/lib.rs index 14c404beb6..47fd911bc6 100644 --- a/sidechain/consensus/slots/src/lib.rs +++ b/sidechain/consensus/slots/src/lib.rs @@ -170,17 +170,17 @@ pub trait SimpleSlotWorker { /// None is returned. fn import_integritee_parentchain_blocks_until( &self, - last_imported_parentchain_header: &::Hash, + last_imported_parentchain_header: &ParentchainBlock::Header, ) -> Result, ConsensusError>; fn import_target_a_parentchain_blocks_until( &self, - last_imported_parentchain_header: &::Hash, + last_imported_parentchain_header: &ParentchainBlock::Header, ) -> Result, ConsensusError>; fn import_target_b_parentchain_blocks_until( &self, - last_imported_parentchain_header: &::Hash, + last_imported_parentchain_header: &ParentchainBlock::Header, ) -> Result, ConsensusError>; /// Peek the parentchain import queue for the latest block in queue. @@ -282,9 +282,9 @@ pub trait SimpleSlotWorker { let _claim = self.claim_slot(&latest_integritee_parentchain_header, slot, &epoch_data)?; // Import the peeked parentchain header(s). - let last_imported_integritee_header = match self.import_integritee_parentchain_blocks_until( - &latest_integritee_parentchain_header.hash(), - ) { + let last_imported_integritee_header = match self + .import_integritee_parentchain_blocks_until(&latest_integritee_parentchain_header) + { Ok(h) => h, Err(e) => { debug!( @@ -302,7 +302,7 @@ pub trait SimpleSlotWorker { let maybe_last_imported_target_a_header = if let Some(ref header) = maybe_latest_target_a_parentchain_header { - match self.import_target_a_parentchain_blocks_until(&header.hash()) { + match self.import_target_a_parentchain_blocks_until(header) { Ok(Some(h)) => Some(h), Ok(None) => None, Err(e) => { @@ -324,7 +324,7 @@ pub trait SimpleSlotWorker { let maybe_last_imported_target_b_header = if let Some(ref header) = maybe_latest_target_b_parentchain_header { - match self.import_target_b_parentchain_blocks_until(&header.hash()) { + match self.import_target_b_parentchain_blocks_until(header) { Ok(Some(h)) => Some(h), Ok(None) => None, Err(e) => { diff --git a/sidechain/consensus/slots/src/mocks.rs b/sidechain/consensus/slots/src/mocks.rs index 8f4be9ea4f..7e458adc7e 100644 --- a/sidechain/consensus/slots/src/mocks.rs +++ b/sidechain/consensus/slots/src/mocks.rs @@ -96,7 +96,7 @@ where fn import_integritee_parentchain_blocks_until( &self, - _last_imported_parentchain_header: &::Hash, + _parentchain_header: &B::Header, ) -> Result> { todo!() } @@ -107,7 +107,7 @@ where fn import_target_a_parentchain_blocks_until( &self, - _last_imported_parentchain_header: &::Hash, + _parentchain_header: &B::Header, ) -> Result> { todo!() } @@ -118,7 +118,7 @@ where fn import_target_b_parentchain_blocks_until( &self, - _last_imported_parentchain_header: &::Hash, + _parentchain_header: &B::Header, ) -> Result> { todo!() } diff --git a/sidechain/consensus/slots/src/slots.rs b/sidechain/consensus/slots/src/slots.rs index 54dcc23349..c988e7969f 100644 --- a/sidechain/consensus/slots/src/slots.rs +++ b/sidechain/consensus/slots/src/slots.rs @@ -19,6 +19,7 @@ //! //! This is used instead of `futures_timer::Interval` because it was unreliable. +use core::fmt::{Debug, Formatter}; use itp_time_utils::duration_now; use its_block_verification::slot::slot_from_timestamp_and_duration; use its_consensus_common::Error as ConsensusError; @@ -27,8 +28,8 @@ use its_primitives::traits::{ }; use lazy_static::lazy_static; use log::warn; -use sp_runtime::traits::Block as ParentchainBlockTrait; -use std::time::Duration; +use sp_runtime::traits::{Block as ParentchainBlockTrait, Header}; +use std::{string::String, time::Duration}; #[cfg(all(not(feature = "std"), feature = "sgx"))] use std::sync::SgxRwLock as RwLock; @@ -53,7 +54,7 @@ pub fn time_until_next_slot(slot_duration: Duration) -> Duration { } /// Information about a slot. -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct SlotInfo { /// The slot number as found in the inherent data. pub slot: Slot, @@ -71,6 +72,33 @@ pub struct SlotInfo { pub maybe_last_imported_target_b_parentchain_head: Option, } +fn header_info_fmt(header: &P::Header) -> String { + format!("number: {:?}, hash: {:?}", header.number(), header.hash()) +} + +impl Debug for SlotInfo

{ + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + write!( + f, + "SlotInfo {{ slot: {:?}, timestamp: {:?}, \ + duration: {:?}, ends_at: {:?} integritee_head: ({:?}),\ + maybe_last_imported_target_a_parentchain_head: ({:?}), \ + maybe_last_imported_target_b_parentchain_head: ({:?}) }}", + self.slot, + self.timestamp, + self.duration, + self.ends_at, + header_info_fmt::

(&self.last_imported_integritee_parentchain_head), + self.maybe_last_imported_target_a_parentchain_head + .as_ref() + .map(header_info_fmt::

), + self.maybe_last_imported_target_b_parentchain_head + .as_ref() + .map(header_info_fmt::

), + ) + } +} + impl SlotInfo { /// Create a new [`SlotInfo`]. /// diff --git a/sidechain/peer-fetch/src/untrusted_peer_fetch.rs b/sidechain/peer-fetch/src/untrusted_peer_fetch.rs index cfdabbfbf4..c220adb0c7 100644 --- a/sidechain/peer-fetch/src/untrusted_peer_fetch.rs +++ b/sidechain/peer-fetch/src/untrusted_peer_fetch.rs @@ -14,12 +14,14 @@ limitations under the License. */ - use crate::error::{Error, Result}; use itc_rpc_client::direct_client::{DirectApi, DirectClient as DirectWorkerApi}; -use itp_node_api::{api_client::PalletTeerexApi, node_api_factory::CreateNodeApi}; +use itp_node_api::{ + api_client::{traits::Request, Config, PalletTeerexApi}, + node_api_factory::CreateNodeApi, +}; use its_primitives::types::ShardIdentifier; -use std::sync::Arc; +use std::{marker::PhantomData, sync::Arc}; /// Trait to fetch untrusted peer servers. pub trait FetchUntrustedPeers { @@ -29,22 +31,25 @@ pub trait FetchUntrustedPeers { /// Fetches the untrusted peer servers /// FIXME: Should probably be combined with the peer fetch in /// service/src/worker.rs -pub struct UntrustedPeerFetcher { +pub struct UntrustedPeerFetcher { node_api_factory: Arc, + _phantom: PhantomData<(NodeConfig, Client)>, } -impl UntrustedPeerFetcher +impl + UntrustedPeerFetcher where - NodeApiFactory: CreateNodeApi + Send + Sync, + NodeApiFactory: CreateNodeApi + Send + Sync, { pub fn new(node_api: Arc) -> Self { - UntrustedPeerFetcher { node_api_factory: node_api } + UntrustedPeerFetcher { node_api_factory: node_api, _phantom: Default::default() } } } -impl FetchUntrustedPeers for UntrustedPeerFetcher +impl FetchUntrustedPeers + for UntrustedPeerFetcher where - NodeApiFactory: CreateNodeApi + Send + Sync, + NodeApiFactory: CreateNodeApi + Send + Sync, { fn get_untrusted_peer_url_of_shard(&self, shard: &ShardIdentifier) -> Result { let node_api = self.node_api_factory.create_api()?; diff --git a/sidechain/state/src/impls.rs b/sidechain/state/src/impls.rs index b69727085c..a4d84d7249 100644 --- a/sidechain/state/src/impls.rs +++ b/sidechain/state/src/impls.rs @@ -23,7 +23,7 @@ use core::fmt::Debug; use frame_support::ensure; use itp_sgx_externalities::{SgxExternalitiesTrait, StateHash}; use itp_storage::keys::storage_value_key; -use log::{debug, error, info}; +use log::{debug, error, info, trace}; use sp_io::{storage, KillStorageResult}; impl SidechainState for T @@ -37,8 +37,8 @@ where info!("Current state size: {}", self.state().encoded_size()); debug!("Current hash: {}", self.hash()); debug!("State_payload hash: {}", state_payload.state_hash_apriori()); - debug!("self is: {:?}", &self); - debug!("state_payload is: {:?}", &state_payload); + trace!("self is: {:?}", &self); + trace!("state_payload is: {:?}", &state_payload); ensure!(self.hash() == state_payload.state_hash_apriori(), Error::InvalidAprioriHash); self.execute_with(|| {