Skip to content

Commit 43f3822

Browse files
feat: Track DA cost in Op Pooled transactions (#13806)
Co-authored-by: Matthias Seitz <[email protected]>
1 parent 5db0129 commit 43f3822

File tree

1 file changed

+49
-26
lines changed

1 file changed

+49
-26
lines changed

crates/optimism/node/src/txpool.rs

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use reth_transaction_pool::{
2525
use revm::primitives::{AccessList, KzgSettings};
2626
use std::sync::{
2727
atomic::{AtomicU64, Ordering},
28-
Arc,
28+
Arc, OnceLock,
2929
};
3030

3131
/// Type alias for default optimism transaction pool
@@ -36,21 +36,44 @@ pub type OpTransactionPool<Client, S> = Pool<
3636
>;
3737

3838
/// Pool transaction for OP.
39+
///
40+
/// This type wraps the actual transaction and caches values that are frequently used by the pool.
41+
/// For payload building this lazily tracks values that are required during payload building:
42+
/// - Estimated compressed size of this transaction
3943
#[derive(Debug, Clone, derive_more::Deref)]
40-
pub struct OpPooledTransaction(EthPooledTransaction<OpTransactionSigned>);
44+
pub struct OpPooledTransaction {
45+
#[deref]
46+
inner: EthPooledTransaction<OpTransactionSigned>,
47+
/// The estimated size of this transaction, lazily computed.
48+
estimated_tx_compressed_size: OnceLock<u32>,
49+
}
4150

4251
impl OpPooledTransaction {
4352
/// Create new instance of [Self].
4453
pub fn new(transaction: RecoveredTx<OpTransactionSigned>, encoded_length: usize) -> Self {
45-
Self(EthPooledTransaction::new(transaction, encoded_length))
54+
Self {
55+
inner: EthPooledTransaction::new(transaction, encoded_length),
56+
estimated_tx_compressed_size: Default::default(),
57+
}
58+
}
59+
60+
/// Returns the estimated compressed size of a transaction in bytes scaled by 1e6.
61+
// This value is computed based on the following formula:
62+
// `max(minTransactionSize, intercept + fastlzCoef*fastlzSize)`
63+
pub fn estimated_compressed_size(&self) -> u32 {
64+
// TODO(mattsse): use standalone flz compute function
65+
*self.estimated_tx_compressed_size.get_or_init(|| self.inner.encoded_length as u32)
4666
}
4767
}
4868

4969
impl From<RecoveredTx<op_alloy_consensus::OpPooledTransaction>> for OpPooledTransaction {
5070
fn from(tx: RecoveredTx<op_alloy_consensus::OpPooledTransaction>) -> Self {
5171
let encoded_len = tx.encode_2718_len();
5272
let tx = tx.map_transaction(|tx| tx.into());
53-
Self(EthPooledTransaction::new(tx, encoded_len))
73+
Self {
74+
inner: EthPooledTransaction::new(tx, encoded_len),
75+
estimated_tx_compressed_size: Default::default(),
76+
}
5477
}
5578
}
5679

@@ -67,7 +90,7 @@ impl TryFrom<RecoveredTx<OpTransactionSigned>> for OpPooledTransaction {
6790

6891
impl From<OpPooledTransaction> for RecoveredTx<OpTransactionSigned> {
6992
fn from(value: OpPooledTransaction) -> Self {
70-
value.0.transaction
93+
value.inner.transaction
7194
}
7295
}
7396

@@ -77,7 +100,7 @@ impl PoolTransaction for OpPooledTransaction {
77100
type Pooled = op_alloy_consensus::OpPooledTransaction;
78101

79102
fn clone_into_consensus(&self) -> RecoveredTx<Self::Consensus> {
80-
self.transaction().clone()
103+
self.inner.transaction().clone()
81104
}
82105

83106
fn try_consensus_into_pooled(
@@ -88,79 +111,79 @@ impl PoolTransaction for OpPooledTransaction {
88111
}
89112

90113
fn hash(&self) -> &TxHash {
91-
self.transaction.tx_hash()
114+
self.inner.transaction.tx_hash()
92115
}
93116

94117
fn sender(&self) -> Address {
95-
self.transaction.signer()
118+
self.inner.transaction.signer()
96119
}
97120

98121
fn sender_ref(&self) -> &Address {
99-
self.transaction.signer_ref()
122+
self.inner.transaction.signer_ref()
100123
}
101124

102125
fn nonce(&self) -> u64 {
103-
self.transaction.nonce()
126+
self.inner.transaction.nonce()
104127
}
105128

106129
fn cost(&self) -> &U256 {
107-
&self.cost
130+
&self.inner.cost
108131
}
109132

110133
fn gas_limit(&self) -> u64 {
111-
self.transaction.gas_limit()
134+
self.inner.transaction.gas_limit()
112135
}
113136

114137
fn max_fee_per_gas(&self) -> u128 {
115-
self.transaction.transaction.max_fee_per_gas()
138+
self.inner.transaction.transaction.max_fee_per_gas()
116139
}
117140

118141
fn access_list(&self) -> Option<&AccessList> {
119-
self.transaction.access_list()
142+
self.inner.transaction.access_list()
120143
}
121144

122145
fn max_priority_fee_per_gas(&self) -> Option<u128> {
123-
self.transaction.transaction.max_priority_fee_per_gas()
146+
self.inner.transaction.transaction.max_priority_fee_per_gas()
124147
}
125148

126149
fn max_fee_per_blob_gas(&self) -> Option<u128> {
127-
self.transaction.max_fee_per_blob_gas()
150+
self.inner.transaction.max_fee_per_blob_gas()
128151
}
129152

130153
fn effective_tip_per_gas(&self, base_fee: u64) -> Option<u128> {
131-
self.transaction.effective_tip_per_gas(base_fee)
154+
self.inner.transaction.effective_tip_per_gas(base_fee)
132155
}
133156

134157
fn priority_fee_or_price(&self) -> u128 {
135-
self.transaction.priority_fee_or_price()
158+
self.inner.transaction.priority_fee_or_price()
136159
}
137160

138161
fn kind(&self) -> TxKind {
139-
self.transaction.kind()
162+
self.inner.transaction.kind()
140163
}
141164

142165
fn is_create(&self) -> bool {
143-
self.transaction.is_create()
166+
self.inner.transaction.is_create()
144167
}
145168

146169
fn input(&self) -> &[u8] {
147-
self.transaction.input()
170+
self.inner.transaction.input()
148171
}
149172

150173
fn size(&self) -> usize {
151-
self.transaction.transaction.input().len()
174+
self.inner.transaction.transaction.input().len()
152175
}
153176

154177
fn tx_type(&self) -> u8 {
155-
self.transaction.ty()
178+
self.inner.transaction.ty()
156179
}
157180

158181
fn encoded_length(&self) -> usize {
159-
self.encoded_length
182+
self.inner.encoded_length
160183
}
161184

162185
fn chain_id(&self) -> Option<u64> {
163-
self.transaction.chain_id()
186+
self.inner.transaction.chain_id()
164187
}
165188
}
166189

@@ -196,7 +219,7 @@ impl EthPoolTransaction for OpPooledTransaction {
196219
}
197220

198221
fn authorization_count(&self) -> usize {
199-
match &self.transaction.transaction {
222+
match &self.inner.transaction.transaction {
200223
OpTypedTransaction::Eip7702(tx) => tx.authorization_list.len(),
201224
_ => 0,
202225
}

0 commit comments

Comments
 (0)