feat: add transaction_by_hash_with_meta (#1878)

This commit is contained in:
Matthias Seitz
2023-03-21 15:23:14 +01:00
committed by GitHub
parent f60b380a1e
commit 92e2c4d2aa
7 changed files with 90 additions and 8 deletions

View File

@@ -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;

View 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,
}

View File

@@ -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;

View File

@@ -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| {

View File

@@ -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!()
}

View File

@@ -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!()
}

View File

@@ -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>>;