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
|
/// transaction and used to determine the sender of
|
||||||
/// the transaction; formally Tr and Ts. This is expanded in Appendix F of yellow paper.
|
/// the transaction; formally Tr and Ts. This is expanded in Appendix F of yellow paper.
|
||||||
#[main_codec]
|
#[main_codec]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
|
||||||
pub struct Signature {
|
pub struct Signature {
|
||||||
/// The R field of the signature; the point on the curve.
|
/// The R field of the signature; the point on the curve.
|
||||||
pub r: U256,
|
pub r: U256,
|
||||||
|
|||||||
@ -9,7 +9,8 @@ use jsonrpsee::{
|
|||||||
types::error::{CallError, ErrorCode},
|
types::error::{CallError, ErrorCode},
|
||||||
};
|
};
|
||||||
use reth_primitives::{
|
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::{
|
use reth_rpc_api::{
|
||||||
clients::{AdminApiClient, EthApiClient},
|
clients::{AdminApiClient, EthApiClient},
|
||||||
@ -50,6 +51,7 @@ where
|
|||||||
let address = Address::default();
|
let address = Address::default();
|
||||||
let index = Index::default();
|
let index = Index::default();
|
||||||
let hash = H256::default();
|
let hash = H256::default();
|
||||||
|
let tx_hash = TxHash::default();
|
||||||
let block_number = BlockNumberOrTag::default();
|
let block_number = BlockNumberOrTag::default();
|
||||||
let call_request = CallRequest::default();
|
let call_request = CallRequest::default();
|
||||||
let transaction_request = TransactionRequest::default();
|
let transaction_request = TransactionRequest::default();
|
||||||
@ -75,21 +77,13 @@ where
|
|||||||
EthApiClient::block_uncles_count_by_number(client, block_number).await.unwrap();
|
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_hash_and_index(client, hash, index).await.unwrap();
|
||||||
EthApiClient::uncle_by_block_number_and_index(client, block_number, 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
|
// Unimplemented
|
||||||
assert!(is_unimplemented(EthApiClient::syncing(client).await.err().unwrap()));
|
assert!(is_unimplemented(EthApiClient::syncing(client).await.err().unwrap()));
|
||||||
assert!(is_unimplemented(EthApiClient::author(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::transaction_receipt(client, hash).await.err().unwrap()));
|
||||||
assert!(is_unimplemented(
|
assert!(is_unimplemented(
|
||||||
EthApiClient::call(client, call_request.clone(), None, None).await.err().unwrap()
|
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
|
/// The block hash, number, and tx index fields should be from the original block where the
|
||||||
/// transaction was mined.
|
/// transaction was mined.
|
||||||
pub(crate) fn from_recovered_with_block_context(
|
pub fn from_recovered_with_block_context(
|
||||||
tx: TransactionSignedEcRecovered,
|
tx: TransactionSignedEcRecovered,
|
||||||
block_hash: H256,
|
block_hash: H256,
|
||||||
block_number: BlockNumber,
|
block_number: BlockNumber,
|
||||||
@ -142,7 +142,7 @@ impl Transaction {
|
|||||||
max_fee_per_gas,
|
max_fee_per_gas,
|
||||||
max_priority_fee_per_gas: signed_tx.max_priority_fee_per_gas().map(U128::from),
|
max_priority_fee_per_gas: signed_tx.max_priority_fee_per_gas().map(U128::from),
|
||||||
signature: Some(Signature::from_primitive_signature(
|
signature: Some(Signature::from_primitive_signature(
|
||||||
signed_tx.signature().clone(),
|
*signed_tx.signature(),
|
||||||
signed_tx.chain_id(),
|
signed_tx.chain_id(),
|
||||||
)),
|
)),
|
||||||
gas: U256::from(signed_tx.gas_limit()),
|
gas: U256::from(signed_tx.gas_limit()),
|
||||||
|
|||||||
@ -117,29 +117,26 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Handler for: `eth_getTransactionByHash`
|
/// Handler for: `eth_getTransactionByHash`
|
||||||
async fn transaction_by_hash(
|
async fn transaction_by_hash(&self, hash: H256) -> Result<Option<reth_rpc_types::Transaction>> {
|
||||||
&self,
|
Ok(EthApi::transaction_by_hash(self, hash).await?)
|
||||||
_hash: H256,
|
|
||||||
) -> Result<Option<reth_rpc_types::Transaction>> {
|
|
||||||
Err(internal_rpc_err("unimplemented"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handler for: `eth_getTransactionByBlockHashAndIndex`
|
/// Handler for: `eth_getTransactionByBlockHashAndIndex`
|
||||||
async fn transaction_by_block_hash_and_index(
|
async fn transaction_by_block_hash_and_index(
|
||||||
&self,
|
&self,
|
||||||
_hash: H256,
|
hash: H256,
|
||||||
_index: Index,
|
index: Index,
|
||||||
) -> Result<Option<reth_rpc_types::Transaction>> {
|
) -> 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`
|
/// Handler for: `eth_getTransactionByBlockNumberAndIndex`
|
||||||
async fn transaction_by_block_number_and_index(
|
async fn transaction_by_block_number_and_index(
|
||||||
&self,
|
&self,
|
||||||
_number: BlockNumberOrTag,
|
number: BlockNumberOrTag,
|
||||||
_index: Index,
|
index: Index,
|
||||||
) -> Result<Option<reth_rpc_types::Transaction>> {
|
) -> 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`
|
/// Handler for: `eth_getTransactionReceipt`
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
//! Contains RPC handler implementations specific to transactions
|
//! Contains RPC handler implementations specific to transactions
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
eth::error::{EthApiError, EthResult},
|
eth::error::{EthApiError, EthResult},
|
||||||
EthApi,
|
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_provider::{BlockProvider, EvmEnvProvider, StateProviderFactory};
|
||||||
use reth_rlp::Decodable;
|
use reth_rlp::Decodable;
|
||||||
use reth_rpc_types::TransactionRequest;
|
use reth_rpc_types::{Index, Transaction, TransactionRequest};
|
||||||
use reth_transaction_pool::{TransactionOrigin, TransactionPool};
|
use reth_transaction_pool::{TransactionOrigin, TransactionPool};
|
||||||
|
|
||||||
impl<Client, Pool, Network> EthApi<Client, Pool, Network>
|
impl<Client, Pool, Network> EthApi<Client, Pool, Network>
|
||||||
@ -20,6 +19,58 @@ where
|
|||||||
unimplemented!()
|
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.
|
/// Decodes and recovers the transaction and submits it to the pool.
|
||||||
///
|
///
|
||||||
/// Returns the hash of the transaction.
|
/// Returns the hash of the transaction.
|
||||||
|
|||||||
Reference in New Issue
Block a user