mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
feat(rpc): eth_transactionBy impls (#1664)
Co-authored-by: Sam Bukowski <sambukowski@Sams-MacBook-Pro.local>
This commit is contained in:
@ -6,7 +6,7 @@ use reth_rlp::{Decodable, DecodeError, Encodable};
|
||||
/// transaction and used to determine the sender of
|
||||
/// the transaction; formally Tr and Ts. This is expanded in Appendix F of yellow paper.
|
||||
#[main_codec]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
|
||||
pub struct Signature {
|
||||
/// The R field of the signature; the point on the curve.
|
||||
pub r: U256,
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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()),
|
||||
|
||||
@ -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`
|
||||
|
||||
@ -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.
|
||||
|
||||
Reference in New Issue
Block a user