diff --git a/tee-worker/omni-executor/parentchain/listener/src/event_handler.rs b/tee-worker/omni-executor/parentchain/listener/src/event_handler.rs index e9968023ab..0e032727d4 100644 --- a/tee-worker/omni-executor/parentchain/listener/src/event_handler.rs +++ b/tee-worker/omni-executor/parentchain/listener/src/event_handler.rs @@ -40,8 +40,8 @@ pub struct IntentEventHandler< MetadataProviderT: MetadataProvider, EthereumIntentExecutorT: IntentExecutor, KeyStoreT: KeyStore, - RpcClient: SubstrateRpcClient, - RpcClientFactory: SubstrateRpcClientFactory, + RpcClient: SubstrateRpcClient, + RpcClientFactory: SubstrateRpcClientFactory, > { metadata_provider: Arc, ethereum_intent_executor: EthereumIntentExecutorT, @@ -65,8 +65,8 @@ impl< MetadataProviderT: MetadataProvider, EthereumIntentExecutorT: IntentExecutor, KeyStoreT: KeyStore, - RpcClient: SubstrateRpcClient, - RpcClientFactory: SubstrateRpcClientFactory, + RpcClient: SubstrateRpcClient, + RpcClientFactory: SubstrateRpcClientFactory, > IntentEventHandler< ChainConfig, @@ -113,8 +113,8 @@ impl< >, EthereumIntentExecutorT: IntentExecutor + Send + Sync, KeyStoreT: KeyStore + Send + Sync, - RpcClient: SubstrateRpcClient + Send + Sync, - RpcClientFactory: SubstrateRpcClientFactory + Send + Sync, + RpcClient: SubstrateRpcClient + Send + Sync, + RpcClientFactory: SubstrateRpcClientFactory + Send + Sync, > EventHandler for IntentEventHandler< ChainConfig, @@ -182,23 +182,22 @@ impl< crate::litentry_rococo::runtime_types::core_primitives::intent::Intent::SystemRemark(_) => None, crate::litentry_rococo::runtime_types::core_primitives::intent::Intent::TransferNative(_) => None, }; - + let mut execution_result = + crate::litentry_rococo::omni_account::calls::types::intent_executed::Result::Success; if let Some(intent) = maybe_intent { // to explicitly handle all intent variants match intent { Intent::CallEthereum(_, _) => { - self.ethereum_intent_executor.execute(intent).await.map_err(|_| { - // assume for now we can easily recover - log::error!("Error executing intent"); - Error::RecoverableError - })?; + if let Err(e) = self.ethereum_intent_executor.execute(intent).await { + log::error!("Error executing intent: {:?}", e); + execution_result = crate::litentry_rococo::omni_account::calls::types::intent_executed::Result::Failure; + } }, Intent::TransferEthereum(_, _) => { - self.ethereum_intent_executor.execute(intent).await.map_err(|_| { - // assume for now we can easily recover - log::error!("Error executing intent"); - Error::RecoverableError - })?; + if let Err(e) = self.ethereum_intent_executor.execute(intent).await { + log::error!("Error executing intent: {:?}", e); + execution_result = crate::litentry_rococo::omni_account::calls::types::intent_executed::Result::Failure; + } }, } @@ -217,9 +216,6 @@ impl< Error::NonRecoverableError })?; - let execution_result = - crate::litentry_rococo::omni_account::calls::types::intent_executed::Result::Success; - let call = crate::litentry_rococo::tx().omni_account().intent_executed( decoded.who, decoded.intent, diff --git a/tee-worker/omni-executor/parentchain/listener/src/fetcher.rs b/tee-worker/omni-executor/parentchain/listener/src/fetcher.rs index 160dce2347..c0ef0ffd0b 100644 --- a/tee-worker/omni-executor/parentchain/listener/src/fetcher.rs +++ b/tee-worker/omni-executor/parentchain/listener/src/fetcher.rs @@ -20,22 +20,28 @@ use crate::rpc_client::SubstrateRpcClientFactory; use async_trait::async_trait; use executor_core::fetcher::{EventsFetcher, LastFinalizedBlockNumFetcher}; use log::error; +use std::marker::PhantomData; use std::sync::Arc; /// Used for fetching data from parentchain pub struct Fetcher< - RpcClient: SubstrateRpcClient, - RpcClientFactory: SubstrateRpcClientFactory, + AccountId, + RpcClient: SubstrateRpcClient, + RpcClientFactory: SubstrateRpcClientFactory, > { client_factory: Arc, client: Option, + phantom_data: PhantomData, } -impl> - Fetcher +impl< + AccountId, + RpcClient: SubstrateRpcClient, + RpcClientFactory: SubstrateRpcClientFactory, + > Fetcher { pub fn new(client_factory: Arc) -> Self { - Self { client: None, client_factory } + Self { client: None, client_factory, phantom_data: PhantomData } } async fn connect_if_needed(&mut self) { @@ -50,9 +56,10 @@ impl + Sync + Send, - > LastFinalizedBlockNumFetcher for Fetcher + AccountId: Sync + Send, + RpcClient: SubstrateRpcClient + Sync + Send, + RpcClientFactory: SubstrateRpcClientFactory + Sync + Send, + > LastFinalizedBlockNumFetcher for Fetcher { async fn get_last_finalized_block_num(&mut self) -> Result, ()> { self.connect_if_needed().await; @@ -68,9 +75,10 @@ impl< #[async_trait] impl< - RpcClient: SubstrateRpcClient + Sync + Send, - RpcClientFactory: SubstrateRpcClientFactory + Sync + Send, - > EventsFetcher for Fetcher + AccountId: Sync + Send, + RpcClient: SubstrateRpcClient + Sync + Send, + RpcClientFactory: SubstrateRpcClientFactory + Sync + Send, + > EventsFetcher for Fetcher { async fn get_block_events(&mut self, block_num: u64) -> Result, ()> { self.connect_if_needed().await; diff --git a/tee-worker/omni-executor/parentchain/listener/src/listener.rs b/tee-worker/omni-executor/parentchain/listener/src/listener.rs index f98f87ae52..5719f9caf2 100644 --- a/tee-worker/omni-executor/parentchain/listener/src/listener.rs +++ b/tee-worker/omni-executor/parentchain/listener/src/listener.rs @@ -22,6 +22,7 @@ use crate::primitives::SyncCheckpoint; use crate::primitives::{BlockEvent, EventId}; use executor_core::listener::Listener; use subxt::Metadata; +use subxt_core::Config; pub type IntentEventId = EventId; @@ -32,7 +33,7 @@ pub type ParentchainListener< ChainConfig, EthereumIntentExecutor, > = Listener< - Fetcher, + Fetcher<::AccountId, RpcClient, RpcClientFactory>, SyncCheckpoint, CheckpointRepository, IntentEventId, diff --git a/tee-worker/omni-executor/parentchain/listener/src/metadata.rs b/tee-worker/omni-executor/parentchain/listener/src/metadata.rs index 0f1b202210..d526b196fb 100644 --- a/tee-worker/omni-executor/parentchain/listener/src/metadata.rs +++ b/tee-worker/omni-executor/parentchain/listener/src/metadata.rs @@ -18,6 +18,7 @@ use crate::rpc_client::{SubstrateRpcClient, SubstrateRpcClientFactory, SubxtClie use async_trait::async_trait; use parity_scale_codec::Decode; use subxt::{Config, Metadata}; +use subxt_core::utils::AccountId32; #[async_trait] pub trait MetadataProvider { @@ -35,7 +36,9 @@ impl SubxtMetadataProvider { } #[async_trait] -impl MetadataProvider for SubxtMetadataProvider { +impl> MetadataProvider + for SubxtMetadataProvider +{ async fn get(&self, block_num: Option) -> Metadata { let mut client = self.client_factory.new_client().await.unwrap(); let raw_metadata = client.get_raw_metadata(block_num).await.unwrap(); diff --git a/tee-worker/omni-executor/parentchain/listener/src/rpc_client.rs b/tee-worker/omni-executor/parentchain/listener/src/rpc_client.rs index bc43904964..727e5fac63 100644 --- a/tee-worker/omni-executor/parentchain/listener/src/rpc_client.rs +++ b/tee-worker/omni-executor/parentchain/listener/src/rpc_client.rs @@ -26,7 +26,9 @@ use subxt::backend::legacy::LegacyRpcMethods; use subxt::backend::BlockRef; use subxt::config::Header; use subxt::events::EventsClient; +use subxt::tx::TxClient; use subxt::{Config, OnlineClient}; +use subxt_core::utils::AccountId32; pub struct RuntimeVersion { pub spec_version: u32, @@ -35,24 +37,28 @@ pub struct RuntimeVersion { /// For fetching data from Substrate RPC node #[async_trait] -pub trait SubstrateRpcClient { +pub trait SubstrateRpcClient { async fn get_last_finalized_block_num(&mut self) -> Result; async fn get_block_events(&mut self, block_num: u64) -> Result, ()>; async fn get_raw_metadata(&mut self, block_num: Option) -> Result, ()>; async fn submit_tx(&mut self, raw_tx: &[u8]) -> Result<(), ()>; async fn runtime_version(&mut self) -> Result; async fn get_genesis_hash(&mut self) -> Result, ()>; + async fn get_account_nonce(&mut self, account_id: &AccountId) -> Result; } pub struct SubxtClient { legacy: LegacyRpcMethods, events: EventsClient>, + tx: TxClient>, } impl SubxtClient {} #[async_trait] -impl SubstrateRpcClient for SubxtClient { +impl> SubstrateRpcClient + for SubxtClient +{ async fn get_last_finalized_block_num(&mut self) -> Result { let finalized_header = self.legacy.chain_get_finalized_head().await.map_err(|_| ())?; match self.legacy.chain_get_header(Some(finalized_header)).await.map_err(|_| ())? { @@ -112,6 +118,10 @@ impl SubstrateRpcClient for SubxtClient { async fn get_genesis_hash(&mut self) -> Result, ()> { self.legacy.genesis_hash().await.map(|h| h.encode()).map_err(|_| ()) } + + async fn get_account_nonce(&mut self, account_id: &ChainConfig::AccountId) -> Result { + self.tx.account_nonce(account_id).await.map_err(|_| ()) + } } pub struct MockedRpcClient { @@ -119,7 +129,7 @@ pub struct MockedRpcClient { } #[async_trait] -impl SubstrateRpcClient for MockedRpcClient { +impl SubstrateRpcClient for MockedRpcClient { async fn get_last_finalized_block_num(&mut self) -> Result { Ok(self.block_num) } @@ -143,10 +153,14 @@ impl SubstrateRpcClient for MockedRpcClient { async fn get_genesis_hash(&mut self) -> Result, ()> { Ok(vec![]) } + + async fn get_account_nonce(&mut self, _account_id: &String) -> Result { + Ok(0) + } } #[async_trait] -pub trait SubstrateRpcClientFactory { +pub trait SubstrateRpcClientFactory> { async fn new_client(&self) -> Result; } @@ -155,7 +169,7 @@ pub struct SubxtClientFactory { _phantom: PhantomData, } -impl SubxtClientFactory { +impl> SubxtClientFactory { pub fn new(url: &str) -> Self { Self { url: url.to_string(), _phantom: PhantomData } } @@ -180,7 +194,8 @@ impl SubxtClientFactory { } #[async_trait] -impl SubstrateRpcClientFactory> +impl> + SubstrateRpcClientFactory> for SubxtClientFactory { async fn new_client(&self) -> Result, ()> { @@ -195,8 +210,10 @@ impl SubstrateRpcClientFactory> OnlineClient::from_insecure_url(self.url.clone()).await.map_err(|e| { log::error!("Could not create OnlineClient: {:?}", e); })?; + let events = online_client.events(); + let tx = online_client.tx(); - Ok(SubxtClient { legacy, events }) + Ok(SubxtClient { legacy, events, tx }) } } diff --git a/tee-worker/omni-executor/parentchain/listener/src/transaction_signer.rs b/tee-worker/omni-executor/parentchain/listener/src/transaction_signer.rs index d29bd53cd8..c5e7240346 100644 --- a/tee-worker/omni-executor/parentchain/listener/src/transaction_signer.rs +++ b/tee-worker/omni-executor/parentchain/listener/src/transaction_signer.rs @@ -1,11 +1,10 @@ use crate::metadata::{MetadataProvider, SubxtMetadataProvider}; use crate::rpc_client::{SubstrateRpcClient, SubstrateRpcClientFactory}; -use executor_core::event_handler::Error::RecoverableError; use executor_core::key_store::KeyStore; use log::error; use parity_scale_codec::Decode; use std::marker::PhantomData; -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use subxt_core::config::{DefaultExtrinsicParams, DefaultExtrinsicParamsBuilder}; use subxt_core::tx::payload::Payload; use subxt_core::utils::{AccountId32, MultiAddress, MultiSignature}; @@ -14,23 +13,22 @@ use subxt_signer::sr25519::SecretKeyBytes; pub struct TransactionSigner< KeyStoreT, - RpcClient: SubstrateRpcClient, - RpcClientFactory: SubstrateRpcClientFactory, - ChainConfig, + RpcClient: SubstrateRpcClient, + RpcClientFactory: SubstrateRpcClientFactory, + ChainConfig: Config, MetadataT, MetadataProviderT: MetadataProvider, > { metadata_provider: Arc, rpc_client_factory: Arc, key_store: Arc, - nonce: RwLock, phantom_data: PhantomData<(RpcClient, ChainConfig, MetadataT)>, } impl< KeyStoreT: KeyStore, - RpcClient: SubstrateRpcClient, - RpcClientFactory: SubstrateRpcClientFactory, + RpcClient: SubstrateRpcClient, + RpcClientFactory: SubstrateRpcClientFactory, ChainConfig: Config< ExtrinsicParams = DefaultExtrinsicParams, AccountId = AccountId32, @@ -52,14 +50,7 @@ impl< rpc_client_factory: Arc, key_store: Arc, ) -> Self { - Self { - metadata_provider, - rpc_client_factory, - key_store, - //todo: read nonce from chain - nonce: RwLock::new(0), - phantom_data: PhantomData, - } + Self { metadata_provider, rpc_client_factory, key_store, phantom_data: PhantomData } } pub async fn sign(&self, call: Call) -> Vec { @@ -81,23 +72,13 @@ impl< let genesis_hash = client.get_genesis_hash().await.unwrap(); - let nonce = *self - .nonce - .read() - .map_err(|e| { - error!("Could not read nonce: {:?}", e); - RecoverableError - }) - .unwrap(); + let account_id = AccountId32::from(signer.public_key()); - *self - .nonce - .write() - .map_err(|e| { - error!("Could not write nonce: {:?}", e); - RecoverableError - }) - .unwrap() = nonce + 1; + let nonce = client + .get_account_nonce(&account_id) + .await + .map_err(|e| error!("Could not read nonce: {:?}", e)) + .unwrap(); // we should get latest metadata let metadata = self.metadata_provider.get(None).await;