Skip to content

Commit

Permalink
remove hardcoded nonce (#3160)
Browse files Browse the repository at this point in the history
  • Loading branch information
kziemianek authored Nov 6, 2024
1 parent 183deab commit 8792613
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 72 deletions.
36 changes: 16 additions & 20 deletions tee-worker/omni-executor/parentchain/listener/src/event_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ pub struct IntentEventHandler<
MetadataProviderT: MetadataProvider<MetadataT>,
EthereumIntentExecutorT: IntentExecutor,
KeyStoreT: KeyStore<SecretKeyBytes>,
RpcClient: SubstrateRpcClient,
RpcClientFactory: SubstrateRpcClientFactory<RpcClient>,
RpcClient: SubstrateRpcClient<ChainConfig::AccountId>,
RpcClientFactory: SubstrateRpcClientFactory<ChainConfig::AccountId, RpcClient>,
> {
metadata_provider: Arc<MetadataProviderT>,
ethereum_intent_executor: EthereumIntentExecutorT,
Expand All @@ -65,8 +65,8 @@ impl<
MetadataProviderT: MetadataProvider<MetadataT>,
EthereumIntentExecutorT: IntentExecutor,
KeyStoreT: KeyStore<SecretKeyBytes>,
RpcClient: SubstrateRpcClient,
RpcClientFactory: SubstrateRpcClientFactory<RpcClient>,
RpcClient: SubstrateRpcClient<ChainConfig::AccountId>,
RpcClientFactory: SubstrateRpcClientFactory<ChainConfig::AccountId, RpcClient>,
>
IntentEventHandler<
ChainConfig,
Expand Down Expand Up @@ -113,8 +113,8 @@ impl<
>,
EthereumIntentExecutorT: IntentExecutor + Send + Sync,
KeyStoreT: KeyStore<SecretKeyBytes> + Send + Sync,
RpcClient: SubstrateRpcClient + Send + Sync,
RpcClientFactory: SubstrateRpcClientFactory<RpcClient> + Send + Sync,
RpcClient: SubstrateRpcClient<ChainConfig::AccountId> + Send + Sync,
RpcClientFactory: SubstrateRpcClientFactory<ChainConfig::AccountId, RpcClient> + Send + Sync,
> EventHandler<BlockEvent>
for IntentEventHandler<
ChainConfig,
Expand Down Expand Up @@ -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;
}
},
}

Expand All @@ -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,
Expand Down
30 changes: 19 additions & 11 deletions tee-worker/omni-executor/parentchain/listener/src/fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<RpcClient>,
AccountId,
RpcClient: SubstrateRpcClient<AccountId>,
RpcClientFactory: SubstrateRpcClientFactory<AccountId, RpcClient>,
> {
client_factory: Arc<RpcClientFactory>,
client: Option<RpcClient>,
phantom_data: PhantomData<AccountId>,
}

impl<RpcClient: SubstrateRpcClient, RpcClientFactory: SubstrateRpcClientFactory<RpcClient>>
Fetcher<RpcClient, RpcClientFactory>
impl<
AccountId,
RpcClient: SubstrateRpcClient<AccountId>,
RpcClientFactory: SubstrateRpcClientFactory<AccountId, RpcClient>,
> Fetcher<AccountId, RpcClient, RpcClientFactory>
{
pub fn new(client_factory: Arc<RpcClientFactory>) -> Self {
Self { client: None, client_factory }
Self { client: None, client_factory, phantom_data: PhantomData }
}

async fn connect_if_needed(&mut self) {
Expand All @@ -50,9 +56,10 @@ impl<RpcClient: SubstrateRpcClient, RpcClientFactory: SubstrateRpcClientFactory<

#[async_trait]
impl<
RpcClient: SubstrateRpcClient + Sync + Send,
RpcClientFactory: SubstrateRpcClientFactory<RpcClient> + Sync + Send,
> LastFinalizedBlockNumFetcher for Fetcher<RpcClient, RpcClientFactory>
AccountId: Sync + Send,
RpcClient: SubstrateRpcClient<AccountId> + Sync + Send,
RpcClientFactory: SubstrateRpcClientFactory<AccountId, RpcClient> + Sync + Send,
> LastFinalizedBlockNumFetcher for Fetcher<AccountId, RpcClient, RpcClientFactory>
{
async fn get_last_finalized_block_num(&mut self) -> Result<Option<u64>, ()> {
self.connect_if_needed().await;
Expand All @@ -68,9 +75,10 @@ impl<

#[async_trait]
impl<
RpcClient: SubstrateRpcClient + Sync + Send,
RpcClientFactory: SubstrateRpcClientFactory<RpcClient> + Sync + Send,
> EventsFetcher<EventId, BlockEvent> for Fetcher<RpcClient, RpcClientFactory>
AccountId: Sync + Send,
RpcClient: SubstrateRpcClient<AccountId> + Sync + Send,
RpcClientFactory: SubstrateRpcClientFactory<AccountId, RpcClient> + Sync + Send,
> EventsFetcher<EventId, BlockEvent> for Fetcher<AccountId, RpcClient, RpcClientFactory>
{
async fn get_block_events(&mut self, block_num: u64) -> Result<Vec<BlockEvent>, ()> {
self.connect_if_needed().await;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -32,7 +33,7 @@ pub type ParentchainListener<
ChainConfig,
EthereumIntentExecutor,
> = Listener<
Fetcher<RpcClient, RpcClientFactory>,
Fetcher<<ChainConfig as Config>::AccountId, RpcClient, RpcClientFactory>,
SyncCheckpoint,
CheckpointRepository,
IntentEventId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<M> {
Expand All @@ -35,7 +36,9 @@ impl<ChainConfig: Config> SubxtMetadataProvider<ChainConfig> {
}

#[async_trait]
impl<ChainConfig: Config> MetadataProvider<Metadata> for SubxtMetadataProvider<ChainConfig> {
impl<ChainConfig: Config<AccountId = AccountId32>> MetadataProvider<Metadata>
for SubxtMetadataProvider<ChainConfig>
{
async fn get(&self, block_num: Option<u64>) -> Metadata {
let mut client = self.client_factory.new_client().await.unwrap();
let raw_metadata = client.get_raw_metadata(block_num).await.unwrap();
Expand Down
31 changes: 24 additions & 7 deletions tee-worker/omni-executor/parentchain/listener/src/rpc_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -35,24 +37,28 @@ pub struct RuntimeVersion {

/// For fetching data from Substrate RPC node
#[async_trait]
pub trait SubstrateRpcClient {
pub trait SubstrateRpcClient<AccountId> {
async fn get_last_finalized_block_num(&mut self) -> Result<u64, ()>;
async fn get_block_events(&mut self, block_num: u64) -> Result<Vec<BlockEvent>, ()>;
async fn get_raw_metadata(&mut self, block_num: Option<u64>) -> Result<Vec<u8>, ()>;
async fn submit_tx(&mut self, raw_tx: &[u8]) -> Result<(), ()>;
async fn runtime_version(&mut self) -> Result<RuntimeVersion, ()>;
async fn get_genesis_hash(&mut self) -> Result<Vec<u8>, ()>;
async fn get_account_nonce(&mut self, account_id: &AccountId) -> Result<u64, ()>;
}

pub struct SubxtClient<ChainConfig: Config> {
legacy: LegacyRpcMethods<ChainConfig>,
events: EventsClient<ChainConfig, OnlineClient<ChainConfig>>,
tx: TxClient<ChainConfig, OnlineClient<ChainConfig>>,
}

impl<ChainConfig: Config> SubxtClient<ChainConfig> {}

#[async_trait]
impl<ChainConfig: Config> SubstrateRpcClient for SubxtClient<ChainConfig> {
impl<ChainConfig: Config<AccountId = AccountId32>> SubstrateRpcClient<ChainConfig::AccountId>
for SubxtClient<ChainConfig>
{
async fn get_last_finalized_block_num(&mut self) -> Result<u64, ()> {
let finalized_header = self.legacy.chain_get_finalized_head().await.map_err(|_| ())?;
match self.legacy.chain_get_header(Some(finalized_header)).await.map_err(|_| ())? {
Expand Down Expand Up @@ -112,14 +118,18 @@ impl<ChainConfig: Config> SubstrateRpcClient for SubxtClient<ChainConfig> {
async fn get_genesis_hash(&mut self) -> Result<Vec<u8>, ()> {
self.legacy.genesis_hash().await.map(|h| h.encode()).map_err(|_| ())
}

async fn get_account_nonce(&mut self, account_id: &ChainConfig::AccountId) -> Result<u64, ()> {
self.tx.account_nonce(account_id).await.map_err(|_| ())
}
}

pub struct MockedRpcClient {
block_num: u64,
}

#[async_trait]
impl SubstrateRpcClient for MockedRpcClient {
impl SubstrateRpcClient<String> for MockedRpcClient {
async fn get_last_finalized_block_num(&mut self) -> Result<u64, ()> {
Ok(self.block_num)
}
Expand All @@ -143,10 +153,14 @@ impl SubstrateRpcClient for MockedRpcClient {
async fn get_genesis_hash(&mut self) -> Result<Vec<u8>, ()> {
Ok(vec![])
}

async fn get_account_nonce(&mut self, _account_id: &String) -> Result<u64, ()> {
Ok(0)
}
}

#[async_trait]
pub trait SubstrateRpcClientFactory<RpcClient: SubstrateRpcClient> {
pub trait SubstrateRpcClientFactory<AccountId, RpcClient: SubstrateRpcClient<AccountId>> {
async fn new_client(&self) -> Result<RpcClient, ()>;
}

Expand All @@ -155,7 +169,7 @@ pub struct SubxtClientFactory<ChainConfig: Config> {
_phantom: PhantomData<ChainConfig>,
}

impl<ChainConfig: Config> SubxtClientFactory<ChainConfig> {
impl<ChainConfig: Config<AccountId = AccountId32>> SubxtClientFactory<ChainConfig> {
pub fn new(url: &str) -> Self {
Self { url: url.to_string(), _phantom: PhantomData }
}
Expand All @@ -180,7 +194,8 @@ impl<ChainConfig: Config> SubxtClientFactory<ChainConfig> {
}

#[async_trait]
impl<ChainConfig: Config> SubstrateRpcClientFactory<SubxtClient<ChainConfig>>
impl<ChainConfig: Config<AccountId = AccountId32>>
SubstrateRpcClientFactory<ChainConfig::AccountId, SubxtClient<ChainConfig>>
for SubxtClientFactory<ChainConfig>
{
async fn new_client(&self) -> Result<SubxtClient<ChainConfig>, ()> {
Expand All @@ -195,8 +210,10 @@ impl<ChainConfig: Config> SubstrateRpcClientFactory<SubxtClient<ChainConfig>>
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 })
}
}
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -14,23 +13,22 @@ use subxt_signer::sr25519::SecretKeyBytes;

pub struct TransactionSigner<
KeyStoreT,
RpcClient: SubstrateRpcClient,
RpcClientFactory: SubstrateRpcClientFactory<RpcClient>,
ChainConfig,
RpcClient: SubstrateRpcClient<ChainConfig::AccountId>,
RpcClientFactory: SubstrateRpcClientFactory<ChainConfig::AccountId, RpcClient>,
ChainConfig: Config,
MetadataT,
MetadataProviderT: MetadataProvider<MetadataT>,
> {
metadata_provider: Arc<MetadataProviderT>,
rpc_client_factory: Arc<RpcClientFactory>,
key_store: Arc<KeyStoreT>,
nonce: RwLock<u64>,
phantom_data: PhantomData<(RpcClient, ChainConfig, MetadataT)>,
}

impl<
KeyStoreT: KeyStore<SecretKeyBytes>,
RpcClient: SubstrateRpcClient,
RpcClientFactory: SubstrateRpcClientFactory<RpcClient>,
RpcClient: SubstrateRpcClient<ChainConfig::AccountId>,
RpcClientFactory: SubstrateRpcClientFactory<ChainConfig::AccountId, RpcClient>,
ChainConfig: Config<
ExtrinsicParams = DefaultExtrinsicParams<ChainConfig>,
AccountId = AccountId32,
Expand All @@ -52,14 +50,7 @@ impl<
rpc_client_factory: Arc<RpcClientFactory>,
key_store: Arc<KeyStoreT>,
) -> 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<Call: Payload>(&self, call: Call) -> Vec<u8> {
Expand All @@ -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;
Expand Down

0 comments on commit 8792613

Please sign in to comment.