-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(util): Add reth payload util (#12590)
- Loading branch information
1 parent
02237bf
commit 5276093
Showing
14 changed files
with
207 additions
and
152 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
[package] | ||
name = "reth-payload-util" | ||
version.workspace = true | ||
edition.workspace = true | ||
rust-version.workspace = true | ||
license.workspace = true | ||
homepage.workspace = true | ||
repository.workspace = true | ||
description = "reth payload utilities" | ||
|
||
[lints] | ||
workspace = true | ||
|
||
[dependencies] | ||
# reth | ||
reth-primitives.workspace = true | ||
|
||
# alloy | ||
alloy-primitives.workspace = true | ||
alloy-consensus.workspace = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
//! payload utils. | ||
|
||
#![doc( | ||
html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", | ||
html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", | ||
issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" | ||
)] | ||
#![cfg_attr(not(test), warn(unused_crate_dependencies))] | ||
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] | ||
|
||
mod traits; | ||
mod transaction; | ||
|
||
pub use traits::PayloadTransactions; | ||
pub use transaction::{PayloadTransactionsChain, PayloadTransactionsFixed}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
use alloy_primitives::Address; | ||
use reth_primitives::TransactionSignedEcRecovered; | ||
|
||
/// Iterator that returns transactions for the block building process in the order they should be | ||
/// included in the block. | ||
/// | ||
/// Can include transactions from the pool and other sources (alternative pools, | ||
/// sequencer-originated transactions, etc.). | ||
pub trait PayloadTransactions { | ||
/// Returns the next transaction to include in the block. | ||
fn next( | ||
&mut self, | ||
// In the future, `ctx` can include access to state for block building purposes. | ||
ctx: (), | ||
) -> Option<TransactionSignedEcRecovered>; | ||
|
||
/// Exclude descendants of the transaction with given sender and nonce from the iterator, | ||
/// because this transaction won't be included in the block. | ||
fn mark_invalid(&mut self, sender: Address, nonce: u64); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
use crate::PayloadTransactions; | ||
use alloy_consensus::Transaction; | ||
use alloy_primitives::Address; | ||
use reth_primitives::TransactionSignedEcRecovered; | ||
|
||
/// An implementation of [`crate::traits::PayloadTransactions`] that yields | ||
/// a pre-defined set of transactions. | ||
/// | ||
/// This is useful to put a sequencer-specified set of transactions into the block | ||
/// and compose it with the rest of the transactions. | ||
#[derive(Debug)] | ||
pub struct PayloadTransactionsFixed<T> { | ||
transactions: Vec<T>, | ||
index: usize, | ||
} | ||
|
||
impl<T> PayloadTransactionsFixed<T> { | ||
/// Constructs a new [`PayloadTransactionsFixed`]. | ||
pub fn new(transactions: Vec<T>) -> Self { | ||
Self { transactions, index: Default::default() } | ||
} | ||
|
||
/// Constructs a new [`PayloadTransactionsFixed`] with a single transaction. | ||
pub fn single(transaction: T) -> Self { | ||
Self { transactions: vec![transaction], index: Default::default() } | ||
} | ||
} | ||
|
||
impl PayloadTransactions for PayloadTransactionsFixed<TransactionSignedEcRecovered> { | ||
fn next(&mut self, _ctx: ()) -> Option<TransactionSignedEcRecovered> { | ||
(self.index < self.transactions.len()).then(|| { | ||
let tx = self.transactions[self.index].clone(); | ||
self.index += 1; | ||
tx | ||
}) | ||
} | ||
|
||
fn mark_invalid(&mut self, _sender: Address, _nonce: u64) {} | ||
} | ||
|
||
/// Wrapper over [`crate::traits::PayloadTransactions`] that combines transactions from multiple | ||
/// `PayloadTransactions` iterators and keeps track of the gas for both of iterators. | ||
/// | ||
/// We can't use [`Iterator::chain`], because: | ||
/// (a) we need to propagate the `mark_invalid` and `no_updates` | ||
/// (b) we need to keep track of the gas | ||
/// | ||
/// Notes that [`PayloadTransactionsChain`] fully drains the first iterator | ||
/// before moving to the second one. | ||
/// | ||
/// If the `before` iterator has transactions that are not fitting into the block, | ||
/// the after iterator will get propagated a `mark_invalid` call for each of them. | ||
#[derive(Debug)] | ||
pub struct PayloadTransactionsChain<B: PayloadTransactions, A: PayloadTransactions> { | ||
/// Iterator that will be used first | ||
before: B, | ||
/// Allowed gas for the transactions from `before` iterator. If `None`, no gas limit is | ||
/// enforced. | ||
before_max_gas: Option<u64>, | ||
/// Gas used by the transactions from `before` iterator | ||
before_gas: u64, | ||
/// Iterator that will be used after `before` iterator | ||
after: A, | ||
/// Allowed gas for the transactions from `after` iterator. If `None`, no gas limit is | ||
/// enforced. | ||
after_max_gas: Option<u64>, | ||
/// Gas used by the transactions from `after` iterator | ||
after_gas: u64, | ||
} | ||
|
||
impl<B: PayloadTransactions, A: PayloadTransactions> PayloadTransactionsChain<B, A> { | ||
/// Constructs a new [`PayloadTransactionsChain`]. | ||
pub fn new( | ||
before: B, | ||
before_max_gas: Option<u64>, | ||
after: A, | ||
after_max_gas: Option<u64>, | ||
) -> Self { | ||
Self { | ||
before, | ||
before_max_gas, | ||
before_gas: Default::default(), | ||
after, | ||
after_max_gas, | ||
after_gas: Default::default(), | ||
} | ||
} | ||
} | ||
|
||
impl<B, A> PayloadTransactions for PayloadTransactionsChain<B, A> | ||
where | ||
B: PayloadTransactions, | ||
A: PayloadTransactions, | ||
{ | ||
fn next(&mut self, ctx: ()) -> Option<TransactionSignedEcRecovered> { | ||
while let Some(tx) = self.before.next(ctx) { | ||
if let Some(before_max_gas) = self.before_max_gas { | ||
if self.before_gas + tx.transaction.gas_limit() <= before_max_gas { | ||
self.before_gas += tx.transaction.gas_limit(); | ||
return Some(tx); | ||
} | ||
self.before.mark_invalid(tx.signer(), tx.transaction.nonce()); | ||
self.after.mark_invalid(tx.signer(), tx.transaction.nonce()); | ||
} else { | ||
return Some(tx); | ||
} | ||
} | ||
|
||
while let Some(tx) = self.after.next(ctx) { | ||
if let Some(after_max_gas) = self.after_max_gas { | ||
if self.after_gas + tx.transaction.gas_limit() <= after_max_gas { | ||
self.after_gas += tx.transaction.gas_limit(); | ||
return Some(tx); | ||
} | ||
self.after.mark_invalid(tx.signer(), tx.transaction.nonce()); | ||
} else { | ||
return Some(tx); | ||
} | ||
} | ||
|
||
None | ||
} | ||
|
||
fn mark_invalid(&mut self, sender: Address, nonce: u64) { | ||
self.before.mark_invalid(sender, nonce); | ||
self.after.mark_invalid(sender, nonce); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.