diff --git a/Cargo.lock b/Cargo.lock index aa42534e7c..b36058e33f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3221,6 +3221,7 @@ dependencies = [ "itp-sgx-crypto", "itp-sgx-runtime-primitives", "itp-stf-executor", + "itp-stf-interface", "itp-stf-primitives", "itp-test", "itp-top-pool-author", diff --git a/app-libs/parentchain-interface/src/integritee/event_filter.rs b/app-libs/parentchain-interface/src/integritee/event_filter.rs index c9ecb19a85..d403a93948 100644 --- a/app-libs/parentchain-interface/src/integritee/event_filter.rs +++ b/app-libs/parentchain-interface/src/integritee/event_filter.rs @@ -74,12 +74,7 @@ impl FilterEvents for FilterableEvents { .iter() .flatten() // flatten filters out the nones .filter_map(|ev| match ev.as_event::() { - Ok(maybe_event) => { - if maybe_event.is_none() { - log::warn!("Transfer event does not exist in parentchain metadata"); - }; - maybe_event - }, + Ok(maybe_event) => maybe_event, Err(e) => { log::error!("Could not decode event: {:?}", e); None diff --git a/app-libs/parentchain-interface/src/integritee/event_handler.rs b/app-libs/parentchain-interface/src/integritee/event_handler.rs index 8e01cbd978..3711b861c0 100644 --- a/app-libs/parentchain-interface/src/integritee/event_handler.rs +++ b/app-libs/parentchain-interface/src/integritee/event_handler.rs @@ -22,17 +22,9 @@ use ita_stf::{Getter, TrustedCall, TrustedCallSigned}; use itc_parentchain_indirect_calls_executor::error::Error; use itp_stf_primitives::{traits::IndirectExecutor, types::TrustedOperation}; use itp_types::parentchain::{AccountId, FilterEvents, HandleParentchainEvents, ParentchainError}; +use itp_utils::hex::hex_encode; use log::*; -type Seed = [u8; 32]; - -const ALICE_ENCODED: Seed = [ - 212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, - 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125, -]; - -const SHIELDING_ACCOUNT: AccountId = AccountId::new(ALICE_ENCODED); - pub struct ParentchainEventHandler {} impl ParentchainEventHandler { @@ -61,15 +53,22 @@ impl HandleParentchainEvents where Executor: IndirectExecutor, { - fn handle_events(executor: &Executor, events: impl FilterEvents) -> Result<(), Error> { + fn handle_events( + executor: &Executor, + events: impl FilterEvents, + vault_account: &AccountId, + ) -> Result<(), Error> { let filter_events = events.get_transfer_events(); - + trace!( + "filtering transfer events to shard vault account: {}", + hex_encode(vault_account.encode().as_slice()) + ); if let Ok(events) = filter_events { events .iter() - .filter(|&event| event.to == SHIELDING_ACCOUNT) + .filter(|&event| event.to == *vault_account) .try_for_each(|event| { - info!("transfer_event: {}", event); + info!("found transfer_event to vault account: {}", event); //call = IndirectCall::ShieldFunds(ShieldFundsArgs{ }) Self::shield_funds(executor, &event.from, event.amount) }) diff --git a/app-libs/parentchain-interface/src/target_a/event_handler.rs b/app-libs/parentchain-interface/src/target_a/event_handler.rs index 40dd0b8867..96cd3997ec 100644 --- a/app-libs/parentchain-interface/src/target_a/event_handler.rs +++ b/app-libs/parentchain-interface/src/target_a/event_handler.rs @@ -20,7 +20,7 @@ pub use ita_sgx_runtime::{Balance, Index}; use ita_stf::TrustedCallSigned; use itc_parentchain_indirect_calls_executor::error::Error; use itp_stf_primitives::traits::IndirectExecutor; -use itp_types::parentchain::{FilterEvents, HandleParentchainEvents}; +use itp_types::parentchain::{AccountId, FilterEvents, HandleParentchainEvents}; use log::*; pub struct ParentchainEventHandler {} @@ -30,7 +30,11 @@ impl HandleParentchainEvents where Executor: IndirectExecutor, { - fn handle_events(_executor: &Executor, _events: impl FilterEvents) -> Result<(), Error> { + fn handle_events( + _executor: &Executor, + _events: impl FilterEvents, + _vault_account: &AccountId, + ) -> Result<(), Error> { debug!("not handling any events for target A"); Ok(()) } diff --git a/app-libs/parentchain-interface/src/target_b/event_handler.rs b/app-libs/parentchain-interface/src/target_b/event_handler.rs index cb33206a8b..39a5555973 100644 --- a/app-libs/parentchain-interface/src/target_b/event_handler.rs +++ b/app-libs/parentchain-interface/src/target_b/event_handler.rs @@ -20,7 +20,7 @@ pub use ita_sgx_runtime::{Balance, Index}; use ita_stf::TrustedCallSigned; use itc_parentchain_indirect_calls_executor::error::Error; use itp_stf_primitives::traits::IndirectExecutor; -use itp_types::parentchain::{FilterEvents, HandleParentchainEvents}; +use itp_types::parentchain::{AccountId, FilterEvents, HandleParentchainEvents}; use log::*; pub struct ParentchainEventHandler {} @@ -30,7 +30,11 @@ impl HandleParentchainEvents where Executor: IndirectExecutor, { - fn handle_events(_executor: &Executor, _events: impl FilterEvents) -> Result<(), Error> { + fn handle_events( + _executor: &Executor, + _events: impl FilterEvents, + _vault_account: &AccountId, + ) -> Result<(), Error> { debug!("not handling any events for target B"); Ok(()) } diff --git a/app-libs/stf/src/stf_sgx.rs b/app-libs/stf/src/stf_sgx.rs index 88d14822cb..2257dc6dc0 100644 --- a/app-libs/stf/src/stf_sgx.rs +++ b/app-libs/stf/src/stf_sgx.rs @@ -26,11 +26,15 @@ use itp_stf_interface::{ parentchain_pallet::ParentchainPalletInterface, sudo_pallet::SudoPalletInterface, system_pallet::{SystemPalletAccountInterface, SystemPalletEventInterface}, - ExecuteCall, ExecuteGetter, InitState, StateCallInterface, StateGetterInterface, UpdateState, + ExecuteCall, ExecuteGetter, InitState, ShardVaultQuery, StateCallInterface, + StateGetterInterface, UpdateState, SHARD_VAULT_KEY, }; use itp_stf_primitives::{error::StfError, traits::TrustedCallVerification}; use itp_storage::storage_value_key; -use itp_types::{parentchain::ParentchainId, OpaqueCall}; +use itp_types::{ + parentchain::{AccountId, ParentchainId}, + OpaqueCall, +}; use itp_utils::stringify::account_id_to_string; use log::*; use sp_runtime::traits::StaticLookup; @@ -160,6 +164,17 @@ where } } +impl ShardVaultQuery for Stf +where + State: SgxExternalitiesTrait + Debug, +{ + fn get_vault(state: &mut State) -> Option { + state + .get(SHARD_VAULT_KEY.as_bytes()) + .and_then(|v| Decode::decode(&mut v.clone().as_slice()).ok()) + } +} + impl SudoPalletInterface for Stf where State: SgxExternalitiesTrait, diff --git a/core-primitives/stf-executor/src/enclave_signer.rs b/core-primitives/stf-executor/src/enclave_signer.rs index 6b41518d24..c6e2435339 100644 --- a/core-primitives/stf-executor/src/enclave_signer.rs +++ b/core-primitives/stf-executor/src/enclave_signer.rs @@ -17,7 +17,7 @@ use crate::{ error::{Error, Result}, - traits::StfEnclaveSigning, + traits::{StfEnclaveSigning, StfShardVaultQuery}, H256, }; use codec::{Decode, Encode}; @@ -25,7 +25,7 @@ use core::{fmt::Debug, marker::PhantomData}; use itp_ocall_api::EnclaveAttestationOCallApi; use itp_sgx_crypto::{ed25519_derivation::DeriveEd25519, key_repository::AccessKey}; use itp_sgx_externalities::SgxExternalitiesTrait; -use itp_stf_interface::system_pallet::SystemPalletAccountInterface; +use itp_stf_interface::{system_pallet::SystemPalletAccountInterface, ShardVaultQuery}; use itp_stf_primitives::{ traits::TrustedCallSigning, types::{AccountId, KeyPair}, @@ -60,7 +60,8 @@ where StateObserver::StateType: SgxExternalitiesTrait, ShieldingKeyRepository: AccessKey, ::KeyType: DeriveEd25519, - Stf: SystemPalletAccountInterface, + Stf: SystemPalletAccountInterface + + ShardVaultQuery, Stf::Index: Into, TopPoolAuthor: AuthorApi + Send + Sync + 'static, TCS: PartialEq + Encode + Decode + Debug + Send + Sync, @@ -105,7 +106,8 @@ where StateObserver::StateType: SgxExternalitiesTrait, ShieldingKeyRepository: AccessKey, ::KeyType: DeriveEd25519, - Stf: SystemPalletAccountInterface, + Stf: SystemPalletAccountInterface + + ShardVaultQuery, Stf::Index: Into, TopPoolAuthor: AuthorApi + Send + Sync + 'static, TCS: PartialEq + Encode + Decode + Debug + Send + Sync, @@ -142,3 +144,25 @@ where )) } } + +impl StfShardVaultQuery + for StfEnclaveSigner +where + OCallApi: EnclaveAttestationOCallApi, + StateObserver: ObserveState, + StateObserver::StateType: SgxExternalitiesTrait, + ShieldingKeyRepository: AccessKey, + ::KeyType: DeriveEd25519, + Stf: SystemPalletAccountInterface + + ShardVaultQuery, + Stf::Index: Into, + TopPoolAuthor: AuthorApi + Send + Sync + 'static, + TCS: PartialEq + Encode + Decode + Debug + Send + Sync, + G: PartialEq + Encode + Decode + Debug + Send + Sync, +{ + fn get_shard_vault(&self, shard: &ShardIdentifier) -> Result { + let vault = self.state_observer.observe_state(shard, move |state| Stf::get_vault(state))?; + + vault.ok_or_else(|| Error::Other("shard vault undefined".into())) + } +} diff --git a/core-primitives/stf-executor/src/mocks.rs b/core-primitives/stf-executor/src/mocks.rs index fd877f34e7..3539ca88a5 100644 --- a/core-primitives/stf-executor/src/mocks.rs +++ b/core-primitives/stf-executor/src/mocks.rs @@ -35,6 +35,7 @@ use sp_runtime::traits::Header as HeaderTrait; use std::sync::RwLock; use std::{boxed::Box, marker::PhantomData, ops::Deref, time::Duration, vec::Vec}; +use crate::traits::StfShardVaultQuery; use itp_stf_primitives::{ traits::{GetterAuthorization, TrustedCallVerification}, types::TrustedOperation, @@ -136,6 +137,12 @@ impl StfEnclaveSigning for StfEnclaveSigne } } +impl StfShardVaultQuery for StfEnclaveSignerMock { + fn get_shard_vault(&self, _shard: &ShardIdentifier) -> Result { + Err(crate::error::Error::Other("shard vault undefined".into())) + } +} + /// GetState mock #[derive(Default)] pub struct GetStateMock { diff --git a/core-primitives/stf-executor/src/traits.rs b/core-primitives/stf-executor/src/traits.rs index 5aed037b88..9f82b473b1 100644 --- a/core-primitives/stf-executor/src/traits.rs +++ b/core-primitives/stf-executor/src/traits.rs @@ -49,6 +49,10 @@ where ) -> Result; } +pub trait StfShardVaultQuery { + fn get_shard_vault(&self, shard: &ShardIdentifier) -> Result; +} + /// Proposes a state update to `Externalities`. pub trait StateUpdateProposer where diff --git a/core-primitives/stf-interface/src/lib.rs b/core-primitives/stf-interface/src/lib.rs index dd46c6c5ce..bdcf00238e 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::ParentchainId, OpaqueCall}; +use itp_types::{ + parentchain::{AccountId, ParentchainId}, + OpaqueCall, +}; #[cfg(feature = "mocks")] pub mod mocks; @@ -44,6 +47,11 @@ pub trait InitState { fn init_state(enclave_account: AccountId) -> State; } +/// Interface to query shard vault account for shard +pub trait ShardVaultQuery { + fn get_vault(state: &mut S) -> Option; +} + /// Interface for all functions calls necessary to update an already /// initialized state. pub trait UpdateState { diff --git a/core-primitives/types/src/parentchain.rs b/core-primitives/types/src/parentchain.rs index 7bb9047cc4..80e2485ea5 100644 --- a/core-primitives/types/src/parentchain.rs +++ b/core-primitives/types/src/parentchain.rs @@ -129,6 +129,7 @@ where fn handle_events( executor: &Executor, events: impl FilterEvents, + vault_account: &AccountId, ) -> core::result::Result<(), Error>; } diff --git a/core/parentchain/block-importer/src/block_importer.rs b/core/parentchain/block-importer/src/block_importer.rs index 008ed65b82..8455224de6 100644 --- a/core/parentchain/block-importer/src/block_importer.rs +++ b/core/parentchain/block-importer/src/block_importer.rs @@ -144,7 +144,7 @@ impl< Ok(executed_shielding_calls) => { calls.push(executed_shielding_calls); }, - Err(_) => error!("[{:?}] Error executing relevant extrinsics", id), + Err(e) => error!("[{:?}] Error executing relevant extrinsics: {:?}", id, e), }; info!( diff --git a/core/parentchain/indirect-calls-executor/Cargo.toml b/core/parentchain/indirect-calls-executor/Cargo.toml index 37d49102c8..9f7356edeb 100644 --- a/core/parentchain/indirect-calls-executor/Cargo.toml +++ b/core/parentchain/indirect-calls-executor/Cargo.toml @@ -16,6 +16,7 @@ itp-ocall-api = { path = "../../../core-primitives/ocall-api", default-features itp-sgx-crypto = { path = "../../../core-primitives/sgx/crypto", default-features = false } itp-sgx-runtime-primitives = { path = "../../../core-primitives/sgx-runtime-primitives", 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-stf-primitives = { path = "../../../core-primitives/stf-primitives", default-features = false } itp-test = { path = "../../../core-primitives/test", default-features = false } itp-top-pool-author = { path = "../../../core-primitives/top-pool-author", default-features = false } @@ -59,6 +60,7 @@ std = [ "itp-ocall-api/std", "itp-sgx-crypto/std", "itp-stf-executor/std", + "itp-stf-interface/std", "itp-top-pool-author/std", "itp-api-client-types/std", "itp-test/std", diff --git a/core/parentchain/indirect-calls-executor/src/executor.rs b/core/parentchain/indirect-calls-executor/src/executor.rs index 34946347ba..76f86ea169 100644 --- a/core/parentchain/indirect-calls-executor/src/executor.rs +++ b/core/parentchain/indirect-calls-executor/src/executor.rs @@ -33,7 +33,7 @@ use itp_node_api::metadata::{ NodeMetadataTrait, }; use itp_sgx_crypto::{key_repository::AccessKey, ShieldingCryptoDecrypt, ShieldingCryptoEncrypt}; -use itp_stf_executor::traits::StfEnclaveSigning; +use itp_stf_executor::traits::{StfEnclaveSigning, StfShardVaultQuery}; use itp_stf_primitives::{ traits::{IndirectExecutor, TrustedCallSigning, TrustedCallVerification}, types::AccountId, @@ -129,7 +129,7 @@ impl< ShieldingKeyRepository: AccessKey, ::KeyType: ShieldingCryptoDecrypt + ShieldingCryptoEncrypt, - StfEnclaveSigner: StfEnclaveSigning, + StfEnclaveSigner: StfEnclaveSigning + StfShardVaultQuery, TopPoolAuthor: AuthorApi + Send + Sync + 'static, NodeMetadataProvider: AccessNodeMetadata, FilterIndirectCalls: FilterIntoDataFrom, @@ -166,7 +166,10 @@ impl< })?; trace!("xt_statuses:: {:?}", xt_statuses); - ParentchainEventHandler::handle_events(self, events)?; + let shard = self.get_default_shard(); + if let Ok(vault) = self.stf_enclave_signer.get_shard_vault(&shard) { + ParentchainEventHandler::handle_events(self, events, &vault)?; + } // This would be catastrophic but should never happen if xt_statuses.len() != block.extrinsics().len() { @@ -253,7 +256,7 @@ impl< ShieldingKeyRepository: AccessKey, ::KeyType: ShieldingCryptoDecrypt + ShieldingCryptoEncrypt, - StfEnclaveSigner: StfEnclaveSigning, + StfEnclaveSigner: StfEnclaveSigning + StfShardVaultQuery, TopPoolAuthor: AuthorApi + Send + Sync + 'static, TCS: PartialEq + Encode + Decode + Debug + Clone + Send + Sync + TrustedCallVerification, G: PartialEq + Encode + Decode + Debug + Clone + Send + Sync, diff --git a/core/parentchain/indirect-calls-executor/src/mock.rs b/core/parentchain/indirect-calls-executor/src/mock.rs index a12a4b820c..bb7ad5a8db 100644 --- a/core/parentchain/indirect-calls-executor/src/mock.rs +++ b/core/parentchain/indirect-calls-executor/src/mock.rs @@ -187,6 +187,7 @@ where fn handle_events( _: &Executor, _: impl itp_types::parentchain::FilterEvents, + _: &AccountId, ) -> core::result::Result<(), Error> { Ok(()) } diff --git a/enclave-runtime/Cargo.lock b/enclave-runtime/Cargo.lock index 794b574e44..1aabcad360 100644 --- a/enclave-runtime/Cargo.lock +++ b/enclave-runtime/Cargo.lock @@ -1856,6 +1856,7 @@ dependencies = [ "itp-sgx-crypto", "itp-sgx-runtime-primitives", "itp-stf-executor", + "itp-stf-interface", "itp-stf-primitives", "itp-test", "itp-top-pool-author",