mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-30 17:48:03 -05:00
feat: add transaction_by_hash_with_meta (#1878)
This commit is contained in:
@@ -70,8 +70,9 @@ pub use storage::{StorageEntry, StorageTrieEntry};
|
||||
pub use transaction::{
|
||||
util::secp256k1::sign_message, AccessList, AccessListItem, AccessListWithGasUsed,
|
||||
FromRecoveredTransaction, IntoRecoveredTransaction, InvalidTransactionError, Signature,
|
||||
Transaction, TransactionKind, TransactionSigned, TransactionSignedEcRecovered, TxEip1559,
|
||||
TxEip2930, TxLegacy, TxType, EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID, LEGACY_TX_TYPE_ID,
|
||||
Transaction, TransactionKind, TransactionMeta, TransactionSigned, TransactionSignedEcRecovered,
|
||||
TxEip1559, TxEip2930, TxLegacy, TxType, EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID,
|
||||
LEGACY_TX_TYPE_ID,
|
||||
};
|
||||
pub use withdrawal::Withdrawal;
|
||||
|
||||
|
||||
14
crates/primitives/src/transaction/meta.rs
Normal file
14
crates/primitives/src/transaction/meta.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
use crate::H256;
|
||||
|
||||
/// Additional fields in the context of a block that contains this transaction.
|
||||
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq)]
|
||||
pub struct TransactionMeta {
|
||||
/// Hash of the transaction.
|
||||
pub tx_hash: H256,
|
||||
/// Index of the transaction in the block
|
||||
pub index: u64,
|
||||
/// Hash of the block.
|
||||
pub block_hash: H256,
|
||||
/// Number of the block.
|
||||
pub block_number: u64,
|
||||
}
|
||||
@@ -3,6 +3,7 @@ pub use access_list::{AccessList, AccessListItem, AccessListWithGasUsed};
|
||||
use bytes::{Buf, BytesMut};
|
||||
use derive_more::{AsRef, Deref};
|
||||
pub use error::InvalidTransactionError;
|
||||
pub use meta::TransactionMeta;
|
||||
use reth_codecs::{add_arbitrary_tests, main_codec, Compact};
|
||||
use reth_rlp::{
|
||||
length_of_length, Decodable, DecodeError, Encodable, Header, EMPTY_LIST_CODE, EMPTY_STRING_CODE,
|
||||
@@ -12,6 +13,7 @@ pub use tx_type::{TxType, EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID, LEGACY_TX_TYPE
|
||||
|
||||
mod access_list;
|
||||
mod error;
|
||||
mod meta;
|
||||
mod signature;
|
||||
mod tx_type;
|
||||
pub(crate) mod util;
|
||||
|
||||
@@ -11,7 +11,7 @@ use reth_db::{
|
||||
use reth_interfaces::Result;
|
||||
use reth_primitives::{
|
||||
Block, BlockHash, BlockId, BlockNumber, ChainInfo, ChainSpec, Hardfork, Head, Header, Receipt,
|
||||
TransactionSigned, TxHash, TxNumber, Withdrawal, H256, U256,
|
||||
TransactionMeta, TransactionSigned, TxHash, TxNumber, Withdrawal, H256, U256,
|
||||
};
|
||||
use reth_revm_primitives::{
|
||||
config::revm_spec,
|
||||
@@ -181,6 +181,50 @@ impl<DB: Database> TransactionsProvider for ShareableDatabase<DB> {
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
fn transaction_by_hash_with_meta(
|
||||
&self,
|
||||
tx_hash: TxHash,
|
||||
) -> Result<Option<(TransactionSigned, TransactionMeta)>> {
|
||||
self.db
|
||||
.view(|tx| -> Result<_> {
|
||||
if let Some(transaction_id) = tx.get::<tables::TxHashNumber>(tx_hash)? {
|
||||
if let Some(transaction) = tx.get::<tables::Transactions>(transaction_id)? {
|
||||
let mut transaction_cursor =
|
||||
tx.cursor_read::<tables::TransactionBlock>()?;
|
||||
if let Some(block_number) =
|
||||
transaction_cursor.seek(transaction_id).map(|b| b.map(|(_, bn)| bn))?
|
||||
{
|
||||
if let Some(block_hash) =
|
||||
tx.get::<tables::CanonicalHeaders>(block_number)?
|
||||
{
|
||||
if let Some(block_body) =
|
||||
tx.get::<tables::BlockBodies>(block_number)?
|
||||
{
|
||||
// the index of the tx in the block is the offset:
|
||||
// len([start..tx_id])
|
||||
// SAFETY: `transaction_id` is always `>=` the block's first
|
||||
// index
|
||||
let index = transaction_id - block_body.first_tx_index();
|
||||
|
||||
let meta = TransactionMeta {
|
||||
tx_hash,
|
||||
index,
|
||||
block_hash,
|
||||
block_number,
|
||||
};
|
||||
|
||||
return Ok(Some((transaction, meta)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
})?
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
fn transaction_block(&self, id: TxNumber) -> Result<Option<BlockNumber>> {
|
||||
self.db
|
||||
.view(|tx| {
|
||||
|
||||
@@ -6,8 +6,8 @@ use parking_lot::Mutex;
|
||||
use reth_interfaces::Result;
|
||||
use reth_primitives::{
|
||||
keccak256, Account, Address, Block, BlockHash, BlockId, BlockNumber, BlockNumberOrTag,
|
||||
Bytecode, Bytes, ChainInfo, Header, Receipt, StorageKey, StorageValue, TransactionSigned,
|
||||
TxHash, TxNumber, H256, U256,
|
||||
Bytecode, Bytes, ChainInfo, Header, Receipt, StorageKey, StorageValue, TransactionMeta,
|
||||
TransactionSigned, TxHash, TxNumber, H256, U256,
|
||||
};
|
||||
use revm_primitives::{BlockEnv, CfgEnv};
|
||||
use std::{collections::HashMap, ops::RangeBounds, sync::Arc};
|
||||
@@ -149,6 +149,13 @@ impl TransactionsProvider for MockEthProvider {
|
||||
.find_map(|(_, block)| block.body.iter().find(|tx| tx.hash == hash).cloned()))
|
||||
}
|
||||
|
||||
fn transaction_by_hash_with_meta(
|
||||
&self,
|
||||
_hash: TxHash,
|
||||
) -> Result<Option<(TransactionSigned, TransactionMeta)>> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn transaction_block(&self, _id: TxNumber) -> Result<Option<BlockNumber>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ use crate::{
|
||||
use reth_interfaces::Result;
|
||||
use reth_primitives::{
|
||||
Account, Address, Block, BlockHash, BlockId, BlockNumber, Bytecode, Bytes, ChainInfo, Header,
|
||||
Receipt, StorageKey, StorageValue, TransactionSigned, TxHash, TxNumber, H256, KECCAK_EMPTY,
|
||||
U256,
|
||||
Receipt, StorageKey, StorageValue, TransactionMeta, TransactionSigned, TxHash, TxNumber, H256,
|
||||
KECCAK_EMPTY, U256,
|
||||
};
|
||||
use revm_primitives::{BlockEnv, CfgEnv};
|
||||
use std::ops::RangeBounds;
|
||||
@@ -56,6 +56,13 @@ impl TransactionsProvider for NoopProvider {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn transaction_by_hash_with_meta(
|
||||
&self,
|
||||
_hash: TxHash,
|
||||
) -> Result<Option<(TransactionSigned, TransactionMeta)>> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn transaction_block(&self, _id: TxNumber) -> Result<Option<BlockNumber>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::BlockIdProvider;
|
||||
use reth_interfaces::Result;
|
||||
use reth_primitives::{BlockId, BlockNumber, TransactionSigned, TxHash, TxNumber};
|
||||
use reth_primitives::{BlockId, BlockNumber, TransactionMeta, TransactionSigned, TxHash, TxNumber};
|
||||
use std::ops::RangeBounds;
|
||||
|
||||
/// Client trait for fetching [TransactionSigned] related data.
|
||||
@@ -12,6 +12,13 @@ pub trait TransactionsProvider: BlockIdProvider + Send + Sync {
|
||||
/// Get transaction by transaction hash.
|
||||
fn transaction_by_hash(&self, hash: TxHash) -> Result<Option<TransactionSigned>>;
|
||||
|
||||
/// Get transaction by transaction hash and additional metadata of the block the transaction was
|
||||
/// mined in
|
||||
fn transaction_by_hash_with_meta(
|
||||
&self,
|
||||
hash: TxHash,
|
||||
) -> Result<Option<(TransactionSigned, TransactionMeta)>>;
|
||||
|
||||
/// Get transaction block number
|
||||
fn transaction_block(&self, id: TxNumber) -> Result<Option<BlockNumber>>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user