mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
chore: add a few tx related helper functions (#5430)
This commit is contained in:
@ -1,4 +1,7 @@
|
|||||||
use crate::{Address, Header, SealedHeader, TransactionSigned, Withdrawal, B256};
|
use crate::{
|
||||||
|
Address, Header, SealedHeader, TransactionSigned, TransactionSignedEcRecovered, Withdrawal,
|
||||||
|
B256,
|
||||||
|
};
|
||||||
use alloy_rlp::{RlpDecodable, RlpEncodable};
|
use alloy_rlp::{RlpDecodable, RlpEncodable};
|
||||||
use reth_codecs::derive_arbitrary;
|
use reth_codecs::derive_arbitrary;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -252,9 +255,38 @@ impl SealedBlockWithSenders {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Split Structure to its components
|
/// Split Structure to its components
|
||||||
|
#[inline]
|
||||||
pub fn into_components(self) -> (SealedBlock, Vec<Address>) {
|
pub fn into_components(self) -> (SealedBlock, Vec<Address>) {
|
||||||
(self.block, self.senders)
|
(self.block, self.senders)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over all transactions in the block.
|
||||||
|
#[inline]
|
||||||
|
pub fn transactions(&self) -> impl Iterator<Item = &TransactionSigned> + '_ {
|
||||||
|
self.block.body.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over all transactions and their sender.
|
||||||
|
#[inline]
|
||||||
|
pub fn transactions_with_sender(
|
||||||
|
&self,
|
||||||
|
) -> impl Iterator<Item = (&Address, &TransactionSigned)> + '_ {
|
||||||
|
self.senders.iter().zip(self.block.body.iter())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Consumes the block and returns the transactions of the block.
|
||||||
|
#[inline]
|
||||||
|
pub fn into_transactions(self) -> Vec<TransactionSigned> {
|
||||||
|
self.block.body
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over all transactions in the chain.
|
||||||
|
#[inline]
|
||||||
|
pub fn into_transactions_ecrecovered(
|
||||||
|
self,
|
||||||
|
) -> impl Iterator<Item = TransactionSignedEcRecovered> {
|
||||||
|
self.block.body.into_iter().zip(self.senders).map(|(tx, sender)| tx.with_signer(sender))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for SealedBlockWithSenders {
|
impl Deref for SealedBlockWithSenders {
|
||||||
|
|||||||
@ -1006,6 +1006,12 @@ impl TransactionSigned {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the [TransactionSignedEcRecovered] transaction with the given sender.
|
||||||
|
#[inline]
|
||||||
|
pub const fn with_signer(self, signer: Address) -> TransactionSignedEcRecovered {
|
||||||
|
TransactionSignedEcRecovered::from_signed_transaction(self, signer)
|
||||||
|
}
|
||||||
|
|
||||||
/// Consumes the type, recover signer and return [`TransactionSignedEcRecovered`]
|
/// Consumes the type, recover signer and return [`TransactionSignedEcRecovered`]
|
||||||
///
|
///
|
||||||
/// Returns `None` if the transaction's signature is invalid, see also [Self::recover_signer].
|
/// Returns `None` if the transaction's signature is invalid, see also [Self::recover_signer].
|
||||||
@ -1424,7 +1430,11 @@ impl TransactionSignedEcRecovered {
|
|||||||
|
|
||||||
/// Create [`TransactionSignedEcRecovered`] from [`TransactionSigned`] and [`Address`] of the
|
/// Create [`TransactionSignedEcRecovered`] from [`TransactionSigned`] and [`Address`] of the
|
||||||
/// signer.
|
/// signer.
|
||||||
pub fn from_signed_transaction(signed_transaction: TransactionSigned, signer: Address) -> Self {
|
#[inline]
|
||||||
|
pub const fn from_signed_transaction(
|
||||||
|
signed_transaction: TransactionSigned,
|
||||||
|
signer: Address,
|
||||||
|
) -> Self {
|
||||||
Self { signed_transaction, signer }
|
Self { signed_transaction, signer }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,8 +3,8 @@
|
|||||||
use crate::bundle_state::BundleStateWithReceipts;
|
use crate::bundle_state::BundleStateWithReceipts;
|
||||||
use reth_interfaces::{executor::BlockExecutionError, RethResult};
|
use reth_interfaces::{executor::BlockExecutionError, RethResult};
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
BlockHash, BlockNumHash, BlockNumber, ForkBlock, Receipt, SealedBlock, SealedBlockWithSenders,
|
Address, BlockHash, BlockNumHash, BlockNumber, ForkBlock, Receipt, SealedBlock,
|
||||||
SealedHeader, TransactionSigned, TxHash,
|
SealedBlockWithSenders, SealedHeader, TransactionSigned, TransactionSignedEcRecovered, TxHash,
|
||||||
};
|
};
|
||||||
use std::{borrow::Cow, collections::BTreeMap, fmt};
|
use std::{borrow::Cow, collections::BTreeMap, fmt};
|
||||||
|
|
||||||
@ -276,11 +276,13 @@ impl<'a> ChainBlocks<'a> {
|
|||||||
/// Creates a consuming iterator over all blocks in the chain with increasing block number.
|
/// Creates a consuming iterator over all blocks in the chain with increasing block number.
|
||||||
///
|
///
|
||||||
/// Note: this always yields at least one block.
|
/// Note: this always yields at least one block.
|
||||||
|
#[inline]
|
||||||
pub fn into_blocks(self) -> impl Iterator<Item = SealedBlockWithSenders> {
|
pub fn into_blocks(self) -> impl Iterator<Item = SealedBlockWithSenders> {
|
||||||
self.blocks.into_owned().into_values()
|
self.blocks.into_owned().into_values()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an iterator over all blocks in the chain with increasing block number.
|
/// Creates an iterator over all blocks in the chain with increasing block number.
|
||||||
|
#[inline]
|
||||||
pub fn iter(&self) -> impl Iterator<Item = (&BlockNumber, &SealedBlockWithSenders)> {
|
pub fn iter(&self) -> impl Iterator<Item = (&BlockNumber, &SealedBlockWithSenders)> {
|
||||||
self.blocks.iter()
|
self.blocks.iter()
|
||||||
}
|
}
|
||||||
@ -290,6 +292,7 @@ impl<'a> ChainBlocks<'a> {
|
|||||||
/// # Note
|
/// # Note
|
||||||
///
|
///
|
||||||
/// Chains always have at least one block.
|
/// Chains always have at least one block.
|
||||||
|
#[inline]
|
||||||
pub fn tip(&self) -> &SealedBlockWithSenders {
|
pub fn tip(&self) -> &SealedBlockWithSenders {
|
||||||
self.blocks.last_key_value().expect("Chain should have at least one block").1
|
self.blocks.last_key_value().expect("Chain should have at least one block").1
|
||||||
}
|
}
|
||||||
@ -299,14 +302,40 @@ impl<'a> ChainBlocks<'a> {
|
|||||||
/// # Note
|
/// # Note
|
||||||
///
|
///
|
||||||
/// Chains always have at least one block.
|
/// Chains always have at least one block.
|
||||||
|
#[inline]
|
||||||
pub fn first(&self) -> &SealedBlockWithSenders {
|
pub fn first(&self) -> &SealedBlockWithSenders {
|
||||||
self.blocks.first_key_value().expect("Chain should have at least one block").1
|
self.blocks.first_key_value().expect("Chain should have at least one block").1
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over all transactions in the chain.
|
/// Returns an iterator over all transactions in the chain.
|
||||||
|
#[inline]
|
||||||
pub fn transactions(&self) -> impl Iterator<Item = &TransactionSigned> + '_ {
|
pub fn transactions(&self) -> impl Iterator<Item = &TransactionSigned> + '_ {
|
||||||
self.blocks.values().flat_map(|block| block.body.iter())
|
self.blocks.values().flat_map(|block| block.body.iter())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over all transactions and their senders.
|
||||||
|
#[inline]
|
||||||
|
pub fn transactions_with_sender(
|
||||||
|
&self,
|
||||||
|
) -> impl Iterator<Item = (&Address, &TransactionSigned)> + '_ {
|
||||||
|
self.blocks.values().flat_map(|block| block.transactions_with_sender())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over all [TransactionSignedEcRecovered] in the blocks
|
||||||
|
///
|
||||||
|
/// Note: This clones the transactions since it is assumed this is part of a shared [Chain].
|
||||||
|
#[inline]
|
||||||
|
pub fn transactions_ecrecovered(
|
||||||
|
&self,
|
||||||
|
) -> impl Iterator<Item = TransactionSignedEcRecovered> + '_ {
|
||||||
|
self.transactions_with_sender().map(|(signer, tx)| tx.clone().with_signer(*signer))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over all transaction hashes in the block
|
||||||
|
#[inline]
|
||||||
|
pub fn transaction_hashes(&self) -> impl Iterator<Item = TxHash> + '_ {
|
||||||
|
self.blocks.values().flat_map(|block| block.transactions().map(|tx| tx.hash))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> IntoIterator for ChainBlocks<'a> {
|
impl<'a> IntoIterator for ChainBlocks<'a> {
|
||||||
|
|||||||
@ -279,15 +279,13 @@ pub async fn maintain_transaction_pool<Client, P, St, Tasks>(
|
|||||||
changed_accounts.extend(new_changed_accounts.into_iter().map(|entry| entry.0));
|
changed_accounts.extend(new_changed_accounts.into_iter().map(|entry| entry.0));
|
||||||
|
|
||||||
// all transactions mined in the new chain
|
// all transactions mined in the new chain
|
||||||
let new_mined_transactions: HashSet<_> =
|
let new_mined_transactions: HashSet<_> = new_blocks.transaction_hashes().collect();
|
||||||
new_blocks.transactions().map(|tx| tx.hash).collect();
|
|
||||||
|
|
||||||
// update the pool then re-inject the pruned transactions
|
// update the pool then re-inject the pruned transactions
|
||||||
// find all transactions that were mined in the old chain but not in the new chain
|
// find all transactions that were mined in the old chain but not in the new chain
|
||||||
let pruned_old_transactions = old_blocks
|
let pruned_old_transactions = old_blocks
|
||||||
.transactions()
|
.transactions_ecrecovered()
|
||||||
.filter(|tx| !new_mined_transactions.contains(&tx.hash))
|
.filter(|tx| !new_mined_transactions.contains(&tx.hash))
|
||||||
.filter_map(|tx| tx.clone().into_ecrecovered())
|
|
||||||
.map(<P as TransactionPool>::Transaction::from_recovered_transaction)
|
.map(<P as TransactionPool>::Transaction::from_recovered_transaction)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
@ -359,7 +357,7 @@ pub async fn maintain_transaction_pool<Client, P, St, Tasks>(
|
|||||||
changed_accounts.push(acc);
|
changed_accounts.push(acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mined_transactions = blocks.transactions().map(|tx| tx.hash).collect();
|
let mined_transactions = blocks.transaction_hashes().collect();
|
||||||
|
|
||||||
// check if the range of the commit is canonical with the pool's block
|
// check if the range of the commit is canonical with the pool's block
|
||||||
if first_block.parent_hash != pool_info.last_seen_block_hash {
|
if first_block.parent_hash != pool_info.last_seen_block_hash {
|
||||||
|
|||||||
Reference in New Issue
Block a user