feat(rpc): eth_transactionBy impls (#1664)

Co-authored-by: Sam Bukowski <sambukowski@Sams-MacBook-Pro.local>
This commit is contained in:
sambukowski
2023-03-11 02:54:11 -07:00
committed by GitHub
parent a0f195590c
commit 853da85c44
5 changed files with 71 additions and 29 deletions

View File

@ -9,7 +9,8 @@ use jsonrpsee::{
types::error::{CallError, ErrorCode},
};
use reth_primitives::{
hex_literal::hex, Address, BlockId, BlockNumberOrTag, Bytes, NodeRecord, H256, H64, U256,
hex_literal::hex, Address, BlockId, BlockNumberOrTag, Bytes, NodeRecord, TxHash, H256, H64,
U256,
};
use reth_rpc_api::{
clients::{AdminApiClient, EthApiClient},
@ -50,6 +51,7 @@ where
let address = Address::default();
let index = Index::default();
let hash = H256::default();
let tx_hash = TxHash::default();
let block_number = BlockNumberOrTag::default();
let call_request = CallRequest::default();
let transaction_request = TransactionRequest::default();
@ -75,21 +77,13 @@ where
EthApiClient::block_uncles_count_by_number(client, block_number).await.unwrap();
EthApiClient::uncle_by_block_hash_and_index(client, hash, index).await.unwrap();
EthApiClient::uncle_by_block_number_and_index(client, block_number, index).await.unwrap();
EthApiClient::create_access_list(client, call_request.clone(), None).await.unwrap();
EthApiClient::transaction_by_hash(client, tx_hash).await.unwrap();
EthApiClient::transaction_by_block_hash_and_index(client, hash, index).await.unwrap();
EthApiClient::transaction_by_block_number_and_index(client, block_number, index).await.unwrap();
// Unimplemented
assert!(is_unimplemented(EthApiClient::syncing(client).await.err().unwrap()));
assert!(is_unimplemented(EthApiClient::author(client).await.err().unwrap()));
assert!(is_unimplemented(EthApiClient::transaction_by_hash(client, hash).await.err().unwrap()));
assert!(is_unimplemented(
EthApiClient::transaction_by_block_hash_and_index(client, hash, index).await.err().unwrap()
));
assert!(is_unimplemented(
EthApiClient::transaction_by_block_number_and_index(client, block_number, index)
.await
.err()
.unwrap()
));
assert!(is_unimplemented(EthApiClient::transaction_receipt(client, hash).await.err().unwrap()));
assert!(is_unimplemented(
EthApiClient::call(client, call_request.clone(), None, None).await.err().unwrap()

View File

@ -74,7 +74,7 @@ impl Transaction {
///
/// The block hash, number, and tx index fields should be from the original block where the
/// transaction was mined.
pub(crate) fn from_recovered_with_block_context(
pub fn from_recovered_with_block_context(
tx: TransactionSignedEcRecovered,
block_hash: H256,
block_number: BlockNumber,
@ -142,7 +142,7 @@ impl Transaction {
max_fee_per_gas,
max_priority_fee_per_gas: signed_tx.max_priority_fee_per_gas().map(U128::from),
signature: Some(Signature::from_primitive_signature(
signed_tx.signature().clone(),
*signed_tx.signature(),
signed_tx.chain_id(),
)),
gas: U256::from(signed_tx.gas_limit()),

View File

@ -117,29 +117,26 @@ where
}
/// Handler for: `eth_getTransactionByHash`
async fn transaction_by_hash(
&self,
_hash: H256,
) -> Result<Option<reth_rpc_types::Transaction>> {
Err(internal_rpc_err("unimplemented"))
async fn transaction_by_hash(&self, hash: H256) -> Result<Option<reth_rpc_types::Transaction>> {
Ok(EthApi::transaction_by_hash(self, hash).await?)
}
/// Handler for: `eth_getTransactionByBlockHashAndIndex`
async fn transaction_by_block_hash_and_index(
&self,
_hash: H256,
_index: Index,
hash: H256,
index: Index,
) -> Result<Option<reth_rpc_types::Transaction>> {
Err(internal_rpc_err("unimplemented"))
Ok(EthApi::transaction_by_block_and_tx_index(self, hash, index).await?)
}
/// Handler for: `eth_getTransactionByBlockNumberAndIndex`
async fn transaction_by_block_number_and_index(
&self,
_number: BlockNumberOrTag,
_index: Index,
number: BlockNumberOrTag,
index: Index,
) -> Result<Option<reth_rpc_types::Transaction>> {
Err(internal_rpc_err("unimplemented"))
Ok(EthApi::transaction_by_block_and_tx_index(self, number, index).await?)
}
/// Handler for: `eth_getTransactionReceipt`

View File

@ -1,13 +1,12 @@
//! Contains RPC handler implementations specific to transactions
use crate::{
eth::error::{EthApiError, EthResult},
EthApi,
};
use reth_primitives::{Bytes, FromRecoveredTransaction, TransactionSigned, H256};
use reth_primitives::{BlockId, Bytes, FromRecoveredTransaction, TransactionSigned, H256, U256};
use reth_provider::{BlockProvider, EvmEnvProvider, StateProviderFactory};
use reth_rlp::Decodable;
use reth_rpc_types::TransactionRequest;
use reth_rpc_types::{Index, Transaction, TransactionRequest};
use reth_transaction_pool::{TransactionOrigin, TransactionPool};
impl<Client, Pool, Network> EthApi<Client, Pool, Network>
@ -20,6 +19,58 @@ where
unimplemented!()
}
/// Finds a given trasaction by its hash.
pub(crate) async fn transaction_by_hash(
&self,
hash: H256,
) -> EthResult<Option<reth_rpc_types::Transaction>> {
let tx_by_hash = match self.client().transaction_by_hash(hash)? {
Some(item) => item,
None => return Ok(None),
};
if let Some(tx) = tx_by_hash.into_ecrecovered() {
Ok(Some(Transaction::from_recovered_with_block_context(
tx,
// TODO: this is just stubbed out for now still need to fully implement tx => block
H256::default(),
u64::default(),
U256::from(usize::from(Index::default())),
)))
} else {
Ok(None)
}
}
/// Get Transaction by Block and tx index within that Block.
/// Used for both:
/// transaction_by_block_hash_and_index() &
/// transaction_by_block_number_and_index()
pub(crate) async fn transaction_by_block_and_tx_index(
&self,
block_id: impl Into<BlockId>,
index: Index,
) -> EthResult<Option<reth_rpc_types::Transaction>> {
let block_id = block_id.into();
let Some(block) = self.client().block(block_id)? else {
return Ok(None);
};
let block_hash =
self.client().block_hash_for_id(block_id)?.ok_or(EthApiError::UnknownBlockNumber)?;
let Some(tx_signed) = block.body.into_iter().nth(usize::from(index)) else {
return Ok(None);
};
let Some(tx) = tx_signed.into_ecrecovered() else {
return Ok(None);
};
Ok(Some(Transaction::from_recovered_with_block_context(
tx,
block_hash,
block.header.number,
U256::from(usize::from(index)),
)))
}
/// Decodes and recovers the transaction and submits it to the pool.
///
/// Returns the hash of the transaction.