feat: add eth_getTransactionByHash (#8)
* add eth_getTransactionByHash * clean up imports
This commit is contained in:
parent
11fd824b01
commit
e0411e1e97
|
@ -2,7 +2,7 @@ use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ethers::prelude::{Address, U256};
|
use ethers::prelude::{Address, U256};
|
||||||
use ethers::types::TransactionReceipt;
|
use ethers::types::{Transaction, TransactionReceipt};
|
||||||
use eyre::Result;
|
use eyre::Result;
|
||||||
|
|
||||||
use config::Config;
|
use config::Config;
|
||||||
|
@ -124,6 +124,12 @@ impl Client {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_transaction_by_hash(&self, tx_hash: &Vec<u8>) -> Result<Option<Transaction>> {
|
||||||
|
self.execution
|
||||||
|
.get_transaction(tx_hash, &self.payloads)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_gas_price(&self) -> Result<U256> {
|
pub fn get_gas_price(&self) -> Result<U256> {
|
||||||
let payload = self.get_payload(&None)?;
|
let payload = self.get_payload(&None)?;
|
||||||
let base_fee = U256::from_little_endian(&payload.base_fee_per_gas.to_bytes_le());
|
let base_fee = U256::from_little_endian(&payload.base_fee_per_gas.to_bytes_le());
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use ethers::{
|
use ethers::{
|
||||||
abi::AbiEncode,
|
abi::AbiEncode,
|
||||||
types::{Address, TransactionReceipt},
|
types::{Address, Transaction, TransactionReceipt},
|
||||||
};
|
};
|
||||||
use eyre::Result;
|
use eyre::Result;
|
||||||
use std::{fmt::Display, net::SocketAddr, str::FromStr, sync::Arc};
|
use std::{fmt::Display, net::SocketAddr, str::FromStr, sync::Arc};
|
||||||
|
@ -68,6 +68,8 @@ trait EthRpc {
|
||||||
async fn send_raw_transaction(&self, bytes: &str) -> Result<String, Error>;
|
async fn send_raw_transaction(&self, bytes: &str) -> Result<String, Error>;
|
||||||
#[method(name = "getTransactionReceipt")]
|
#[method(name = "getTransactionReceipt")]
|
||||||
async fn get_transaction_receipt(&self, hash: &str) -> Result<TransactionReceipt, Error>;
|
async fn get_transaction_receipt(&self, hash: &str) -> Result<TransactionReceipt, Error>;
|
||||||
|
#[method(name = "getTransactionByHash")]
|
||||||
|
async fn get_transaction_by_hash(&self, hash: &str) -> Result<Transaction, Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rpc(client, server, namespace = "net")]
|
#[rpc(client, server, namespace = "net")]
|
||||||
|
@ -179,6 +181,17 @@ impl EthRpcServer for RpcInner {
|
||||||
None => Err(Error::Custom("Receipt Not Found".to_string())),
|
None => Err(Error::Custom("Receipt Not Found".to_string())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_transaction_by_hash(&self, hash: &str) -> Result<Transaction, Error> {
|
||||||
|
let client = self.client.lock().await;
|
||||||
|
let hash = convert_err(hex_str_to_bytes(hash))?;
|
||||||
|
let tx = convert_err(client.get_transaction_by_hash(&hash).await)?;
|
||||||
|
|
||||||
|
match tx {
|
||||||
|
Some(tx) => Ok(tx),
|
||||||
|
None => Err(Error::Custom("Transaction Not Found".to_string())),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::str::FromStr;
|
||||||
|
|
||||||
use ethers::abi::AbiEncode;
|
use ethers::abi::AbiEncode;
|
||||||
use ethers::prelude::{Address, U256};
|
use ethers::prelude::{Address, U256};
|
||||||
use ethers::types::{TransactionReceipt, H256};
|
use ethers::types::{Transaction, TransactionReceipt, H256};
|
||||||
use ethers::utils::keccak256;
|
use ethers::utils::keccak256;
|
||||||
use ethers::utils::rlp::{encode, RlpStream};
|
use ethers::utils::rlp::{encode, RlpStream};
|
||||||
use eyre::Result;
|
use eyre::Result;
|
||||||
|
@ -142,7 +142,6 @@ impl ExecutionClient {
|
||||||
tx_hash: &Vec<u8>,
|
tx_hash: &Vec<u8>,
|
||||||
payloads: &HashMap<u64, ExecutionPayload>,
|
payloads: &HashMap<u64, ExecutionPayload>,
|
||||||
) -> Result<Option<TransactionReceipt>> {
|
) -> Result<Option<TransactionReceipt>> {
|
||||||
|
|
||||||
let receipt = self.rpc.get_transaction_receipt(tx_hash).await?;
|
let receipt = self.rpc.get_transaction_receipt(tx_hash).await?;
|
||||||
if receipt.is_none() {
|
if receipt.is_none() {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
|
@ -188,6 +187,46 @@ impl ExecutionClient {
|
||||||
|
|
||||||
Ok(Some(receipt))
|
Ok(Some(receipt))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_transaction(
|
||||||
|
&self,
|
||||||
|
hash: &Vec<u8>,
|
||||||
|
payloads: &HashMap<u64, ExecutionPayload>,
|
||||||
|
) -> Result<Option<Transaction>> {
|
||||||
|
let tx = self.rpc.get_transaction(hash).await?;
|
||||||
|
if tx.is_none() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
let tx = tx.unwrap();
|
||||||
|
|
||||||
|
let block_number = tx.block_number;
|
||||||
|
if block_number.is_none() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
let block_number = block_number.unwrap();
|
||||||
|
|
||||||
|
let payload = payloads.get(&block_number.as_u64());
|
||||||
|
if payload.is_none() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
let payload = payload.unwrap();
|
||||||
|
|
||||||
|
let tx_encoded = tx.rlp().to_vec();
|
||||||
|
let txs_encoded = payload
|
||||||
|
.transactions
|
||||||
|
.iter()
|
||||||
|
.map(|tx| tx.to_vec())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if !txs_encoded.contains(&tx_encoded) {
|
||||||
|
return Err(eyre::eyre!("Transaction Proof Invalid"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Some(tx))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_receipt(receipt: &TransactionReceipt) -> Vec<u8> {
|
fn encode_receipt(receipt: &TransactionReceipt) -> Vec<u8> {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use ethers::abi::AbiEncode;
|
use ethers::abi::AbiEncode;
|
||||||
use ethers::prelude::{Address, U256};
|
use ethers::prelude::{Address, U256};
|
||||||
use ethers::providers::{Middleware, Provider};
|
use ethers::providers::{Middleware, Provider};
|
||||||
use ethers::types::{TransactionReceipt, H256};
|
use ethers::types::{Transaction, TransactionReceipt, H256};
|
||||||
use eyre::Result;
|
use eyre::Result;
|
||||||
use jsonrpsee::{
|
use jsonrpsee::{
|
||||||
core::client::ClientT,
|
core::client::ClientT,
|
||||||
|
@ -64,6 +64,11 @@ impl Rpc {
|
||||||
.await?)
|
.await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_transaction(&self, tx_hash: &Vec<u8>) -> Result<Option<Transaction>> {
|
||||||
|
let provider = Provider::try_from(&self.rpc)?;
|
||||||
|
Ok(provider.get_transaction(H256::from_slice(tx_hash)).await?)
|
||||||
|
}
|
||||||
|
|
||||||
fn client(&self) -> Result<HttpClient> {
|
fn client(&self) -> Result<HttpClient> {
|
||||||
Ok(HttpClientBuilder::default().build(&self.rpc)?)
|
Ok(HttpClientBuilder::default().build(&self.rpc)?)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue