From 77180bb0cb8fce6c6ab17f2117e4019cb4400a27 Mon Sep 17 00:00:00 2001 From: Kasper Ziemianek Date: Thu, 31 Oct 2024 14:49:47 +0100 Subject: [PATCH] 3rd party ethereum node integration adjustments (#3153) * adjust ethereum rpc node integration --- tee-worker/omni-executor/Cargo.lock | 1 + tee-worker/omni-executor/Dockerfile | 6 + .../ethereum/intent-executor/Cargo.toml | 3 + .../ethereum/intent-executor/src/lib.rs | 86 ++++++++++++-- .../artifacts/rococo-omni-account.scale | Bin 31087 -> 31439 bytes .../parentchain/listener/src/event_handler.rs | 108 +++++++++--------- 6 files changed, 144 insertions(+), 60 deletions(-) diff --git a/tee-worker/omni-executor/Cargo.lock b/tee-worker/omni-executor/Cargo.lock index d2368f28f5..63b09a07f6 100644 --- a/tee-worker/omni-executor/Cargo.lock +++ b/tee-worker/omni-executor/Cargo.lock @@ -2396,6 +2396,7 @@ dependencies = [ "async-trait", "executor-core", "log", + "tokio", ] [[package]] diff --git a/tee-worker/omni-executor/Dockerfile b/tee-worker/omni-executor/Dockerfile index 63dc7198ce..4f98c37bdc 100644 --- a/tee-worker/omni-executor/Dockerfile +++ b/tee-worker/omni-executor/Dockerfile @@ -5,4 +5,10 @@ RUN cargo build --release FROM ubuntu:22.04 COPY --from=builder /usr/src/omni-executor/target/release/executor-worker /usr/local/bin/executor-worker + +RUN \ + apt-get update && \ + apt-get install -y ca-certificates && \ + apt-get clean + CMD ["executor-worker"] \ No newline at end of file diff --git a/tee-worker/omni-executor/ethereum/intent-executor/Cargo.toml b/tee-worker/omni-executor/ethereum/intent-executor/Cargo.toml index 3bb21d68ea..2eae9fd2a2 100644 --- a/tee-worker/omni-executor/ethereum/intent-executor/Cargo.toml +++ b/tee-worker/omni-executor/ethereum/intent-executor/Cargo.toml @@ -10,5 +10,8 @@ async-trait = { workspace = true } executor-core = { path = "../../executor-core" } log = { workspace = true } +[dev-dependencies] +tokio = { workspace = true } + [lints] workspace = true diff --git a/tee-worker/omni-executor/ethereum/intent-executor/src/lib.rs b/tee-worker/omni-executor/ethereum/intent-executor/src/lib.rs index e8b9efc162..5aef97909f 100644 --- a/tee-worker/omni-executor/ethereum/intent-executor/src/lib.rs +++ b/tee-worker/omni-executor/ethereum/intent-executor/src/lib.rs @@ -16,7 +16,7 @@ use std::str::FromStr; -use alloy::network::EthereumWallet; +use alloy::network::{EthereumWallet, TransactionBuilder}; use alloy::primitives::{Address, U256}; use alloy::providers::{Provider, ProviderBuilder, WalletProvider}; use alloy::rpc::types::{TransactionInput, TransactionRequest}; @@ -43,7 +43,7 @@ impl IntentExecutor for EthereumIntentExecutor { info!("Executin intent: {:?}", intent); // todo: this should be retrieved from key_store let signer = PrivateKeySigner::from_str( - "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d", + "0x59c6995e998f97a5a0044964f0945389dc9e86dae86c7a8412f4603b6b78690d", ) .unwrap(); let wallet = EthereumWallet::from(signer); @@ -51,14 +51,20 @@ impl IntentExecutor for EthereumIntentExecutor { .with_recommended_fillers() .wallet(wallet) .on_http(self.rpc_url.parse().map_err(|e| error!("Could not parse rpc url: {:?}", e))?); - let account = - provider.get_account(provider.signer_addresses().next().unwrap()).await.unwrap(); + let nonce = provider + .get_transaction_count(provider.signer_addresses().next().unwrap()) + .await + .unwrap(); + let gas_price = provider.get_gas_price().await.unwrap(); + match intent { Intent::TransferEthereum(to, value) => { - let tx = TransactionRequest::default() + let mut tx = TransactionRequest::default() .to(Address::from(to)) - .nonce(account.nonce) + .nonce(nonce) .value(U256::from_be_bytes(value)); + + tx.set_gas_price(gas_price); let pending_tx = provider.send_transaction(tx).await.map_err(|e| { error!("Could not send transaction: {:?}", e); })?; @@ -68,10 +74,12 @@ impl IntentExecutor for EthereumIntentExecutor { })?; }, Intent::CallEthereum(address, input) => { - let tx = TransactionRequest::default() + let mut tx = TransactionRequest::default() .to(Address::from(address)) - .nonce(account.nonce) + .nonce(nonce) .input(TransactionInput::from(input)); + + tx.set_gas_price(gas_price); let pending_tx = provider.send_transaction(tx).await.map_err(|e| { error!("Could not send transaction: {:?}", e); })?; @@ -84,3 +92,65 @@ impl IntentExecutor for EthereumIntentExecutor { Ok(()) } } + +#[cfg(test)] +pub mod test { + use alloy::hex; + use alloy::hex::FromHex; + use alloy::network::{EthereumWallet, NetworkWallet, TransactionBuilder}; + use alloy::primitives::Address; + use alloy::providers::{Provider, ProviderBuilder, WalletProvider}; + use alloy::rpc::types::{TransactionInput, TransactionRequest}; + use alloy::signers::local::PrivateKeySigner; + use log::error; + use std::str::FromStr; + + // #[tokio::test] + pub async fn test() { + // place url here: + let url = ""; + + let signer = PrivateKeySigner::from_str( + "0x59c6995e998f97a5a0044964f0945389dc9e86dae86c7a8412f4603b6b78690d", + ) + .unwrap(); + let wallet = EthereumWallet::from(signer); + + let provider = ProviderBuilder::new() + .with_recommended_fillers() + .wallet(wallet) + .on_http(url.parse().map_err(|e| error!("Could not parse rpc url: {:?}", e)).unwrap()); + let nonce = provider + .get_transaction_count(provider.signer_addresses().next().unwrap()) + .await + .unwrap(); + let gas_price = provider.get_gas_price().await.unwrap(); + + let mut tx = TransactionRequest::default() + .to(Address::from_hex("0x1f754692f0b0578d6af97faed6319542c9ffd468").unwrap()) + .nonce(nonce) + .input(TransactionInput::from(hex::decode("0x2166e8280000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001e4c6974656e747279204f6d6e694163636f756e7420657865637574696f6e0000").unwrap())); + + tx.set_gas_price(gas_price); + + let pending_tx = provider + .send_transaction(tx) + .await + .map_err(|e| { + std::println!("Could not send transaction: {:?}", e); + }) + .map_err(|e| { + std::println!("Could not get transaction receipt: {:?}", e); + () + }) + .unwrap(); + + pending_tx + .get_receipt() + .await + .map_err(|e| { + error!("Could not get transaction receipt: {:?}", e); + }) + .unwrap(); + } +} diff --git a/tee-worker/omni-executor/parentchain/artifacts/rococo-omni-account.scale b/tee-worker/omni-executor/parentchain/artifacts/rococo-omni-account.scale index 5f18bed23feac0aeafcfc87eefaaa395047d16f2..66fa4feed966e1e77e60f9eef2cce90e56badc85 100644 GIT binary patch delta 5969 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 Z7LS2zSo8KqMN2paNpz@B=O!E2{{Z95W@rEa 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 230dee4a61..e9968023ab 100644 --- a/tee-worker/omni-executor/parentchain/listener/src/event_handler.rs +++ b/tee-worker/omni-executor/parentchain/listener/src/event_handler.rs @@ -172,68 +172,72 @@ impl< Error::NonRecoverableError })?; - let intent = match decoded.intent { + let maybe_intent = match decoded.intent { crate::litentry_rococo::runtime_types::core_primitives::intent::Intent::CallEthereum(call_ethereum) => { - Intent::CallEthereum(call_ethereum.address.to_fixed_bytes(), call_ethereum.input.0) + Some(Intent::CallEthereum(call_ethereum.address.to_fixed_bytes(), call_ethereum.input.0)) }, crate::litentry_rococo::runtime_types::core_primitives::intent::Intent::TransferEthereum(transfer) => { - Intent::TransferEthereum(transfer.to.to_fixed_bytes(), transfer.value) - } - }; - - //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 - })?; - }, - 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 - })?; + Some(Intent::TransferEthereum(transfer.to.to_fixed_bytes(), transfer.value)) }, - } + crate::litentry_rococo::runtime_types::core_primitives::intent::Intent::SystemRemark(_) => None, + crate::litentry_rococo::runtime_types::core_primitives::intent::Intent::TransferNative(_) => None, + }; - log::debug!("Intent executed, publishing result"); + 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 + })?; + }, + 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 + })?; + }, + } - // todo: the whole signing part should be encapsulated in separate component like `TransactionSigner` - //we need to report back to parachain intent result - let decoded = - crate::litentry_rococo::omni_account::events::IntentRequested::decode_as_fields( - &mut event.field_bytes.as_slice(), - &mut fields, - metadata.types(), - ) - .map_err(|_| { - log::error!("Could not decode event {:?}", event.id); - Error::NonRecoverableError - })?; + log::debug!("Intent executed, publishing result"); + + // todo: the whole signing part should be encapsulated in separate component like `TransactionSigner` + //we need to report back to parachain intent result + let decoded = + crate::litentry_rococo::omni_account::events::IntentRequested::decode_as_fields( + &mut event.field_bytes.as_slice(), + &mut fields, + metadata.types(), + ) + .map_err(|_| { + log::error!("Could not decode event {:?}", event.id); + Error::NonRecoverableError + })?; - let execution_result = - crate::litentry_rococo::omni_account::calls::types::intent_executed::Result::Success; + 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, - execution_result, - ); + let call = crate::litentry_rococo::tx().omni_account().intent_executed( + decoded.who, + decoded.intent, + execution_result, + ); - let mut client = self.rpc_client_factory.new_client().await.map_err(|e| { - error!("Could not create RPC client: {:?}", e); - RecoverableError - })?; + let mut client = self.rpc_client_factory.new_client().await.map_err(|e| { + error!("Could not create RPC client: {:?}", e); + RecoverableError + })?; - let signed_call = self.transaction_signer.sign(call).await; - client.submit_tx(&signed_call).await.map_err(|e| { - error!("Error while submitting tx: {:?}", e); - RecoverableError - })?; - log::debug!("Result published"); + let signed_call = self.transaction_signer.sign(call).await; + client.submit_tx(&signed_call).await.map_err(|e| { + error!("Error while submitting tx: {:?}", e); + RecoverableError + })?; + log::debug!("Result published"); + } Ok(()) } }