From 061aff2e2459f61b5c3438295d7136cbf4b0629c Mon Sep 17 00:00:00 2001 From: brenzi Date: Mon, 15 Jan 2024 16:49:39 +0100 Subject: [PATCH] propagate parentchain(s) timestamps (#1572) * filter timestamp set extrinsic and add trusted call to set timestamp * use all extrinsic parsers to propagate parentchain timestamps * extend to target_b and generically solve parentchain instance type branching * lift patches * split out shard creation into module * WIP: get shard creation info back to service * implemented shard creation info refactoring. untested * initialize creation timestamp (has ~3 blocks delay to creation number * fix secondary validateer handling * cargo fix * carg fix ++ * clippy * fmt --- Cargo.lock | 32 ++-- Cargo.toml | 26 ++-- .../src/{integritee => }/extrinsic_parser.rs | 5 +- .../src/indirect_calls/mod.rs | 1 + .../src/indirect_calls/timestamp_set.rs | 62 ++++++++ .../src/integritee/mod.rs | 55 +++---- app-libs/parentchain-interface/src/lib.rs | 19 ++- .../src/target_a/extrinsic_parser.rs | 77 ---------- .../parentchain-interface/src/target_a/mod.rs | 67 ++++---- .../src/target_b/extrinsic_parser.rs | 77 ---------- .../parentchain-interface/src/target_b/mod.rs | 66 +++++--- app-libs/sgx-runtime/Cargo.toml | 2 +- app-libs/sgx-runtime/src/lib.rs | 6 +- app-libs/stf/Cargo.toml | 3 +- app-libs/stf/src/helpers.rs | 34 +++++ app-libs/stf/src/stf_sgx.rs | 59 ++++++- app-libs/stf/src/trusted_call.rs | 66 +++++++- cli/Cargo.toml | 14 +- core-primitives/enclave-api/Cargo.toml | 3 +- core-primitives/enclave-api/ffi/src/lib.rs | 2 +- .../enclave-api/src/enclave_base.rs | 23 ++- core-primitives/node-api/metadata/src/lib.rs | 7 +- .../node-api/metadata/src/metadata_mocks.rs | 11 ++ .../node-api/metadata/src/pallet_system.rs | 20 +-- .../node-api/metadata/src/pallet_timestamp.rs | 30 ++++ core-primitives/stf-executor/src/executor.rs | 4 - core-primitives/stf-interface/src/lib.rs | 34 ++++- .../stf-interface/src/parentchain_pallet.rs | 6 + core-primitives/types/Cargo.toml | 6 +- core/parentchain/block-importer/Cargo.toml | 2 + .../block-importer/src/block_importer.rs | 25 ++- enclave-runtime/Cargo.lock | 16 +- enclave-runtime/Cargo.toml | 32 ++-- enclave-runtime/Enclave.edl | 2 +- .../src/initialization/global_components.rs | 6 +- .../src/initialization/parentchain/common.rs | 13 +- .../parentchain/integritee_parachain.rs | 7 +- .../parentchain/integritee_solochain.rs | 7 +- .../src/initialization/parentchain/mod.rs | 62 ++++---- .../parentchain/target_a_parachain.rs | 3 + .../parentchain/target_a_solochain.rs | 3 + .../parentchain/target_b_parachain.rs | 3 + .../parentchain/target_b_solochain.rs | 3 + enclave-runtime/src/lib.rs | 124 +-------------- enclave-runtime/src/shard_creation_info.rs | 144 ++++++++++++++++++ enclave-runtime/src/test/top_pool_tests.rs | 2 +- service/Cargo.toml | 9 +- service/src/main_impl.rs | 9 +- service/src/parentchain_handler.rs | 30 ++-- service/src/tests/mocks/enclave_api_mock.rs | 6 +- 50 files changed, 777 insertions(+), 548 deletions(-) rename app-libs/parentchain-interface/src/{integritee => }/extrinsic_parser.rs (90%) create mode 100644 app-libs/parentchain-interface/src/indirect_calls/timestamp_set.rs delete mode 100644 app-libs/parentchain-interface/src/target_a/extrinsic_parser.rs delete mode 100644 app-libs/parentchain-interface/src/target_b/extrinsic_parser.rs create mode 100644 core-primitives/node-api/metadata/src/pallet_timestamp.rs create mode 100644 enclave-runtime/src/shard_creation_info.rs diff --git a/Cargo.lock b/Cargo.lock index 8fba92e52a..cae88e4995 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -740,7 +740,7 @@ dependencies = [ [[package]] name = "common-primitives" version = "0.1.0" -source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.10-polkadot-v0.9.42#91321c805edc1e94d9ba04a5a6d74d63cf6c59e6" +source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.11-polkadot-v0.9.42#094b1e982b4637ebfbf5afb985100417215d49a0" dependencies = [ "derive_more", "parity-scale-codec", @@ -1216,7 +1216,7 @@ dependencies = [ [[package]] name = "enclave-bridge-primitives" version = "0.1.0" -source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.10-polkadot-v0.9.42#91321c805edc1e94d9ba04a5a6d74d63cf6c59e6" +source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.11-polkadot-v0.9.42#094b1e982b4637ebfbf5afb985100417215d49a0" dependencies = [ "common-primitives", "log 0.4.20", @@ -2581,7 +2581,7 @@ dependencies = [ [[package]] name = "integritee-cli" -version = "0.12.10" +version = "0.12.11" dependencies = [ "array-bytes 6.1.0", "base58", @@ -2631,7 +2631,7 @@ dependencies = [ [[package]] name = "integritee-service" -version = "0.12.10" +version = "0.12.11" dependencies = [ "anyhow", "async-trait", @@ -2655,6 +2655,7 @@ dependencies = [ "itp-enclave-metrics", "itp-node-api", "itp-settings", + "itp-stf-interface", "itp-storage", "itp-types", "itp-utils", @@ -2859,6 +2860,7 @@ dependencies = [ "itp-node-api", "itp-node-api-metadata", "itp-sgx-externalities", + "itp-sgx-runtime-primitives", "itp-stf-interface", "itp-stf-primitives", "itp-storage", @@ -2957,6 +2959,7 @@ dependencies = [ "itc-parentchain-light-client", "itp-extrinsics-factory", "itp-stf-executor", + "itp-stf-interface", "itp-types", "log 0.4.20", "parity-scale-codec", @@ -3227,6 +3230,7 @@ dependencies = [ "itc-parentchain", "itp-enclave-api-ffi", "itp-settings", + "itp-stf-interface", "itp-storage", "itp-types", "log 0.4.20", @@ -5154,7 +5158,7 @@ dependencies = [ [[package]] name = "pallet-enclave-bridge" version = "0.12.0" -source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.10-polkadot-v0.9.42#91321c805edc1e94d9ba04a5a6d74d63cf6c59e6" +source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.11-polkadot-v0.9.42#094b1e982b4637ebfbf5afb985100417215d49a0" dependencies = [ "enclave-bridge-primitives", "frame-support", @@ -5212,8 +5216,8 @@ dependencies = [ [[package]] name = "pallet-parentchain" -version = "0.10.0" -source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.10-polkadot-v0.9.42#91321c805edc1e94d9ba04a5a6d74d63cf6c59e6" +version = "0.11.0" +source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.11-polkadot-v0.9.42#094b1e982b4637ebfbf5afb985100417215d49a0" dependencies = [ "frame-support", "frame-system", @@ -5231,7 +5235,7 @@ dependencies = [ [[package]] name = "pallet-sidechain" version = "0.11.0" -source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.10-polkadot-v0.9.42#91321c805edc1e94d9ba04a5a6d74d63cf6c59e6" +source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.11-polkadot-v0.9.42#094b1e982b4637ebfbf5afb985100417215d49a0" dependencies = [ "enclave-bridge-primitives", "frame-support", @@ -5268,7 +5272,7 @@ dependencies = [ [[package]] name = "pallet-teeracle" version = "0.1.0" -source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.10-polkadot-v0.9.42#91321c805edc1e94d9ba04a5a6d74d63cf6c59e6" +source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.11-polkadot-v0.9.42#094b1e982b4637ebfbf5afb985100417215d49a0" dependencies = [ "frame-support", "frame-system", @@ -5288,7 +5292,7 @@ dependencies = [ [[package]] name = "pallet-teerex" version = "0.10.0" -source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.10-polkadot-v0.9.42#91321c805edc1e94d9ba04a5a6d74d63cf6c59e6" +source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.11-polkadot-v0.9.42#094b1e982b4637ebfbf5afb985100417215d49a0" dependencies = [ "frame-support", "frame-system", @@ -6813,7 +6817,7 @@ dependencies = [ [[package]] name = "sgx-verify" version = "0.1.4" -source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.10-polkadot-v0.9.42#91321c805edc1e94d9ba04a5a6d74d63cf6c59e6" +source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.11-polkadot-v0.9.42#094b1e982b4637ebfbf5afb985100417215d49a0" dependencies = [ "base64 0.13.1", "chrono 0.4.26", @@ -7088,7 +7092,7 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "sidechain-primitives" version = "0.1.0" -source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.10-polkadot-v0.9.42#91321c805edc1e94d9ba04a5a6d74d63cf6c59e6" +source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.11-polkadot-v0.9.42#094b1e982b4637ebfbf5afb985100417215d49a0" dependencies = [ "parity-scale-codec", "scale-info", @@ -7973,7 +7977,7 @@ checksum = "1d2faeef5759ab89935255b1a4cd98e0baf99d1085e37d36599c625dac49ae8e" [[package]] name = "teeracle-primitives" version = "0.1.0" -source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.10-polkadot-v0.9.42#91321c805edc1e94d9ba04a5a6d74d63cf6c59e6" +source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.11-polkadot-v0.9.42#094b1e982b4637ebfbf5afb985100417215d49a0" dependencies = [ "common-primitives", "sp-std", @@ -7983,7 +7987,7 @@ dependencies = [ [[package]] name = "teerex-primitives" version = "0.1.0" -source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.10-polkadot-v0.9.42#91321c805edc1e94d9ba04a5a6d74d63cf6c59e6" +source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.11-polkadot-v0.9.42#094b1e982b4637ebfbf5afb985100417215d49a0" dependencies = [ "common-primitives", "derive_more", diff --git a/Cargo.toml b/Cargo.toml index 4eb585e3a1..cdae016af3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,16 +94,16 @@ ring = { git = "https://github.com/betrusted-io/ring-xous", branch = "0.16.20-cl #substrate-client-keystore = { path = "../../scs/substrate-api-client/client-keystore" } #[patch."https://github.com/integritee-network/pallets.git"] -#pallet-claims = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#pallet-enclave-bridge = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#pallet-teerex = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#pallet-sidechain = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#pallet-parentchain = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#sgx-verify = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#pallet-teeracle = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#test-utils = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#claims-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#enclave-bridge-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#teerex-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#teeracle-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#common-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } +#pallet-claims = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#pallet-enclave-bridge = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#pallet-teerex = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#pallet-sidechain = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#pallet-parentchain = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#sgx-verify = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#pallet-teeracle = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#test-utils = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#claims-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#enclave-bridge-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#teerex-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#teeracle-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#common-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } diff --git a/app-libs/parentchain-interface/src/integritee/extrinsic_parser.rs b/app-libs/parentchain-interface/src/extrinsic_parser.rs similarity index 90% rename from app-libs/parentchain-interface/src/integritee/extrinsic_parser.rs rename to app-libs/parentchain-interface/src/extrinsic_parser.rs index 925aca30ee..de9caf318b 100644 --- a/app-libs/parentchain-interface/src/integritee/extrinsic_parser.rs +++ b/app-libs/parentchain-interface/src/extrinsic_parser.rs @@ -18,16 +18,13 @@ use codec::{Decode, Encode}; use core::marker::PhantomData; use itp_node_api::api_client::{ - Address, CallIndex, PairSignature, ParentchainSignedExtra, Signature, UncheckedExtrinsicV4, + Address, CallIndex, PairSignature, Signature, UncheckedExtrinsicV4, }; pub struct ExtrinsicParser { _phantom: PhantomData, } -/// Parses the extrinsics corresponding to the parentchain. -pub type ParentchainExtrinsicParser = ExtrinsicParser; - /// Partially interpreted extrinsic containing the `signature` and the `call_index` whereas /// the `call_args` remain in encoded form. /// diff --git a/app-libs/parentchain-interface/src/indirect_calls/mod.rs b/app-libs/parentchain-interface/src/indirect_calls/mod.rs index 89095a5cf5..14eabcfbb0 100644 --- a/app-libs/parentchain-interface/src/indirect_calls/mod.rs +++ b/app-libs/parentchain-interface/src/indirect_calls/mod.rs @@ -17,6 +17,7 @@ pub mod invoke; pub mod shield_funds; +pub mod timestamp_set; pub mod transfer_to_alice_shields_funds; pub use invoke::InvokeArgs; diff --git a/app-libs/parentchain-interface/src/indirect_calls/timestamp_set.rs b/app-libs/parentchain-interface/src/indirect_calls/timestamp_set.rs new file mode 100644 index 0000000000..64cf0dd600 --- /dev/null +++ b/app-libs/parentchain-interface/src/indirect_calls/timestamp_set.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. + +*/ + +use crate::{Integritee, ParentchainInstance, TargetA, TargetB}; +use codec::{Compact, Decode, Encode}; +use core::{any::TypeId, marker::PhantomData}; +use ita_stf::{Getter, TrustedCall, TrustedCallSigned}; +use itc_parentchain_indirect_calls_executor::{ + error::{Error, Result}, + IndirectDispatch, +}; +use itp_stf_primitives::{traits::IndirectExecutor, types::TrustedOperation}; +use itp_types::{parentchain::ParentchainId, Moment}; +use log::info; + +#[derive(Debug, Clone, Encode, Decode, Eq, PartialEq)] +pub struct TimestampSetArgs { + now: Compact, + _phantom: PhantomData, +} + +impl, I: ParentchainInstance + 'static> + IndirectDispatch for TimestampSetArgs +{ + fn dispatch(&self, executor: &Executor) -> Result<()> { + info!("Found TimestampSet extrinsic in block: now = {:?}", self.now); + let enclave_account_id = executor.get_enclave_account()?; + let parentchain_id = if TypeId::of::() == TypeId::of::() { + ParentchainId::Integritee + } else if TypeId::of::() == TypeId::of::() { + ParentchainId::TargetA + } else if TypeId::of::() == TypeId::of::() { + ParentchainId::TargetB + } else { + return Err(Error::Other("unknown parentchain instance".into())) + }; + let trusted_call = + TrustedCall::timestamp_set(enclave_account_id, self.now.0, parentchain_id); + let shard = executor.get_default_shard(); + let signed_trusted_call = executor.sign_call_with_self(&trusted_call, &shard)?; + let trusted_operation = + TrustedOperation::::indirect_call(signed_trusted_call); + + let encrypted_trusted_call = executor.encrypt(&trusted_operation.encode())?; + executor.submit_trusted_call(shard, encrypted_trusted_call); + Ok(()) + } +} diff --git a/app-libs/parentchain-interface/src/integritee/mod.rs b/app-libs/parentchain-interface/src/integritee/mod.rs index 8fe0ef1e0c..00c350cf20 100644 --- a/app-libs/parentchain-interface/src/integritee/mod.rs +++ b/app-libs/parentchain-interface/src/integritee/mod.rs @@ -18,39 +18,47 @@ mod event_filter; mod event_handler; -mod extrinsic_parser; - use crate::{ decode_and_log_error, - indirect_calls::{invoke::InvokeArgs, shield_funds::ShieldFundsArgs}, - integritee::extrinsic_parser::ParseExtrinsic, + extrinsic_parser::ParseExtrinsic, + indirect_calls::{ + invoke::InvokeArgs, shield_funds::ShieldFundsArgs, timestamp_set::TimestampSetArgs, + }, + Integritee, }; use codec::{Decode, Encode}; -use core::marker::PhantomData; pub use event_filter::FilterableEvents; pub use event_handler::ParentchainEventHandler; -pub use extrinsic_parser::ParentchainExtrinsicParser; use ita_stf::TrustedCallSigned; use itc_parentchain_indirect_calls_executor::{ error::{Error, Result}, filter_metadata::FilterIntoDataFrom, IndirectDispatch, }; -use itp_node_api::metadata::NodeMetadataTrait; +use itp_api_client_types::ParentchainSignedExtra; +use itp_node_api::metadata::{ + pallet_enclave_bridge::EnclaveBridgeCallIndexes, pallet_timestamp::TimestampCallIndexes, +}; use itp_stf_primitives::traits::IndirectExecutor; -use log::trace; +use log::*; use sp_runtime::traits::BlakeTwo256; pub type BlockNumber = u32; pub type Header = sp_runtime::generic::Header; +use crate::extrinsic_parser::ExtrinsicParser; pub use itp_types::parentchain::{AccountId, Balance, Hash}; + pub type Signature = sp_runtime::MultiSignature; +/// Parses the extrinsics corresponding to the parentchain. +pub type ParentchainExtrinsicParser = ExtrinsicParser; + /// The default indirect call (extrinsic-triggered) of the Integritee-Parachain. #[derive(Debug, Clone, Encode, Decode, Eq, PartialEq)] pub enum IndirectCall { ShieldFunds(ShieldFundsArgs), Invoke(InvokeArgs), + TimestampSet(TimestampSetArgs), } impl> @@ -61,22 +69,19 @@ impl> match self { IndirectCall::ShieldFunds(shieldfunds_args) => shieldfunds_args.dispatch(executor), IndirectCall::Invoke(invoke_args) => invoke_args.dispatch(executor), + IndirectCall::TimestampSet(timestamp_set_args) => timestamp_set_args.dispatch(executor), } } } /// Default filter we use for the Integritee-Parachain. -pub struct ShieldFundsAndInvokeFilter { - _phantom: PhantomData, -} +pub struct ExtrinsicFilter {} -impl FilterIntoDataFrom - for ShieldFundsAndInvokeFilter -where - ExtrinsicParser: ParseExtrinsic, +impl FilterIntoDataFrom + for ExtrinsicFilter { type Output = IndirectCall; - type ParseParentchainMetadata = ExtrinsicParser; + type ParseParentchainMetadata = ParentchainExtrinsicParser; fn filter_into_from_metadata( encoded_data: &[u8], @@ -89,27 +94,25 @@ where let xt = match Self::ParseParentchainMetadata::parse(call_mut) { Ok(xt) => xt, Err(e) => { - log::error!( - "[ShieldFundsAndInvokeFilter] Could not parse parentchain extrinsic: {:?}", - e - ); + error!("ExtrinsicFilter: Could not parse parentchain extrinsic: {:?}", e); return None }, }; let index = xt.call_index; let call_args = &mut &xt.call_args[..]; - log::trace!( - "[ShieldFundsAndInvokeFilter] attempting to execute indirect call with index {:?}", - index - ); + trace!("ExtrinsicFilter: attempting to execute indirect call with index {:?}", index); if index == metadata.shield_funds_call_indexes().ok()? { - log::debug!("executing shield funds call"); + debug!("ExtrinsicFilter: executing shield funds call"); let args = decode_and_log_error::(call_args)?; Some(IndirectCall::ShieldFunds(args)) } else if index == metadata.invoke_call_indexes().ok()? { - log::debug!("executing invoke call"); + debug!("ExtrinsicFilter: executing invoke call"); let args = decode_and_log_error::(call_args)?; Some(IndirectCall::Invoke(args)) + } else if index == metadata.timestamp_set_call_indexes().ok()? { + debug!("ExtrinsicFilter: found timestamp set extrinsic"); + let args = decode_and_log_error::>(call_args)?; + Some(IndirectCall::TimestampSet(args)) } else { None } diff --git a/app-libs/parentchain-interface/src/lib.rs b/app-libs/parentchain-interface/src/lib.rs index 5feeb20e96..e2e0582bf7 100644 --- a/app-libs/parentchain-interface/src/lib.rs +++ b/app-libs/parentchain-interface/src/lib.rs @@ -21,20 +21,35 @@ #[cfg(all(not(feature = "std"), feature = "sgx"))] extern crate sgx_tstd as std; -use codec::Decode; +use codec::{Decode, Encode}; #[cfg(feature = "std")] pub mod event_subscriber; +pub mod extrinsic_parser; pub mod indirect_calls; pub mod integritee; pub mod target_a; pub mod target_b; +pub trait ParentchainInstance {} + +#[derive(Debug, Clone, Encode, Decode, Eq, PartialEq)] +pub struct Integritee; +impl ParentchainInstance for Integritee {} + +#[derive(Debug, Clone, Encode, Decode, Eq, PartialEq)] +pub struct TargetA; +impl ParentchainInstance for TargetA {} + +#[derive(Debug, Clone, Encode, Decode, Eq, PartialEq)] +pub struct TargetB; +impl ParentchainInstance for TargetB {} + pub fn decode_and_log_error(encoded: &mut &[u8]) -> Option { match V::decode(encoded) { Ok(v) => Some(v), Err(e) => { - log::warn!("Could not decode. {:?}", e); + log::warn!("Could not decode. {:?}: raw: {:?}", e, encoded); None }, } diff --git a/app-libs/parentchain-interface/src/target_a/extrinsic_parser.rs b/app-libs/parentchain-interface/src/target_a/extrinsic_parser.rs deleted file mode 100644 index 925aca30ee..0000000000 --- a/app-libs/parentchain-interface/src/target_a/extrinsic_parser.rs +++ /dev/null @@ -1,77 +0,0 @@ -/* - 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. - -*/ - -use codec::{Decode, Encode}; -use core::marker::PhantomData; -use itp_node_api::api_client::{ - Address, CallIndex, PairSignature, ParentchainSignedExtra, Signature, UncheckedExtrinsicV4, -}; - -pub struct ExtrinsicParser { - _phantom: PhantomData, -} - -/// Parses the extrinsics corresponding to the parentchain. -pub type ParentchainExtrinsicParser = ExtrinsicParser; - -/// Partially interpreted extrinsic containing the `signature` and the `call_index` whereas -/// the `call_args` remain in encoded form. -/// -/// Intended for usage, where the actual `call_args` form is unknown. -pub struct SemiOpaqueExtrinsic<'a, SignedExtra> { - /// Signature of the Extrinsic. - pub signature: Signature, - /// Call index of the dispatchable. - pub call_index: CallIndex, - /// Encoded arguments of the dispatchable corresponding to the `call_index`. - pub call_args: &'a [u8], -} - -/// Trait to extract signature and call indexes of an encoded [UncheckedExtrinsicV4]. -pub trait ParseExtrinsic { - /// Signed extra of the extrinsic. - type SignedExtra; - - fn parse(encoded_call: &[u8]) -> Result, codec::Error>; -} - -impl ParseExtrinsic for ExtrinsicParser -where - SignedExtra: Decode + Encode, -{ - type SignedExtra = SignedExtra; - - /// Extract a call index of an encoded call. - fn parse(encoded_call: &[u8]) -> Result, codec::Error> { - let call_mut = &mut &encoded_call[..]; - - // `()` is a trick to stop decoding after the call index. So the remaining bytes - // of `call` after decoding only contain the parentchain's dispatchable's arguments. - let xt = UncheckedExtrinsicV4::< - Address, - (CallIndex, ()), - PairSignature, - Self::SignedExtra, - >::decode(call_mut)?; - - Ok(SemiOpaqueExtrinsic { - signature: xt.signature, - call_index: xt.function.0, - call_args: call_mut, - }) - } -} diff --git a/app-libs/parentchain-interface/src/target_a/mod.rs b/app-libs/parentchain-interface/src/target_a/mod.rs index 3bc15498b3..d8d804d42f 100644 --- a/app-libs/parentchain-interface/src/target_a/mod.rs +++ b/app-libs/parentchain-interface/src/target_a/mod.rs @@ -16,64 +16,77 @@ */ mod event_filter; mod event_handler; -mod extrinsic_parser; -use crate::indirect_calls::transfer_to_alice_shields_funds::TransferToAliceShieldsFundsArgs; +use crate::{ + decode_and_log_error, + extrinsic_parser::{ExtrinsicParser, ParseExtrinsic}, + indirect_calls::timestamp_set::TimestampSetArgs, + TargetA, +}; use codec::{Decode, Encode}; -use core::marker::PhantomData; pub use event_filter::FilterableEvents; pub use event_handler::ParentchainEventHandler; -pub use extrinsic_parser::ParentchainExtrinsicParser; -use extrinsic_parser::ParseExtrinsic; use ita_stf::TrustedCallSigned; use itc_parentchain_indirect_calls_executor::{ error::{Error, Result}, filter_metadata::FilterIntoDataFrom, IndirectDispatch, }; -use itp_node_api::metadata::pallet_balances::BalancesCallIndexes; +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; + /// The default indirect call (extrinsic-triggered) of the Target-A-Parachain. #[derive(Debug, Clone, Encode, Decode, Eq, PartialEq)] pub enum IndirectCall { - TransferToAliceShieldsFunds(TransferToAliceShieldsFundsArgs), + TimestampSet(TimestampSetArgs), } impl> IndirectDispatch for IndirectCall { - fn dispatch(&self, _executor: &Executor) -> Result<()> { - debug!("shielding from TargetA extrinsic to Alice suppressed"); - /* + fn dispatch(&self, executor: &Executor) -> Result<()> { trace!("dispatching indirect call {:?}", self); match self { - IndirectCall::TransferToAliceShieldsFunds(args) => args.dispatch(executor), + IndirectCall::TimestampSet(timestamp_set_args) => timestamp_set_args.dispatch(executor), } - - */ - Ok(()) } } -pub struct TargetAExtrinsicFilter { - _phantom: PhantomData, -} +pub struct ExtrinsicFilter {} -impl FilterIntoDataFrom - for TargetAExtrinsicFilter -where - ExtrinsicParser: ParseExtrinsic, -{ +impl FilterIntoDataFrom for ExtrinsicFilter { type Output = IndirectCall; - type ParseParentchainMetadata = ExtrinsicParser; + type ParseParentchainMetadata = ParentchainExtrinsicParser; fn filter_into_from_metadata( - _encoded_data: &[u8], - _metadata: &NodeMetadata, + encoded_data: &[u8], + metadata: &NodeMetadata, ) -> Option { - warn!("no indirect calls filter has been implemented for target_a"); - None + let call_mut = &mut &encoded_data[..]; + + // Todo: the filter should not need to parse, only filter. This should directly be configured + // in the indirect executor. + let xt = match Self::ParseParentchainMetadata::parse(call_mut) { + Ok(xt) => xt, + Err(e) => { + error!("ExtrinsicFilter: Could not parse parentchain extrinsic: {:?}", e); + return None + }, + }; + let index = xt.call_index; + let call_args = &mut &xt.call_args[..]; + trace!("ExtrinsicFilter: attempting to execute indirect call with index {:?}", index); + if index == metadata.timestamp_set_call_indexes().ok()? { + debug!("ExtrinsicFilter: found timestamp set extrinsic"); + let args = decode_and_log_error::>(call_args)?; + Some(IndirectCall::TimestampSet(args)) + } else { + None + } } } diff --git a/app-libs/parentchain-interface/src/target_b/extrinsic_parser.rs b/app-libs/parentchain-interface/src/target_b/extrinsic_parser.rs deleted file mode 100644 index 925aca30ee..0000000000 --- a/app-libs/parentchain-interface/src/target_b/extrinsic_parser.rs +++ /dev/null @@ -1,77 +0,0 @@ -/* - 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. - -*/ - -use codec::{Decode, Encode}; -use core::marker::PhantomData; -use itp_node_api::api_client::{ - Address, CallIndex, PairSignature, ParentchainSignedExtra, Signature, UncheckedExtrinsicV4, -}; - -pub struct ExtrinsicParser { - _phantom: PhantomData, -} - -/// Parses the extrinsics corresponding to the parentchain. -pub type ParentchainExtrinsicParser = ExtrinsicParser; - -/// Partially interpreted extrinsic containing the `signature` and the `call_index` whereas -/// the `call_args` remain in encoded form. -/// -/// Intended for usage, where the actual `call_args` form is unknown. -pub struct SemiOpaqueExtrinsic<'a, SignedExtra> { - /// Signature of the Extrinsic. - pub signature: Signature, - /// Call index of the dispatchable. - pub call_index: CallIndex, - /// Encoded arguments of the dispatchable corresponding to the `call_index`. - pub call_args: &'a [u8], -} - -/// Trait to extract signature and call indexes of an encoded [UncheckedExtrinsicV4]. -pub trait ParseExtrinsic { - /// Signed extra of the extrinsic. - type SignedExtra; - - fn parse(encoded_call: &[u8]) -> Result, codec::Error>; -} - -impl ParseExtrinsic for ExtrinsicParser -where - SignedExtra: Decode + Encode, -{ - type SignedExtra = SignedExtra; - - /// Extract a call index of an encoded call. - fn parse(encoded_call: &[u8]) -> Result, codec::Error> { - let call_mut = &mut &encoded_call[..]; - - // `()` is a trick to stop decoding after the call index. So the remaining bytes - // of `call` after decoding only contain the parentchain's dispatchable's arguments. - let xt = UncheckedExtrinsicV4::< - Address, - (CallIndex, ()), - PairSignature, - Self::SignedExtra, - >::decode(call_mut)?; - - Ok(SemiOpaqueExtrinsic { - signature: xt.signature, - call_index: xt.function.0, - call_args: call_mut, - }) - } -} diff --git a/app-libs/parentchain-interface/src/target_b/mod.rs b/app-libs/parentchain-interface/src/target_b/mod.rs index 0fb12a2005..c21bbe6654 100644 --- a/app-libs/parentchain-interface/src/target_b/mod.rs +++ b/app-libs/parentchain-interface/src/target_b/mod.rs @@ -17,53 +17,77 @@ mod event_filter; mod event_handler; -mod extrinsic_parser; +use crate::{ + decode_and_log_error, + extrinsic_parser::{ExtrinsicParser, ParseExtrinsic}, + indirect_calls::timestamp_set::TimestampSetArgs, + TargetB, +}; use codec::{Decode, Encode}; -use core::marker::PhantomData; pub use event_filter::FilterableEvents; pub use event_handler::ParentchainEventHandler; -pub use extrinsic_parser::ParentchainExtrinsicParser; -use extrinsic_parser::ParseExtrinsic; use ita_stf::TrustedCallSigned; use itc_parentchain_indirect_calls_executor::{ error::{Error, Result}, filter_metadata::FilterIntoDataFrom, IndirectDispatch, }; -use itp_node_api::metadata::pallet_balances::BalancesCallIndexes; +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; + /// The default indirect call (extrinsic-triggered) of the Target-A-Parachain. #[derive(Debug, Clone, Encode, Decode, Eq, PartialEq)] -pub enum IndirectCall {} +pub enum IndirectCall { + TimestampSet(TimestampSetArgs), +} impl> IndirectDispatch for IndirectCall { - fn dispatch(&self, _executor: &Executor) -> Result<()> { - Err(Error::Other("no indirect calls defined for target_b".into())) + fn dispatch(&self, executor: &Executor) -> Result<()> { + trace!("dispatching indirect call {:?}", self); + match self { + IndirectCall::TimestampSet(timestamp_set_args) => timestamp_set_args.dispatch(executor), + } } } -pub struct TargetBExtrinsicFilter { - _phantom: PhantomData, -} +pub struct ExtrinsicFilter {} -impl FilterIntoDataFrom - for TargetBExtrinsicFilter -where - ExtrinsicParser: ParseExtrinsic, -{ +impl FilterIntoDataFrom for ExtrinsicFilter { type Output = IndirectCall; - type ParseParentchainMetadata = ExtrinsicParser; + type ParseParentchainMetadata = ParentchainExtrinsicParser; fn filter_into_from_metadata( - _encoded_data: &[u8], - _metadata: &NodeMetadata, + encoded_data: &[u8], + metadata: &NodeMetadata, ) -> Option { - warn!("no indirect calls filter has been implemented for target_b"); - None + let call_mut = &mut &encoded_data[..]; + + // Todo: the filter should not need to parse, only filter. This should directly be configured + // in the indirect executor. + let xt = match Self::ParseParentchainMetadata::parse(call_mut) { + Ok(xt) => xt, + Err(e) => { + error!("ExtrinsicFilter: Could not parse parentchain extrinsic: {:?}", e); + return None + }, + }; + let index = xt.call_index; + let call_args = &mut &xt.call_args[..]; + trace!("ExtrinsicFilter: attempting to execute indirect call with index {:?}", index); + if index == metadata.timestamp_set_call_indexes().ok()? { + debug!("ExtrinsicFilter: found timestamp set extrinsic"); + let args = decode_and_log_error::>(call_args)?; + Some(IndirectCall::TimestampSet(args)) + } else { + None + } } } diff --git a/app-libs/sgx-runtime/Cargo.toml b/app-libs/sgx-runtime/Cargo.toml index b4de122d5b..91f6550a2d 100644 --- a/app-libs/sgx-runtime/Cargo.toml +++ b/app-libs/sgx-runtime/Cargo.toml @@ -42,7 +42,7 @@ sp-version = { default-features = false, git = "https://github.com/paritytech/su # Integritee dependencies pallet-evm = { default-features = false, optional = true, git = "https://github.com/integritee-network/frontier.git", branch = "bar/polkadot-v0.9.42" } -pallet-parentchain = { default-features = false, git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.10-polkadot-v0.9.42" } +pallet-parentchain = { default-features = false, git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.11-polkadot-v0.9.42" } [features] default = ["std"] diff --git a/app-libs/sgx-runtime/src/lib.rs b/app-libs/sgx-runtime/src/lib.rs index bbc51347e0..93b1026d1a 100644 --- a/app-libs/sgx-runtime/src/lib.rs +++ b/app-libs/sgx-runtime/src/lib.rs @@ -70,6 +70,7 @@ pub use frame_support::{ }, StorageValue, }; +use itp_sgx_runtime_primitives::types::Moment; pub use pallet_balances::Call as BalancesCall; pub use pallet_parentchain::Call as ParentchainPalletCall; pub use pallet_timestamp::Call as TimestampCall; @@ -211,7 +212,7 @@ parameter_types! { impl pallet_timestamp::Config for Runtime { /// A timestamp: milliseconds since the unix epoch. - type Moment = u64; + type Moment = Moment; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; type WeightInfo = (); @@ -263,18 +264,21 @@ pub type ParentchainInstanceIntegritee = pallet_parentchain::Instance1; impl pallet_parentchain::Config for Runtime { type WeightInfo = (); type RuntimeEvent = RuntimeEvent; + type Moment = Moment; } pub type ParentchainInstanceTargetA = pallet_parentchain::Instance2; impl pallet_parentchain::Config for Runtime { type WeightInfo = (); type RuntimeEvent = RuntimeEvent; + type Moment = Moment; } pub type ParentchainInstanceTargetB = pallet_parentchain::Instance3; impl pallet_parentchain::Config for Runtime { type WeightInfo = (); type RuntimeEvent = RuntimeEvent; + type Moment = Moment; } // The plain sgx-runtime without the `evm-pallet` diff --git a/app-libs/stf/Cargo.toml b/app-libs/stf/Cargo.toml index 1d0c8cd2a8..d07fc5a156 100644 --- a/app-libs/stf/Cargo.toml +++ b/app-libs/stf/Cargo.toml @@ -20,6 +20,7 @@ itp-hashing = { default-features = false, path = "../../core-primitives/hashing" itp-node-api = { default-features = false, path = "../../core-primitives/node-api" } itp-node-api-metadata = { default-features = false, path = "../../core-primitives/node-api/metadata" } itp-sgx-externalities = { default-features = false, path = "../../core-primitives/substrate-sgx/externalities" } +itp-sgx-runtime-primitives = { default-features = false, path = "../../core-primitives/sgx-runtime-primitives" } itp-stf-interface = { default-features = false, path = "../../core-primitives/stf-interface" } itp-stf-primitives = { default-features = false, path = "../../core-primitives/stf-primitives" } itp-storage = { default-features = false, path = "../../core-primitives/storage" } @@ -31,7 +32,7 @@ sp-io = { default-features = false, features = ["disable_oom", "disable_panic_ha frame-support = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } frame-system = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } pallet-balances = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -pallet-parentchain = { default-features = false, git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.10-polkadot-v0.9.42" } +pallet-parentchain = { default-features = false, git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.11-polkadot-v0.9.42" } pallet-sudo = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } sp-core = { default-features = false, features = ["full_crypto"], git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } diff --git a/app-libs/stf/src/helpers.rs b/app-libs/stf/src/helpers.rs index 001c19a30a..af3f97f992 100644 --- a/app-libs/stf/src/helpers.rs +++ b/app-libs/stf/src/helpers.rs @@ -17,6 +17,7 @@ use crate::ENCLAVE_ACCOUNT_KEY; use codec::{Decode, Encode}; use ita_sgx_runtime::{ParentchainIntegritee, ParentchainTargetA, ParentchainTargetB}; +use itp_stf_interface::{BlockMetadata, ShardCreationInfo}; use itp_stf_primitives::{ error::{StfError, StfResult}, types::AccountId, @@ -126,3 +127,36 @@ pub fn get_shard_vaults() -> Vec<(AccountId, ParentchainId)> { .filter_map(|vp| vp.0.map(|v| (v, vp.1))) .collect() } + +pub fn shard_creation_info() -> ShardCreationInfo { + let maybe_integritee_info: Option = + ParentchainIntegritee::creation_block_number().and_then(|number| { + ParentchainIntegritee::creation_block_hash().map(|hash| BlockMetadata { + number, + hash, + timestamp: ParentchainIntegritee::creation_timestamp(), + }) + }); + let maybe_target_a_info: Option = ParentchainTargetA::creation_block_number() + .and_then(|number| { + ParentchainTargetA::creation_block_hash().map(|hash| BlockMetadata { + number, + hash, + timestamp: ParentchainTargetA::creation_timestamp(), + }) + }); + let maybe_target_b_info: Option = ParentchainTargetB::creation_block_number() + .and_then(|number| { + ParentchainTargetB::creation_block_hash().map(|hash| BlockMetadata { + number, + hash, + timestamp: ParentchainTargetB::creation_timestamp(), + }) + }); + + ShardCreationInfo { + integritee: maybe_integritee_info, + target_a: maybe_target_a_info, + target_b: maybe_target_b_info, + } +} diff --git a/app-libs/stf/src/stf_sgx.rs b/app-libs/stf/src/stf_sgx.rs index b07b05e0ae..e09e70a3ab 100644 --- a/app-libs/stf/src/stf_sgx.rs +++ b/app-libs/stf/src/stf_sgx.rs @@ -18,7 +18,7 @@ #[cfg(feature = "test")] use crate::test_genesis::test_genesis_setup; use crate::{ - helpers::{enclave_signer_account, get_shard_vaults, shard_vault}, + helpers::{enclave_signer_account, get_shard_vaults, shard_creation_info, shard_vault}, Stf, ENCLAVE_ACCOUNT_KEY, }; use codec::{Decode, Encode}; @@ -32,8 +32,8 @@ use itp_stf_interface::{ parentchain_pallet::ParentchainPalletInstancesInterface, sudo_pallet::SudoPalletInterface, system_pallet::{SystemPalletAccountInterface, SystemPalletEventInterface}, - ExecuteCall, ExecuteGetter, InitState, ShardVaultQuery, StateCallInterface, - StateGetterInterface, UpdateState, + ExecuteCall, ExecuteGetter, InitState, ShardCreationInfo, ShardCreationQuery, ShardVaultQuery, + StateCallInterface, StateGetterInterface, UpdateState, }; use itp_stf_primitives::{error::StfError, traits::TrustedCallVerification}; use itp_storage::storage_value_key; @@ -176,6 +176,15 @@ where } } +impl ShardCreationQuery for Stf +where + State: SgxExternalitiesTrait + Debug, +{ + fn get_shard_creation_info(state: &mut State) -> ShardCreationInfo { + state.execute_with(shard_creation_info) + } +} + impl SudoPalletInterface for Stf where State: SgxExternalitiesTrait, @@ -257,6 +266,7 @@ where + pallet_parentchain::Config + pallet_parentchain::Config, <::Lookup as StaticLookup>::Source: From, + ParentchainHeader: Debug, { type Error = StfError; @@ -264,6 +274,7 @@ where state: &mut State, header: ParentchainHeader, ) -> Result<(), Self::Error> { + trace!("updating integritee parentchain block : {:?}", header); state.execute_with(|| { pallet_parentchain::Call::::set_block { header } .dispatch_bypass_filter(Runtime::RuntimeOrigin::root()) @@ -281,6 +292,7 @@ where state: &mut State, header: ParentchainHeader, ) -> Result<(), Self::Error> { + trace!("updating target_a parentchain block: {:?}", header); state.execute_with(|| { pallet_parentchain::Call::::set_block { header } .dispatch_bypass_filter(Runtime::RuntimeOrigin::root()) @@ -298,6 +310,7 @@ where state: &mut State, header: ParentchainHeader, ) -> Result<(), Self::Error> { + trace!("updating target_b parentchain block: {:?}", header); state.execute_with(|| { pallet_parentchain::Call::::set_block { header } .dispatch_bypass_filter(Runtime::RuntimeOrigin::root()) @@ -359,6 +372,46 @@ where Ok(()) } + fn set_creation_block( + state: &mut State, + header: ParentchainHeader, + parentchain_id: ParentchainId, + ) -> Result<(), Self::Error> { + state.execute_with(|| match parentchain_id { + ParentchainId::Integritee => pallet_parentchain::Call::< + Runtime, + ParentchainInstanceIntegritee, + >::set_creation_block { + header, + } + .dispatch_bypass_filter(Runtime::RuntimeOrigin::root()) + .map_err(|e| { + Self::Error::Dispatch(format!("Init shard vault account error: {:?}", e.error)) + }), + ParentchainId::TargetA => pallet_parentchain::Call::< + Runtime, + ParentchainInstanceTargetA, + >::set_creation_block { + header, + } + .dispatch_bypass_filter(Runtime::RuntimeOrigin::root()) + .map_err(|e| { + Self::Error::Dispatch(format!("Init shard vault account error: {:?}", e.error)) + }), + ParentchainId::TargetB => pallet_parentchain::Call::< + Runtime, + ParentchainInstanceTargetB, + >::set_creation_block { + header, + } + .dispatch_bypass_filter(Runtime::RuntimeOrigin::root()) + .map_err(|e| { + Self::Error::Dispatch(format!("Init shard vault account error: {:?}", e.error)) + }), + })?; + Ok(()) + } + fn get_shard_vault_ensure_single_parentchain( state: &mut State, ) -> Result, Self::Error> { diff --git a/app-libs/stf/src/trusted_call.rs b/app-libs/stf/src/trusted_call.rs index abe5d5c6ba..201a098110 100644 --- a/app-libs/stf/src/trusted_call.rs +++ b/app-libs/stf/src/trusted_call.rs @@ -32,7 +32,10 @@ use frame_support::{ensure, traits::UnfilteredDispatchable}; #[cfg(feature = "evm")] use ita_sgx_runtime::{AddressMapping, HashedAddressMapping}; pub use ita_sgx_runtime::{Balance, Index}; -use ita_sgx_runtime::{Runtime, System}; +use ita_sgx_runtime::{ + ParentchainInstanceIntegritee, ParentchainInstanceTargetA, ParentchainInstanceTargetB, + ParentchainIntegritee, Runtime, System, +}; use itp_node_api::metadata::{provider::AccessNodeMetadata, NodeMetadataTrait}; use itp_node_api_metadata::{ pallet_balances::BalancesCallIndexes, pallet_enclave_bridge::EnclaveBridgeCallIndexes, @@ -46,7 +49,7 @@ use itp_stf_primitives::{ }; use itp_types::{ parentchain::{ParentchainCall, ParentchainId, ProxyType}, - Address, OpaqueCall, + Address, Moment, OpaqueCall, }; use itp_utils::stringify::account_id_to_string; use log::*; @@ -66,6 +69,7 @@ pub enum TrustedCall { balance_transfer(AccountId, AccountId, Balance), balance_unshield(AccountId, AccountId, Balance, ShardIdentifier), // (AccountIncognito, BeneficiaryPublicAccount, Amount, Shard) balance_shield(AccountId, AccountId, Balance, ParentchainId), // (Root, AccountIncognito, Amount, origin parentchain) + timestamp_set(AccountId, Moment, ParentchainId), // (Root, now) #[cfg(feature = "evm")] evm_withdraw(AccountId, H160, Balance), // (Origin, Address EVM Account, Value) // (Origin, Source, Target, Input, Value, Gas limit, Max fee per gas, Max priority fee per gas, Nonce, Access list) @@ -119,6 +123,7 @@ impl TrustedCall { Self::balance_transfer(sender_account, ..) => sender_account, Self::balance_unshield(sender_account, ..) => sender_account, Self::balance_shield(sender_account, ..) => sender_account, + Self::timestamp_set(sender_account, ..) => sender_account, #[cfg(feature = "evm")] Self::evm_withdraw(sender_account, ..) => sender_account, #[cfg(feature = "evm")] @@ -381,6 +386,62 @@ where )))); Ok(()) }, + TrustedCall::timestamp_set(enclave_account, now, parentchain_id) => { + ensure_enclave_signer_account(&enclave_account)?; + debug!("timestamp_set({}, {:?})", now, parentchain_id); + match parentchain_id { + ParentchainId::Integritee => { + if ParentchainIntegritee::creation_timestamp().is_none() { + debug!( + "initializing creation timestamp({}, {:?})", + now, parentchain_id + ); + ita_sgx_runtime::ParentchainPalletCall::< + Runtime, + ParentchainInstanceIntegritee, + >::set_creation_timestamp { + creation: now, + } + .dispatch_bypass_filter(ita_sgx_runtime::RuntimeOrigin::root()) + .map_err(|e| { + Self::Error::Dispatch(format!("Timestamp Set error: {:?}", e.error)) + })?; + }; + ita_sgx_runtime::ParentchainPalletCall::< + Runtime, + ParentchainInstanceIntegritee, + >::set_now { + now, + } + .dispatch_bypass_filter(ita_sgx_runtime::RuntimeOrigin::root()) + .map_err(|e| { + Self::Error::Dispatch(format!("Timestamp Set error: {:?}", e.error)) + })? + }, + ParentchainId::TargetA => ita_sgx_runtime::ParentchainPalletCall::< + Runtime, + ParentchainInstanceTargetA, + >::set_now { + now, + } + .dispatch_bypass_filter(ita_sgx_runtime::RuntimeOrigin::root()) + .map_err(|e| { + Self::Error::Dispatch(format!("Timestamp Set error: {:?}", e.error)) + })?, + ParentchainId::TargetB => ita_sgx_runtime::ParentchainPalletCall::< + Runtime, + ParentchainInstanceTargetB, + >::set_now { + now, + } + .dispatch_bypass_filter(ita_sgx_runtime::RuntimeOrigin::root()) + .map_err(|e| { + Self::Error::Dispatch(format!("Timestamp Set error: {:?}", e.error)) + })?, + }; + Ok(()) + }, + #[cfg(feature = "evm")] TrustedCall::evm_withdraw(from, address, value) => { debug!("evm_withdraw({}, {}, {})", account_id_to_string(&from), address, value); @@ -510,6 +571,7 @@ where TrustedCall::balance_transfer(..) => debug!("No storage updates needed..."), TrustedCall::balance_unshield(..) => debug!("No storage updates needed..."), TrustedCall::balance_shield(..) => debug!("No storage updates needed..."), + TrustedCall::timestamp_set(..) => debug!("No storage updates needed..."), #[cfg(feature = "evm")] _ => debug!("No storage updates needed..."), }; diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 1dfbdc24e9..761296035b 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "integritee-cli" -version = "0.12.10" +version = "0.12.11" authors = ["Integritee AG "] edition = "2021" @@ -25,14 +25,14 @@ thiserror = "1.0" urlencoding = "2.1.3" # scs / integritee -enclave-bridge-primitives = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.10-polkadot-v0.9.42" } +enclave-bridge-primitives = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.11-polkadot-v0.9.42" } ita-parentchain-interface = { path = "../app-libs/parentchain-interface" } -pallet-enclave-bridge = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.10-polkadot-v0.9.42" } +pallet-enclave-bridge = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.11-polkadot-v0.9.42" } pallet-evm = { optional = true, git = "https://github.com/integritee-network/frontier.git", branch = "bar/polkadot-v0.9.42" } -pallet-sidechain = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.10-polkadot-v0.9.42" } -pallet-teeracle = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.10-polkadot-v0.9.42" } -pallet-teerex = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.10-polkadot-v0.9.42" } -teeracle-primitives = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.10-polkadot-v0.9.42" } +pallet-sidechain = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.11-polkadot-v0.9.42" } +pallet-teeracle = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.11-polkadot-v0.9.42" } +pallet-teerex = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.11-polkadot-v0.9.42" } +teeracle-primitives = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.11-polkadot-v0.9.42" } # `default-features = false` to remove the jsonrpsee dependency. # disable unsupported jsonrpcsee diff --git a/core-primitives/enclave-api/Cargo.toml b/core-primitives/enclave-api/Cargo.toml index f2a8e63577..f639f9d7e8 100644 --- a/core-primitives/enclave-api/Cargo.toml +++ b/core-primitives/enclave-api/Cargo.toml @@ -19,11 +19,12 @@ frame-support = { git = "https://github.com/paritytech/substrate.git", branch = sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -teerex-primitives = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.10-polkadot-v0.9.42" } +teerex-primitives = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.11-polkadot-v0.9.42" } itc-parentchain = { path = "../../core/parentchain/parentchain-crate" } itp-enclave-api-ffi = { path = "ffi" } itp-settings = { path = "../settings" } +itp-stf-interface = { path = "../stf-interface" } itp-storage = { path = "../storage" } itp-types = { path = "../types" } diff --git a/core-primitives/enclave-api/ffi/src/lib.rs b/core-primitives/enclave-api/ffi/src/lib.rs index 6398aed8c2..b222573c94 100644 --- a/core-primitives/enclave-api/ffi/src/lib.rs +++ b/core-primitives/enclave-api/ffi/src/lib.rs @@ -80,7 +80,7 @@ extern "C" { header_size: u32, ) -> sgx_status_t; - pub fn get_shard_creation_header( + pub fn get_shard_creation_info( eid: sgx_enclave_id_t, retval: *mut sgx_status_t, shard: *const u8, diff --git a/core-primitives/enclave-api/src/enclave_base.rs b/core-primitives/enclave-api/src/enclave_base.rs index 23b3556f7e..22f17d7f6b 100644 --- a/core-primitives/enclave-api/src/enclave_base.rs +++ b/core-primitives/enclave-api/src/enclave_base.rs @@ -20,6 +20,7 @@ use crate::EnclaveResult; use codec::Decode; use core::fmt::Debug; use itc_parentchain::primitives::{ParentchainId, ParentchainInitParams}; +use itp_stf_interface::ShardCreationInfo; use itp_types::{parentchain::Header, Balance, ShardIdentifier}; use sgx_crypto_helper::rsa3072::Rsa3072PubKey; use sp_core::ed25519; @@ -66,10 +67,7 @@ pub trait EnclaveBase: Send + Sync + 'static { header: &Header, ) -> EnclaveResult<()>; - fn get_shard_creation_header( - &self, - shard: &ShardIdentifier, - ) -> EnclaveResult<(ParentchainId, Header)>; + fn get_shard_creation_info(&self, shard: &ShardIdentifier) -> EnclaveResult; fn set_nonce(&self, nonce: u32, parentchain_id: ParentchainId) -> EnclaveResult<()>; @@ -102,6 +100,7 @@ mod impl_ffi { use itp_settings::worker::{ HEADER_MAX_SIZE, MR_ENCLAVE_SIZE, SHIELDING_KEY_SIZE, SIGNING_KEY_SIZE, }; + use itp_stf_interface::ShardCreationInfo; use itp_types::{ parentchain::{Balance, Header}, ShardIdentifier, @@ -258,30 +257,28 @@ mod impl_ffi { Ok(()) } - fn get_shard_creation_header( + fn get_shard_creation_info( &self, shard: &ShardIdentifier, - ) -> EnclaveResult<(ParentchainId, Header)> { + ) -> EnclaveResult { let mut retval = sgx_status_t::SGX_SUCCESS; - let mut creation = [0u8; HEADER_MAX_SIZE + std::mem::size_of::()]; + let mut creation_info = [0u8; std::mem::size_of::()]; let shard_bytes = shard.encode(); let result = unsafe { - ffi::get_shard_creation_header( + ffi::get_shard_creation_info( self.eid, &mut retval, shard_bytes.as_ptr(), shard_bytes.len() as u32, - creation.as_mut_ptr(), - creation.len() as u32, + creation_info.as_mut_ptr(), + creation_info.len() as u32, ) }; ensure!(result == sgx_status_t::SGX_SUCCESS, Error::Sgx(result)); ensure!(retval == sgx_status_t::SGX_SUCCESS, Error::Sgx(retval)); - let (creation_parentchain_id, creation_header): (ParentchainId, Header) = - Decode::decode(&mut creation.as_slice())?; - Ok((creation_parentchain_id, creation_header)) + Decode::decode(&mut creation_info.as_slice()).map_err(|e| Error::Codec(e.into())) } fn set_nonce(&self, nonce: u32, parentchain_id: ParentchainId) -> EnclaveResult<()> { diff --git a/core-primitives/node-api/metadata/src/lib.rs b/core-primitives/node-api/metadata/src/lib.rs index 648876eb40..6a8662e5d0 100644 --- a/core-primitives/node-api/metadata/src/lib.rs +++ b/core-primitives/node-api/metadata/src/lib.rs @@ -23,6 +23,7 @@ use crate::{ error::Result, pallet_balances::BalancesCallIndexes, pallet_enclave_bridge::EnclaveBridgeCallIndexes, pallet_proxy::ProxyCallIndexes, pallet_sidechain::SidechainCallIndexes, pallet_teerex::TeerexCallIndexes, + pallet_timestamp::TimestampCallIndexes, }; use codec::{Decode, Encode}; use sp_core::storage::StorageKey; @@ -38,6 +39,8 @@ pub mod pallet_sidechain; pub mod pallet_teeracle; pub mod pallet_teerex; +pub mod pallet_timestamp; + #[cfg(feature = "mocks")] pub mod metadata_mocks; @@ -47,6 +50,7 @@ pub trait NodeMetadataTrait: + SidechainCallIndexes + ProxyCallIndexes + BalancesCallIndexes + + TimestampCallIndexes { } impl< @@ -54,7 +58,8 @@ impl< + EnclaveBridgeCallIndexes + SidechainCallIndexes + ProxyCallIndexes - + BalancesCallIndexes, + + BalancesCallIndexes + + TimestampCallIndexes, > NodeMetadataTrait for T { } diff --git a/core-primitives/node-api/metadata/src/metadata_mocks.rs b/core-primitives/node-api/metadata/src/metadata_mocks.rs index 8bf47298ec..40711e24c7 100644 --- a/core-primitives/node-api/metadata/src/metadata_mocks.rs +++ b/core-primitives/node-api/metadata/src/metadata_mocks.rs @@ -19,6 +19,7 @@ use crate::{ error::Result, pallet_balances::BalancesCallIndexes, pallet_enclave_bridge::EnclaveBridgeCallIndexes, pallet_proxy::ProxyCallIndexes, pallet_sidechain::SidechainCallIndexes, pallet_teerex::TeerexCallIndexes, + pallet_timestamp::TimestampCallIndexes, }; use codec::{Decode, Encode}; @@ -56,6 +57,8 @@ pub struct NodeMetadataMock { transfer: u8, transfer_keep_alive: u8, transfer_allow_death: u8, + timestamp_module: u8, + timestamp_set: u8, runtime_spec_version: u32, runtime_transaction_version: u32, } @@ -85,6 +88,8 @@ impl NodeMetadataMock { transfer: 7u8, transfer_keep_alive: 3u8, transfer_allow_death: 0u8, + timestamp_module: 3, + timestamp_set: 0, runtime_spec_version: 25, runtime_transaction_version: 4, } @@ -168,3 +173,9 @@ impl BalancesCallIndexes for NodeMetadataMock { Ok([self.balances_module, self.transfer_allow_death]) } } + +impl TimestampCallIndexes for NodeMetadataMock { + fn timestamp_set_call_indexes(&self) -> Result<[u8; 2]> { + Ok([self.timestamp_module, self.timestamp_set]) + } +} diff --git a/core-primitives/node-api/metadata/src/pallet_system.rs b/core-primitives/node-api/metadata/src/pallet_system.rs index 1a9b4c7958..c79d6f971b 100644 --- a/core-primitives/node-api/metadata/src/pallet_system.rs +++ b/core-primitives/node-api/metadata/src/pallet_system.rs @@ -3,7 +3,7 @@ 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 + 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. @@ -17,17 +17,17 @@ use sp_core::storage::StorageKey; const SYSTEM: &str = "System"; pub trait SystemStorageIndexes { - fn system_account_storage_key(&self) -> Result; + fn system_account_storage_key(&self) -> Result; - fn system_account_storage_map_key(&self, index: u64) -> Result; + fn system_account_storage_map_key(&self, index: u64) -> Result; } impl SystemStorageIndexes for NodeMetadata { - fn system_account_storage_key(&self) -> Result { - self.storage_value_key(SYSTEM, "Account") - } + fn system_account_storage_key(&self) -> Result { + self.storage_value_key(SYSTEM, "Account") + } - fn system_account_storage_map_key(&self, index: u64) -> Result { - self.storage_map_key(SYSTEM, "Account", index) - } -} \ No newline at end of file + fn system_account_storage_map_key(&self, index: u64) -> Result { + self.storage_map_key(SYSTEM, "Account", index) + } +} diff --git a/core-primitives/node-api/metadata/src/pallet_timestamp.rs b/core-primitives/node-api/metadata/src/pallet_timestamp.rs new file mode 100644 index 0000000000..75e695579b --- /dev/null +++ b/core-primitives/node-api/metadata/src/pallet_timestamp.rs @@ -0,0 +1,30 @@ +/* + 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. + +*/ +use crate::{error::Result, NodeMetadata}; + +/// Pallet' name: +const TIMESTAMP: &str = "Timestamp"; + +pub trait TimestampCallIndexes { + fn timestamp_set_call_indexes(&self) -> Result<[u8; 2]>; +} + +impl TimestampCallIndexes for NodeMetadata { + fn timestamp_set_call_indexes(&self) -> Result<[u8; 2]> { + self.call_indexes(TIMESTAMP, "set") + } +} diff --git a/core-primitives/stf-executor/src/executor.rs b/core-primitives/stf-executor/src/executor.rs index 5549828b9f..d99351a9ff 100644 --- a/core-primitives/stf-executor/src/executor.rs +++ b/core-primitives/stf-executor/src/executor.rs @@ -185,10 +185,6 @@ where debug!("Update STF storage upon block import!"); let storage_hashes = Stf::storage_hashes_to_update_on_block(parentchain_id); - if storage_hashes.is_empty() { - return Ok(()) - } - // global requests they are the same for every shard let state_diff_update = self .ocall_api diff --git a/core-primitives/stf-interface/src/lib.rs b/core-primitives/stf-interface/src/lib.rs index 436172ad4a..7dba9697dd 100644 --- a/core-primitives/stf-interface/src/lib.rs +++ b/core-primitives/stf-interface/src/lib.rs @@ -28,7 +28,10 @@ use core::fmt::Debug; use itp_node_api_metadata::NodeMetadataTrait; use itp_node_api_metadata_provider::AccessNodeMetadata; use itp_stf_primitives::traits::TrustedCallVerification; -use itp_types::parentchain::{AccountId, ParentchainCall, ParentchainId}; +use itp_types::{ + parentchain::{AccountId, BlockHash, BlockNumber, ParentchainCall, ParentchainId}, + Moment, +}; #[cfg(feature = "mocks")] pub mod mocks; @@ -49,6 +52,11 @@ pub trait ShardVaultQuery { fn get_vault(state: &mut S) -> Option<(AccountId, ParentchainId)>; } +/// Interface to query shard creation block information for shard on a specified parentchain +pub trait ShardCreationQuery { + fn get_shard_creation_info(state: &mut S) -> ShardCreationInfo; +} + /// Interface for all functions calls necessary to update an already /// initialized state. pub trait UpdateState { @@ -107,3 +115,27 @@ pub trait ExecuteGetter { /// Get storages hashes that should be updated for a specific getter. fn get_storage_hashes_to_update(self) -> Vec>; } + +#[derive(Debug, Clone, Copy, Encode, Decode)] +pub struct BlockMetadata { + pub number: BlockNumber, + pub hash: BlockHash, + pub timestamp: Option, +} + +#[derive(Debug, Clone, Copy, Encode, Decode)] +pub struct ShardCreationInfo { + pub integritee: Option, + pub target_a: Option, + pub target_b: Option, +} + +impl ShardCreationInfo { + pub fn for_parentchain(&self, id: ParentchainId) -> Option { + match id { + ParentchainId::Integritee => self.integritee, + ParentchainId::TargetA => self.target_a, + ParentchainId::TargetB => self.target_b, + } + } +} diff --git a/core-primitives/stf-interface/src/parentchain_pallet.rs b/core-primitives/stf-interface/src/parentchain_pallet.rs index 8f0ae2ecd0..b73898f104 100644 --- a/core-primitives/stf-interface/src/parentchain_pallet.rs +++ b/core-primitives/stf-interface/src/parentchain_pallet.rs @@ -45,6 +45,12 @@ pub trait ParentchainPalletInstancesInterface { parentchain_id: ParentchainId, ) -> Result<(), Self::Error>; + fn set_creation_block( + state: &mut State, + header: ParentchainHeader, + parentchain_id: ParentchainId, + ) -> Result<(), Self::Error>; + fn get_shard_vault_ensure_single_parentchain( state: &mut State, ) -> Result, Self::Error>; diff --git a/core-primitives/types/Cargo.toml b/core-primitives/types/Cargo.toml index abc9efb883..a6d2f2d7a9 100644 --- a/core-primitives/types/Cargo.toml +++ b/core-primitives/types/Cargo.toml @@ -27,9 +27,9 @@ sp-runtime = { default-features = false, git = "https://github.com/paritytech/su sp-std = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } # integritee-node -enclave-bridge-primitives = { default-features = false, git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.10-polkadot-v0.9.42" } -teeracle-primitives = { default-features = false, git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.10-polkadot-v0.9.42" } -teerex-primitives = { default-features = false, git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.10-polkadot-v0.9.42" } +enclave-bridge-primitives = { default-features = false, git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.11-polkadot-v0.9.42" } +teeracle-primitives = { default-features = false, git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.11-polkadot-v0.9.42" } +teerex-primitives = { default-features = false, git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.11-polkadot-v0.9.42" } [features] default = ["std"] diff --git a/core/parentchain/block-importer/Cargo.toml b/core/parentchain/block-importer/Cargo.toml index 632d98ffbe..be6b1c93c4 100644 --- a/core/parentchain/block-importer/Cargo.toml +++ b/core/parentchain/block-importer/Cargo.toml @@ -15,6 +15,7 @@ itc-parentchain-indirect-calls-executor = { path = "../indirect-calls-executor", itc-parentchain-light-client = { path = "../light-client", default-features = false } itp-extrinsics-factory = { path = "../../../core-primitives/extrinsics-factory", default-features = false } itp-stf-executor = { path = "../../../core-primitives/stf-executor", default-features = false } +itp-stf-interface = { path = "../../../core-primitives/stf-interface", default-features = false } itp-types = { path = "../../../core-primitives/types", default-features = false } # sgx enabled external libraries @@ -37,6 +38,7 @@ std = [ "itc-parentchain-light-client/std", "itp-extrinsics-factory/std", "itp-stf-executor/std", + "itp-stf-interface/std", "itp-types/std", # no-std compatible libraries "codec/std", diff --git a/core/parentchain/block-importer/src/block_importer.rs b/core/parentchain/block-importer/src/block_importer.rs index 612709b4d5..becb9e9a6b 100644 --- a/core/parentchain/block-importer/src/block_importer.rs +++ b/core/parentchain/block-importer/src/block_importer.rs @@ -26,8 +26,9 @@ use itc_parentchain_light_client::{ }; use itp_extrinsics_factory::CreateExtrinsics; use itp_stf_executor::traits::StfUpdateState; +use itp_stf_interface::ShardCreationInfo; use itp_types::{ - parentchain::{Header, IdentifyParentchain, ParentchainId}, + parentchain::{IdentifyParentchain, ParentchainId}, OpaqueCall, H256, }; use log::*; @@ -49,7 +50,7 @@ pub struct ParentchainBlockImporter< stf_executor: Arc, extrinsics_factory: Arc, pub indirect_calls_executor: Arc, - maybe_creation_header: Option
, + shard_creation_info: ShardCreationInfo, pub parentchain_id: ParentchainId, _phantom: PhantomData, } @@ -74,7 +75,7 @@ impl< stf_executor: Arc, extrinsics_factory: Arc, indirect_calls_executor: Arc, - maybe_creation_header: Option
, + shard_creation_info: ShardCreationInfo, parentchain_id: ParentchainId, ) -> Self { ParentchainBlockImporter { @@ -82,7 +83,7 @@ impl< stf_executor, extrinsics_factory, indirect_calls_executor, - maybe_creation_header, + shard_creation_info, parentchain_id, _phantom: Default::default(), } @@ -144,15 +145,13 @@ impl< } // check if we can fast-sync - if id == ParentchainId::Integritee { - if let Some(ref creation_header) = self.maybe_creation_header { - if signed_block.block.header().number < creation_header.number { - trace!( - "fast-syncing block import, ignoring any invocations before block {:}", - creation_header.number - ); - continue - } + if let Some(creation_block) = self.shard_creation_info.for_parentchain(id) { + if signed_block.block.header().number < creation_block.number { + trace!( + "fast-syncing block import, ignoring any invocations before block {:}", + creation_block.number + ); + continue } } diff --git a/enclave-runtime/Cargo.lock b/enclave-runtime/Cargo.lock index feaab78ef1..4ceb34379b 100644 --- a/enclave-runtime/Cargo.lock +++ b/enclave-runtime/Cargo.lock @@ -500,7 +500,7 @@ dependencies = [ [[package]] name = "common-primitives" version = "0.1.0" -source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.10-polkadot-v0.9.42#91321c805edc1e94d9ba04a5a6d74d63cf6c59e6" +source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.11-polkadot-v0.9.42#094b1e982b4637ebfbf5afb985100417215d49a0" dependencies = [ "derive_more", "parity-scale-codec", @@ -756,7 +756,7 @@ dependencies = [ [[package]] name = "enclave-bridge-primitives" version = "0.1.0" -source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.10-polkadot-v0.9.42#91321c805edc1e94d9ba04a5a6d74d63cf6c59e6" +source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.11-polkadot-v0.9.42#094b1e982b4637ebfbf5afb985100417215d49a0" dependencies = [ "common-primitives", "log", @@ -771,7 +771,7 @@ dependencies = [ [[package]] name = "enclave-runtime" -version = "0.12.10" +version = "0.12.11" dependencies = [ "array-bytes 6.2.2", "cid", @@ -1733,6 +1733,7 @@ dependencies = [ "itp-node-api", "itp-node-api-metadata", "itp-sgx-externalities", + "itp-sgx-runtime-primitives", "itp-stf-interface", "itp-stf-primitives", "itp-storage", @@ -1822,6 +1823,7 @@ dependencies = [ "itc-parentchain-light-client", "itp-extrinsics-factory", "itp-stf-executor", + "itp-stf-interface", "itp-types", "log", "parity-scale-codec", @@ -3003,8 +3005,8 @@ dependencies = [ [[package]] name = "pallet-parentchain" -version = "0.10.0" -source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.10-polkadot-v0.9.42#91321c805edc1e94d9ba04a5a6d74d63cf6c59e6" +version = "0.11.0" +source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.11-polkadot-v0.9.42#094b1e982b4637ebfbf5afb985100417215d49a0" dependencies = [ "frame-support", "frame-system", @@ -4625,7 +4627,7 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "teeracle-primitives" version = "0.1.0" -source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.10-polkadot-v0.9.42#91321c805edc1e94d9ba04a5a6d74d63cf6c59e6" +source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.11-polkadot-v0.9.42#094b1e982b4637ebfbf5afb985100417215d49a0" dependencies = [ "common-primitives", "sp-std", @@ -4635,7 +4637,7 @@ dependencies = [ [[package]] name = "teerex-primitives" version = "0.1.0" -source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.10-polkadot-v0.9.42#91321c805edc1e94d9ba04a5a6d74d63cf6c59e6" +source = "git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.11-polkadot-v0.9.42#094b1e982b4637ebfbf5afb985100417215d49a0" dependencies = [ "common-primitives", "derive_more", diff --git a/enclave-runtime/Cargo.toml b/enclave-runtime/Cargo.toml index 39a6c9e4a2..84e0d5be00 100644 --- a/enclave-runtime/Cargo.toml +++ b/enclave-runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "enclave-runtime" -version = "0.12.10" +version = "0.12.11" authors = ["Integritee AG "] edition = "2021" @@ -87,9 +87,9 @@ webpki = { git = "https://github.com/mesalock-linux/webpki", branch = "mesalock_ base58 = { rev = "sgx_1.1.3", package = "rust-base58", default-features = false, features = ["mesalock_sgx"], git = "https://github.com/mesalock-linux/rust-base58-sgx" } cid = { default-features = false, git = "https://github.com/whalelephant/rust-cid", branch = "nstd" } -enclave-bridge-primitives = { default-features = false, git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.10-polkadot-v0.9.42" } +enclave-bridge-primitives = { default-features = false, git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.11-polkadot-v0.9.42" } multibase = { default-features = false, git = "https://github.com/whalelephant/rust-multibase", branch = "nstd" } -teerex-primitives = { default-features = false, git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.10-polkadot-v0.9.42" } +teerex-primitives = { default-features = false, git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.11-polkadot-v0.9.42" } # local deps ita-oracle = { path = "../app-libs/oracle", default-features = false, optional = true, features = ["sgx"] } @@ -175,16 +175,16 @@ sgx_types = { version = "1.1.6", git = "https://github.com/apache/incubator-teac #parachains-common = { path = "../../parachain/polkadot-parachains/common"} #[patch."https://github.com/integritee-network/pallets.git"] -#pallet-claims = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#pallet-enclave-bridge = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#pallet-teerex = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#pallet-sidechain = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#pallet-parentchain = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#sgx-verify = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#pallet-teeracle = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#test-utils = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#claims-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#enclave-bridge-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#teerex-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#teeracle-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } -#common-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/make_parentchain_pallet_instantiable" } +#pallet-claims = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#pallet-enclave-bridge = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#pallet-teerex = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#pallet-sidechain = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#pallet-parentchain = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#sgx-verify = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#pallet-teeracle = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#test-utils = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#claims-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#enclave-bridge-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#teerex-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#teeracle-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } +#common-primitives = { git = "https://github.com/integritee-network//pallets", branch = "ab/parentchian-set-timestamp" } diff --git a/enclave-runtime/Enclave.edl b/enclave-runtime/Enclave.edl index 2244a3d86f..d633ac0a38 100644 --- a/enclave-runtime/Enclave.edl +++ b/enclave-runtime/Enclave.edl @@ -70,7 +70,7 @@ enclave { [in, size=header_size] uint8_t* header, uint32_t header_size ); - public sgx_status_t get_shard_creation_header( + public sgx_status_t get_shard_creation_info( [in, size=shard_size] uint8_t* shard, uint32_t shard_size, [out, size=creation_size] uint8_t* creation, uint32_t creation_size); diff --git a/enclave-runtime/src/initialization/global_components.rs b/enclave-runtime/src/initialization/global_components.rs index 76a061088f..b81166568e 100644 --- a/enclave-runtime/src/initialization/global_components.rs +++ b/enclave-runtime/src/initialization/global_components.rs @@ -170,7 +170,7 @@ pub type IntegriteeParentchainIndirectCallsExecutor = IndirectCallsExecutor< EnclaveStfEnclaveSigner, EnclaveTopPoolAuthor, EnclaveNodeMetadataRepository, - integritee::ShieldFundsAndInvokeFilter, + integritee::ExtrinsicFilter, EventCreator, integritee::ParentchainEventHandler, EnclaveTrustedCallSigned, @@ -212,7 +212,7 @@ pub type TargetAParentchainIndirectCallsExecutor = IndirectCallsExecutor< EnclaveStfEnclaveSigner, EnclaveTopPoolAuthor, EnclaveNodeMetadataRepository, - target_a::TargetAExtrinsicFilter, + target_a::ExtrinsicFilter, EventCreator, target_a::ParentchainEventHandler, EnclaveTrustedCallSigned, @@ -254,7 +254,7 @@ pub type TargetBParentchainIndirectCallsExecutor = IndirectCallsExecutor< EnclaveStfEnclaveSigner, EnclaveTopPoolAuthor, EnclaveNodeMetadataRepository, - target_b::TargetBExtrinsicFilter, + target_b::ExtrinsicFilter, EventCreator, target_b::ParentchainEventHandler, EnclaveTrustedCallSigned, diff --git a/enclave-runtime/src/initialization/parentchain/common.rs b/enclave-runtime/src/initialization/parentchain/common.rs index f0fdc5f674..01832132a0 100644 --- a/enclave-runtime/src/initialization/parentchain/common.rs +++ b/enclave-runtime/src/initialization/parentchain/common.rs @@ -46,7 +46,8 @@ use crate::{ use itp_component_container::ComponentGetter; use itp_nonce_cache::NonceCache; use itp_sgx_crypto::key_repository::AccessKey; -use itp_types::parentchain::{Header, ParentchainId}; +use itp_stf_interface::ShardCreationInfo; +use itp_types::parentchain::ParentchainId; use log::*; use sp_core::H256; use std::sync::Arc; @@ -56,7 +57,7 @@ pub(crate) fn create_integritee_parentchain_block_importer( stf_executor: Arc, extrinsics_factory: Arc, node_metadata_repository: Arc, - maybe_creation_header: Option
, + shard_creation_info: ShardCreationInfo, ) -> Result { let state_observer = GLOBAL_STATE_OBSERVER_COMPONENT.get()?; let top_pool_author = GLOBAL_TOP_POOL_AUTHOR_COMPONENT.get()?; @@ -81,7 +82,7 @@ pub(crate) fn create_integritee_parentchain_block_importer( stf_executor, extrinsics_factory, indirect_calls_executor, - maybe_creation_header, + shard_creation_info, ParentchainId::Integritee, )) } @@ -91,6 +92,7 @@ pub(crate) fn create_target_a_parentchain_block_importer( stf_executor: Arc, extrinsics_factory: Arc, node_metadata_repository: Arc, + shard_creation_info: ShardCreationInfo, ) -> Result { let state_observer = GLOBAL_STATE_OBSERVER_COMPONENT.get()?; let top_pool_author = GLOBAL_TOP_POOL_AUTHOR_COMPONENT.get()?; @@ -115,7 +117,7 @@ pub(crate) fn create_target_a_parentchain_block_importer( stf_executor, extrinsics_factory, indirect_calls_executor, - None, + shard_creation_info, ParentchainId::TargetA, )) } @@ -125,6 +127,7 @@ pub(crate) fn create_target_b_parentchain_block_importer( stf_executor: Arc, extrinsics_factory: Arc, node_metadata_repository: Arc, + shard_creation_info: ShardCreationInfo, ) -> Result { let state_observer = GLOBAL_STATE_OBSERVER_COMPONENT.get()?; let top_pool_author = GLOBAL_TOP_POOL_AUTHOR_COMPONENT.get()?; @@ -149,7 +152,7 @@ pub(crate) fn create_target_b_parentchain_block_importer( stf_executor, extrinsics_factory, indirect_calls_executor, - None, + shard_creation_info, ParentchainId::TargetB, )) } diff --git a/enclave-runtime/src/initialization/parentchain/integritee_parachain.rs b/enclave-runtime/src/initialization/parentchain/integritee_parachain.rs index db20703229..d6264c2ea4 100644 --- a/enclave-runtime/src/initialization/parentchain/integritee_parachain.rs +++ b/enclave-runtime/src/initialization/parentchain/integritee_parachain.rs @@ -40,7 +40,8 @@ use itp_types::parentchain::ParentchainId; use std::{path::PathBuf, sync::Arc}; pub use itc_parentchain::primitives::{ParachainBlock, ParachainHeader, ParachainParams}; -use itp_types::parentchain::Header; +use itp_stf_interface::ShardCreationInfo; + #[derive(Clone)] pub struct IntegriteeParachainHandler { pub genesis_header: ParachainHeader, @@ -55,7 +56,7 @@ impl IntegriteeParachainHandler { pub fn init( _base_path: PathBuf, params: ParachainParams, - maybe_creation_header: Option
, + shard_creation_info: ShardCreationInfo, ) -> Result { let ocall_api = GLOBAL_OCALL_API_COMPONENT.get()?; let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; @@ -92,7 +93,7 @@ impl IntegriteeParachainHandler { stf_executor.clone(), extrinsics_factory.clone(), node_metadata_repository.clone(), - maybe_creation_header, + shard_creation_info, )?; let import_dispatcher = match WorkerModeProvider::worker_mode() { diff --git a/enclave-runtime/src/initialization/parentchain/integritee_solochain.rs b/enclave-runtime/src/initialization/parentchain/integritee_solochain.rs index 77fe5cec54..37b95135e5 100644 --- a/enclave-runtime/src/initialization/parentchain/integritee_solochain.rs +++ b/enclave-runtime/src/initialization/parentchain/integritee_solochain.rs @@ -36,10 +36,11 @@ use crate::{ use itc_parentchain::light_client::{concurrent_access::ValidatorAccess, LightClientState}; use itp_component_container::ComponentGetter; use itp_settings::worker_mode::{ProvideWorkerMode, WorkerMode}; -use itp_types::parentchain::{Header, ParentchainId}; +use itp_types::parentchain::ParentchainId; use std::{path::PathBuf, sync::Arc}; pub use itc_parentchain::primitives::{SolochainBlock, SolochainHeader, SolochainParams}; +use itp_stf_interface::ShardCreationInfo; pub struct IntegriteeSolochainHandler { pub genesis_header: SolochainHeader, @@ -54,7 +55,7 @@ impl IntegriteeSolochainHandler { pub fn init( _base_path: PathBuf, params: SolochainParams, - maybe_creation_header: Option
, + shard_creation_info: ShardCreationInfo, ) -> Result { let ocall_api = GLOBAL_OCALL_API_COMPONENT.get()?; let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; @@ -91,7 +92,7 @@ impl IntegriteeSolochainHandler { stf_executor.clone(), extrinsics_factory.clone(), node_metadata_repository.clone(), - maybe_creation_header, + shard_creation_info, )?; let import_dispatcher = match WorkerModeProvider::worker_mode() { diff --git a/enclave-runtime/src/initialization/parentchain/mod.rs b/enclave-runtime/src/initialization/parentchain/mod.rs index f2a730b2cb..0062df8d46 100644 --- a/enclave-runtime/src/initialization/parentchain/mod.rs +++ b/enclave-runtime/src/initialization/parentchain/mod.rs @@ -17,7 +17,6 @@ use crate::{ error::Result, - get_shard_creation_parentchain_header_internal, initialization::{ global_components::{ GLOBAL_INTEGRITEE_PARACHAIN_HANDLER_COMPONENT, @@ -34,6 +33,7 @@ use crate::{ target_b_solochain::TargetBSolochainHandler, }, }, + shard_creation_info::get_shard_creation_info_internal, }; use codec::{Decode, Encode}; use integritee_parachain::IntegriteeParachainHandler; @@ -44,7 +44,7 @@ use itc_parentchain::{ }; use itp_component_container::ComponentInitializer; use itp_settings::worker_mode::ProvideWorkerMode; -use itp_types::parentchain::Header; + use std::{path::PathBuf, vec::Vec}; mod common; @@ -61,18 +61,7 @@ pub(crate) fn init_parentchain_components ) -> Result> { match ParentchainInitParams::decode(&mut encoded_params.as_slice())? { ParentchainInitParams::Parachain { id, shard, params } => { - let maybe_creation: Option<(ParentchainId, Header)> = - get_shard_creation_parentchain_header_internal(shard).ok(); - let maybe_creation_header = if let Some((creation_parachain_id, creation_header)) = - maybe_creation - { - if creation_parachain_id != ParentchainId::Integritee { - unimplemented!("only Integritee parentchain is supported for shard creation"); - } - Some(creation_header) - } else { - None - }; + let shard_creation_info = get_shard_creation_info_internal(shard)?; // todo: query timestamp of creation header to give a creation reference to target_a/b as well in order to fast-sync match id { @@ -80,7 +69,7 @@ pub(crate) fn init_parentchain_components let handler = IntegriteeParachainHandler::init::( base_path, params, - maybe_creation_header, + shard_creation_info, )?; let header = handler .validator_accessor @@ -89,8 +78,11 @@ pub(crate) fn init_parentchain_components Ok(header.encode()) }, ParentchainId::TargetA => { - let handler = - TargetAParachainHandler::init::(base_path, params)?; + let handler = TargetAParachainHandler::init::( + base_path, + params, + shard_creation_info, + )?; let header = handler .validator_accessor .execute_on_validator(|v| v.latest_finalized_header())?; @@ -98,8 +90,11 @@ pub(crate) fn init_parentchain_components Ok(header.encode()) }, ParentchainId::TargetB => { - let handler = - TargetBParachainHandler::init::(base_path, params)?; + let handler = TargetBParachainHandler::init::( + base_path, + params, + shard_creation_info, + )?; let header = handler .validator_accessor .execute_on_validator(|v| v.latest_finalized_header())?; @@ -109,25 +104,14 @@ pub(crate) fn init_parentchain_components } }, ParentchainInitParams::Solochain { id, shard, params } => { - let maybe_creation: Option<(ParentchainId, Header)> = - get_shard_creation_parentchain_header_internal(shard).ok(); - let maybe_creation_header = if let Some((creation_parachain_id, creation_header)) = - maybe_creation - { - if creation_parachain_id != ParentchainId::Integritee { - unimplemented!("only Integritee parentchain is supported for shard creation"); - } - Some(creation_header) - } else { - None - }; + let shard_creation_info = get_shard_creation_info_internal(shard)?; // todo: query timestamp of creation header to give a creation reference to target_a/b as well in order to fast-sync match id { ParentchainId::Integritee => { let handler = IntegriteeSolochainHandler::init::( base_path, params, - maybe_creation_header, + shard_creation_info, )?; let header = handler .validator_accessor @@ -136,8 +120,11 @@ pub(crate) fn init_parentchain_components Ok(header.encode()) }, ParentchainId::TargetA => { - let handler = - TargetASolochainHandler::init::(base_path, params)?; + let handler = TargetASolochainHandler::init::( + base_path, + params, + shard_creation_info, + )?; let header = handler .validator_accessor .execute_on_validator(|v| v.latest_finalized_header())?; @@ -145,8 +132,11 @@ pub(crate) fn init_parentchain_components Ok(header.encode()) }, ParentchainId::TargetB => { - let handler = - TargetBSolochainHandler::init::(base_path, params)?; + let handler = TargetBSolochainHandler::init::( + base_path, + params, + shard_creation_info, + )?; let header = handler .validator_accessor .execute_on_validator(|v| v.latest_finalized_header())?; diff --git a/enclave-runtime/src/initialization/parentchain/target_a_parachain.rs b/enclave-runtime/src/initialization/parentchain/target_a_parachain.rs index bf24f6fdd4..31799d636a 100644 --- a/enclave-runtime/src/initialization/parentchain/target_a_parachain.rs +++ b/enclave-runtime/src/initialization/parentchain/target_a_parachain.rs @@ -41,6 +41,7 @@ use itc_parentchain::light_client::{concurrent_access::ValidatorAccess, LightCli pub use itc_parentchain::primitives::{ParachainBlock, ParachainHeader, ParachainParams}; use itp_component_container::ComponentGetter; use itp_settings::worker_mode::{ProvideWorkerMode, WorkerMode}; +use itp_stf_interface::ShardCreationInfo; use itp_types::parentchain::ParentchainId; use std::{path::PathBuf, sync::Arc}; @@ -58,6 +59,7 @@ impl TargetAParachainHandler { pub fn init( _base_path: PathBuf, params: ParachainParams, + shard_creation_info: ShardCreationInfo, ) -> Result { let ocall_api = GLOBAL_OCALL_API_COMPONENT.get()?; let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; @@ -93,6 +95,7 @@ impl TargetAParachainHandler { stf_executor.clone(), extrinsics_factory.clone(), node_metadata_repository.clone(), + shard_creation_info, )?; let import_dispatcher = match WorkerModeProvider::worker_mode() { diff --git a/enclave-runtime/src/initialization/parentchain/target_a_solochain.rs b/enclave-runtime/src/initialization/parentchain/target_a_solochain.rs index f5cf2ae8ff..4348dc8e19 100644 --- a/enclave-runtime/src/initialization/parentchain/target_a_solochain.rs +++ b/enclave-runtime/src/initialization/parentchain/target_a_solochain.rs @@ -35,6 +35,7 @@ use itc_parentchain::light_client::{concurrent_access::ValidatorAccess, LightCli pub use itc_parentchain::primitives::{SolochainBlock, SolochainHeader, SolochainParams}; use itp_component_container::ComponentGetter; use itp_settings::worker_mode::{ProvideWorkerMode, WorkerMode}; +use itp_stf_interface::ShardCreationInfo; use itp_types::parentchain::ParentchainId; use std::{path::PathBuf, sync::Arc}; @@ -51,6 +52,7 @@ impl TargetASolochainHandler { pub fn init( _base_path: PathBuf, params: SolochainParams, + shard_creation_info: ShardCreationInfo, ) -> Result { let ocall_api = GLOBAL_OCALL_API_COMPONENT.get()?; let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; @@ -86,6 +88,7 @@ impl TargetASolochainHandler { stf_executor.clone(), extrinsics_factory.clone(), node_metadata_repository.clone(), + shard_creation_info, )?; let import_dispatcher = match WorkerModeProvider::worker_mode() { diff --git a/enclave-runtime/src/initialization/parentchain/target_b_parachain.rs b/enclave-runtime/src/initialization/parentchain/target_b_parachain.rs index be44224c65..113103ee87 100644 --- a/enclave-runtime/src/initialization/parentchain/target_b_parachain.rs +++ b/enclave-runtime/src/initialization/parentchain/target_b_parachain.rs @@ -41,6 +41,7 @@ use itc_parentchain::light_client::{concurrent_access::ValidatorAccess, LightCli pub use itc_parentchain::primitives::{ParachainBlock, ParachainHeader, ParachainParams}; use itp_component_container::ComponentGetter; use itp_settings::worker_mode::{ProvideWorkerMode, WorkerMode}; +use itp_stf_interface::ShardCreationInfo; use itp_types::parentchain::ParentchainId; use std::{path::PathBuf, sync::Arc}; @@ -58,6 +59,7 @@ impl TargetBParachainHandler { pub fn init( _base_path: PathBuf, params: ParachainParams, + shard_creation_info: ShardCreationInfo, ) -> Result { let ocall_api = GLOBAL_OCALL_API_COMPONENT.get()?; let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; @@ -93,6 +95,7 @@ impl TargetBParachainHandler { stf_executor.clone(), extrinsics_factory.clone(), node_metadata_repository.clone(), + shard_creation_info, )?; let import_dispatcher = match WorkerModeProvider::worker_mode() { diff --git a/enclave-runtime/src/initialization/parentchain/target_b_solochain.rs b/enclave-runtime/src/initialization/parentchain/target_b_solochain.rs index 842baa8129..edab731e6d 100644 --- a/enclave-runtime/src/initialization/parentchain/target_b_solochain.rs +++ b/enclave-runtime/src/initialization/parentchain/target_b_solochain.rs @@ -35,6 +35,7 @@ use itc_parentchain::light_client::{concurrent_access::ValidatorAccess, LightCli pub use itc_parentchain::primitives::{SolochainBlock, SolochainHeader, SolochainParams}; use itp_component_container::ComponentGetter; use itp_settings::worker_mode::{ProvideWorkerMode, WorkerMode}; +use itp_stf_interface::ShardCreationInfo; use itp_types::parentchain::ParentchainId; use std::{path::PathBuf, sync::Arc}; @@ -51,6 +52,7 @@ impl TargetBSolochainHandler { pub fn init( _base_path: PathBuf, params: SolochainParams, + shard_creation_info: ShardCreationInfo, ) -> Result { let ocall_api = GLOBAL_OCALL_API_COMPONENT.get()?; let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; @@ -86,6 +88,7 @@ impl TargetBSolochainHandler { stf_executor.clone(), extrinsics_factory.clone(), node_metadata_repository.clone(), + shard_creation_info, )?; let import_dispatcher = match WorkerModeProvider::worker_mode() { diff --git a/enclave-runtime/src/lib.rs b/enclave-runtime/src/lib.rs index 681b69688a..d08ccb0458 100644 --- a/enclave-runtime/src/lib.rs +++ b/enclave-runtime/src/lib.rs @@ -47,7 +47,7 @@ use crate::{ get_node_metadata_repository_from_target_b_solo_or_parachain, utf8_str_from_raw, DecodeRaw, }, }; -use codec::{Decode, Encode}; +use codec::Decode; use core::ffi::c_int; use itc_parentchain::{block_import_dispatcher::DispatchBlockImport, primitives::ParentchainId}; use itp_component_container::ComponentGetter; @@ -58,10 +58,8 @@ use itp_nonce_cache::{MutateNonce, Nonce}; use itp_settings::worker_mode::{ProvideWorkerMode, WorkerMode, WorkerModeProvider}; use itp_sgx_crypto::key_repository::AccessPubkey; -use itp_stf_interface::SHARD_CREATION_HEADER_KEY; -use itp_stf_state_handler::{handle_state::HandleState, query_shard_state::QueryShardState}; use itp_storage::{StorageProof, StorageProofChecker}; -use itp_types::{parentchain::Header, ShardIdentifier, SignedBlock}; +use itp_types::{ShardIdentifier, SignedBlock}; use itp_utils::write_slice_and_whitespace_pad; use log::*; use once_cell::sync::OnceCell; @@ -80,6 +78,7 @@ mod initialization; mod ipfs; mod ocall; mod shard_config; +mod shard_creation_info; mod shard_vault; mod utils; @@ -431,123 +430,6 @@ pub unsafe extern "C" fn init_shard(shard: *const u8, shard_size: u32) -> sgx_st sgx_status_t::SGX_SUCCESS } -#[no_mangle] -pub unsafe extern "C" fn init_shard_creation_parentchain_header( - shard: *const u8, - shard_size: u32, - parentchain_id: *const u8, - parentchain_id_size: u32, - header: *const u8, - header_size: u32, -) -> sgx_status_t { - let shard_identifier = - ShardIdentifier::from_slice(slice::from_raw_parts(shard, shard_size as usize)); - let header = match Header::decode(&mut slice::from_raw_parts(header, header_size as usize)) { - Ok(hdr) => hdr, - Err(e) => { - error!("Could not decode header: {:?}", e); - return sgx_status_t::SGX_ERROR_UNEXPECTED - }, - }; - let parentchain_id = - match ParentchainId::decode_raw(parentchain_id, parentchain_id_size as usize) { - Ok(id) => id, - Err(e) => { - error!("Could not decode parentchain id: {:?}", e); - return sgx_status_t::SGX_ERROR_UNEXPECTED - }, - }; - - if let Err(e) = - init_shard_creation_parentchain_header_internal(shard_identifier, parentchain_id, header) - { - error!( - "Failed to initialize first relevant parentchain header [{:?}]: {:?}", - parentchain_id, e - ); - return sgx_status_t::SGX_ERROR_UNEXPECTED - } - sgx_status_t::SGX_SUCCESS -} - -fn init_shard_creation_parentchain_header_internal( - shard: ShardIdentifier, - parentchain_id: ParentchainId, - header: Header, -) -> Result<()> { - if let Ok((id, _hdr)) = get_shard_creation_parentchain_header_internal(shard) { - error!("first relevant parentchain header has been previously initialized. cannot change: {:?}", id); - return Err(Error::Other( - "first relevant parentchain header has been previously initialized. cannot change" - .into(), - )) - } - debug!("initializing shard creation header: {:?}", parentchain_id); - - let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; - if !state_handler - .shard_exists(&shard) - .map_err(|_| Error::Other("get shard_exists failed".into()))? - { - return Err(Error::Other("shard not initialized".into())) - }; - - let (state_lock, mut state) = state_handler.load_for_mutation(&shard)?; - let value = (parentchain_id, header); - state.state.insert(SHARD_CREATION_HEADER_KEY.into(), value.encode()); - state_handler.write_after_mutation(state, state_lock, &shard)?; - - shard_config::init_shard_config(shard)?; - Ok(()) -} - -/// reads the shard vault account id form state if it has been initialized previously -pub(crate) fn get_shard_creation_parentchain_header_internal( - shard: ShardIdentifier, -) -> Result<(ParentchainId, Header)> { - let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; - - state_handler - .execute_on_current(&shard, |state, _| { - state - .state - .get::>(&SHARD_CREATION_HEADER_KEY.into()) - .and_then(|v| Decode::decode(&mut v.clone().as_slice()).ok()) - })? - .ok_or_else(|| { - Error::Other( - "failed to fetch shard creation parentchain header. has it been initialized?" - .into(), - ) - }) -} - -/// reads the shard vault account id form state if it has been initialized previously -#[no_mangle] -pub unsafe extern "C" fn get_shard_creation_header( - shard: *const u8, - shard_size: u32, - creation: *mut u8, - creation_size: u32, -) -> sgx_status_t { - let shard = ShardIdentifier::from_slice(slice::from_raw_parts(shard, shard_size as usize)); - - let shard_creation = match get_shard_creation_parentchain_header_internal(shard) { - Ok(creation) => creation, - Err(e) => { - warn!("Failed to fetch creation header: {:?}", e); - return sgx_status_t::SGX_ERROR_UNEXPECTED - }, - }; - trace!("fetched shard creation header from state: {:?}", shard_creation); - - let creation_slice = slice::from_raw_parts_mut(creation, creation_size as usize); - if let Err(e) = write_slice_and_whitespace_pad(creation_slice, shard_creation.encode()) { - return Error::BufferError(e).into() - }; - sgx_status_t::SGX_SUCCESS -} - #[no_mangle] pub unsafe extern "C" fn sync_parentchain( blocks_to_sync: *const u8, diff --git a/enclave-runtime/src/shard_creation_info.rs b/enclave-runtime/src/shard_creation_info.rs new file mode 100644 index 0000000000..93e2ce5208 --- /dev/null +++ b/enclave-runtime/src/shard_creation_info.rs @@ -0,0 +1,144 @@ +/* + Copyright 2021 Integritee 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. +*/ +use crate::{ + error::{Error, Result as EnclaveResult}, + initialization::global_components::{EnclaveStf, GLOBAL_STATE_HANDLER_COMPONENT}, + shard_config, + std::string::ToString, + utils::DecodeRaw, +}; +use codec::{Decode, Encode}; +use itp_component_container::ComponentGetter; + +use itp_stf_interface::{ + parentchain_pallet::ParentchainPalletInstancesInterface, ShardCreationInfo, ShardCreationQuery, +}; +use itp_stf_state_handler::{handle_state::HandleState, query_shard_state::QueryShardState}; +use itp_types::{ + parentchain::{Header, ParentchainId}, + ShardIdentifier, +}; +use itp_utils::write_slice_and_whitespace_pad; +use log::*; +use sgx_types::sgx_status_t; +use std::slice; + +#[no_mangle] +pub unsafe extern "C" fn init_shard_creation_parentchain_header( + shard: *const u8, + shard_size: u32, + parentchain_id: *const u8, + parentchain_id_size: u32, + header: *const u8, + header_size: u32, +) -> sgx_status_t { + let shard_identifier = + ShardIdentifier::from_slice(slice::from_raw_parts(shard, shard_size as usize)); + let header = match Header::decode(&mut slice::from_raw_parts(header, header_size as usize)) { + Ok(hdr) => hdr, + Err(e) => { + error!("Could not decode header: {:?}", e); + return sgx_status_t::SGX_ERROR_UNEXPECTED + }, + }; + let parentchain_id = + match ParentchainId::decode_raw(parentchain_id, parentchain_id_size as usize) { + Ok(id) => id, + Err(e) => { + error!("Could not decode parentchain id: {:?}", e); + return sgx_status_t::SGX_ERROR_UNEXPECTED + }, + }; + + if let Err(e) = + init_shard_creation_parentchain_header_internal(shard_identifier, parentchain_id, header) + { + error!( + "Failed to initialize first relevant parentchain header [{:?}]: {:?}", + parentchain_id, e + ); + return sgx_status_t::SGX_ERROR_UNEXPECTED + } + sgx_status_t::SGX_SUCCESS +} + +fn init_shard_creation_parentchain_header_internal( + shard: ShardIdentifier, + parentchain_id: ParentchainId, + header: Header, +) -> EnclaveResult<()> { + if let Some(_creation_block) = + get_shard_creation_info_internal(shard)?.for_parentchain(parentchain_id) + { + error!("first relevant parentchain header has been previously initialized. cannot change: {:?}", parentchain_id); + return Err(Error::Other( + "first relevant parentchain header has been previously initialized. cannot change" + .into(), + )) + } + debug!("initializing shard creation header: {:?}", parentchain_id); + + let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; + if !state_handler + .shard_exists(&shard) + .map_err(|_| Error::Other("get shard_exists failed".into()))? + { + return Err(Error::Other("shard not initialized".into())) + }; + + let (state_lock, mut state) = state_handler.load_for_mutation(&shard)?; + EnclaveStf::set_creation_block(&mut state, header, parentchain_id) + .map_err(|e| Error::Stf(e.to_string()))?; + state_handler.write_after_mutation(state, state_lock, &shard)?; + + shard_config::init_shard_config(shard)?; + Ok(()) +} + +/// reads the shard vault account id form state if it has been initialized previously +pub(crate) fn get_shard_creation_info_internal( + shard: ShardIdentifier, +) -> EnclaveResult { + let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?; + let (_state_lock, mut state) = state_handler.load_for_mutation(&shard)?; + Ok(EnclaveStf::get_shard_creation_info(&mut state)) +} + +/// reads the shard vault account id form state if it has been initialized previously +#[no_mangle] +pub unsafe extern "C" fn get_shard_creation_info( + shard: *const u8, + shard_size: u32, + creation: *mut u8, + creation_size: u32, +) -> sgx_status_t { + let shard = ShardIdentifier::from_slice(slice::from_raw_parts(shard, shard_size as usize)); + + let shard_creation_info = match get_shard_creation_info_internal(shard) { + Ok(creation) => creation, + Err(e) => { + warn!("Failed to fetch creation header: {:?}", e); + return sgx_status_t::SGX_ERROR_UNEXPECTED + }, + }; + trace!("fetched shard creation header from state: {:?}", shard_creation_info); + + let creation_slice = slice::from_raw_parts_mut(creation, creation_size as usize); + if let Err(e) = write_slice_and_whitespace_pad(creation_slice, shard_creation_info.encode()) { + return Error::BufferError(e).into() + }; + sgx_status_t::SGX_SUCCESS +} diff --git a/enclave-runtime/src/test/top_pool_tests.rs b/enclave-runtime/src/test/top_pool_tests.rs index 38fd8057b1..b535cf3934 100644 --- a/enclave-runtime/src/test/top_pool_tests.rs +++ b/enclave-runtime/src/test/top_pool_tests.rs @@ -136,7 +136,7 @@ pub fn submit_shielding_call_to_top_pool() { _, _, _, - integritee::ShieldFundsAndInvokeFilter, + integritee::ExtrinsicFilter, TestEventCreator, integritee::ParentchainEventHandler, TrustedCallSigned, diff --git a/service/Cargo.toml b/service/Cargo.toml index 6838864d59..b3f079d6b4 100644 --- a/service/Cargo.toml +++ b/service/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "integritee-service" -version = "0.12.10" +version = "0.12.11" authors = ["Integritee AG "] build = "build.rs" edition = "2021" @@ -49,6 +49,7 @@ itp-enclave-api = { path = "../core-primitives/enclave-api" } itp-enclave-metrics = { path = "../core-primitives/enclave-metrics" } itp-node-api = { path = "../core-primitives/node-api" } itp-settings = { path = "../core-primitives/settings" } +itp-stf-interface = { path = "../core-primitives/stf-interface" } itp-storage = { path = "../core-primitives/storage" } itp-types = { path = "../core-primitives/types" } itp-utils = { path = "../core-primitives/utils" } @@ -58,12 +59,12 @@ its-primitives = { path = "../sidechain/primitives" } its-rpc-handler = { path = "../sidechain/rpc-handler" } its-storage = { path = "../sidechain/storage" } -sgx-verify = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.10-polkadot-v0.9.42" } +sgx-verify = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.11-polkadot-v0.9.42" } # `default-features = false` to remove the jsonrpsee dependency. -enclave-bridge-primitives = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.10-polkadot-v0.9.42" } +enclave-bridge-primitives = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.11-polkadot-v0.9.42" } # disable unsupported jsonrpcsee substrate-api-client = { default-features = false, features = ["std", "sync-api"], git = "https://github.com/scs/substrate-api-client.git", branch = "polkadot-v0.9.42-tag-v0.14.0" } -teerex-primitives = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.10-polkadot-v0.9.42" } +teerex-primitives = { git = "https://github.com/integritee-network/pallets.git", branch = "sdk-v0.12.11-polkadot-v0.9.42" } # Substrate dependencies frame-support = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } diff --git a/service/src/main_impl.rs b/service/src/main_impl.rs index 1a399cc082..e51c4a460f 100644 --- a/service/src/main_impl.rs +++ b/service/src/main_impl.rs @@ -515,7 +515,12 @@ fn start_worker( primary.to_ss58check(), ); info!("The primary worker enclave is {:?}", primary_enclave); - if enclave.get_shard_creation_header(shard).is_err() { + if enclave + .get_shard_creation_info(shard) + .unwrap() + .for_parentchain(ParentchainId::Integritee) + .is_none() + { //obtain provisioning from last active worker as this hasn't been done before info!("my state doesn't know the creation header of the shard. will request provisioning"); sync_state::sync_state::<_, _, WorkerModeProvider>( @@ -552,7 +557,7 @@ fn start_worker( } }, }; - debug!("getting shard creation: {:?}", enclave.get_shard_creation_header(shard)); + debug!("getting shard creation: {:?}", enclave.get_shard_creation_info(shard)); initialization_handler.registered_on_parentchain(); let (integritee_parentchain_handler, integritee_last_synced_header_at_last_run) = diff --git a/service/src/parentchain_handler.rs b/service/src/parentchain_handler.rs index c0e1b03854..23cb2848fa 100644 --- a/service/src/parentchain_handler.rs +++ b/service/src/parentchain_handler.rs @@ -173,22 +173,14 @@ where "[{:?}] Syncing blocks from {} to {}", id, last_synced_header.number, curr_block_number ); - let maybe_creation = self.enclave_api.get_shard_creation_header(&shard).ok(); - let maybe_creation_header = - if let Some((creation_parentchain_id, creation_header)) = maybe_creation { - trace!( - "shard_creation header is from {:?}: {:?}", - creation_parentchain_id, - creation_header - ); - if *id == creation_parentchain_id { - Some(creation_header) - } else { - None - } - } else { - None - }; + let creation_info = self.enclave_api.get_shard_creation_info(&shard)?; + let maybe_creation_block = if let Some(creation_block) = creation_info.for_parentchain(*id) + { + trace!("[{:?}] shard creation block: {:?}", id, creation_block); + Some(creation_block) + } else { + None + }; let mut until_synced_header = last_synced_header; loop { @@ -206,11 +198,11 @@ where return Ok(until_synced_header) } - let skip_invocations = if let Some(creation_header) = maybe_creation_header.clone() { + let skip_invocations = if let Some(creation_block) = maybe_creation_block { let max_blocknumber_in_chunk = block_chunk_to_sync.last().map_or_else(|| 0, |b| b.block.header.number()); - if max_blocknumber_in_chunk < *creation_header.number() { - trace!("skipping invocations for fast-sync for blocks older than shard creation: {} < {}", max_blocknumber_in_chunk, creation_header.number()); + if max_blocknumber_in_chunk < creation_block.number { + trace!("skipping invocations for fast-sync for blocks older than shard creation: {} < {}", max_blocknumber_in_chunk, creation_block.number); true } else { false diff --git a/service/src/tests/mocks/enclave_api_mock.rs b/service/src/tests/mocks/enclave_api_mock.rs index 813eb4739c..77d1b80307 100644 --- a/service/src/tests/mocks/enclave_api_mock.rs +++ b/service/src/tests/mocks/enclave_api_mock.rs @@ -24,6 +24,7 @@ use itc_parentchain::primitives::{ }; use itp_enclave_api::{enclave_base::EnclaveBase, sidechain::Sidechain, EnclaveResult}; use itp_settings::worker::MR_ENCLAVE_SIZE; +use itp_stf_interface::ShardCreationInfo; use itp_storage::StorageProof; use itp_types::{ parentchain::{Balance, Header}, @@ -82,10 +83,7 @@ impl EnclaveBase for EnclaveMock { unimplemented!() } - fn get_shard_creation_header( - &self, - shard: &ShardIdentifier, - ) -> EnclaveResult<(ParentchainId, Header)> { + fn get_shard_creation_info(&self, shard: &ShardIdentifier) -> EnclaveResult { unimplemented!() }