diff --git a/Cargo.lock b/Cargo.lock index 332b0cd..f8c9091 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6005,20 +6005,6 @@ dependencies = [ "thiserror 2.0.17", ] -[[package]] -name = "op-alloy-consensus" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1fc8aa0e2f5b136d101630be009e4e6dbdd1f17bc3ce670f431511600d2930" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-primitives", - "alloy-rlp", - "derive_more", - "thiserror 2.0.17", -] - [[package]] name = "op-alloy-consensus" version = "0.22.0" @@ -13057,13 +13043,14 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tips-core" version = "0.1.0" -source = "git+https://github.com/base/tips?rev=27674ae051a86033ece61ae24434aeacdb28ce73#27674ae051a86033ece61ae24434aeacdb28ce73" +source = "git+https://github.com/base/tips?rev=98c9ab49419e62352fe29cf79873141aaa3eb956#98c9ab49419e62352fe29cf79873141aaa3eb956" dependencies = [ "alloy-consensus", "alloy-primitives", "alloy-provider", "alloy-serde", - "op-alloy-consensus 0.21.0", + "op-alloy-consensus 0.22.0", + "op-alloy-flz", "serde", "tracing", "tracing-subscriber 0.3.20", diff --git a/Cargo.toml b/Cargo.toml index 2bf905b..f21aad3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,7 +45,7 @@ base-reth-transaction-tracing = { path = "crates/transaction-tracing" } # base/tips # Note: default-features = false avoids version conflicts with reth's alloy/op-alloy dependencies -tips-core = { git = "https://github.com/base/tips", rev = "27674ae051a86033ece61ae24434aeacdb28ce73", default-features = false } +tips-core = { git = "https://github.com/base/tips", rev = "98c9ab49419e62352fe29cf79873141aaa3eb956", default-features = false } # reth reth = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.0" } diff --git a/crates/metering/src/meter.rs b/crates/metering/src/meter.rs index 01e6190..d8882ee 100644 --- a/crates/metering/src/meter.rs +++ b/crates/metering/src/meter.rs @@ -9,6 +9,7 @@ use reth_optimism_evm::{OpEvmConfig, OpNextBlockEnvAttributes}; use reth_primitives_traits::SealedHeader; use std::sync::Arc; use std::time::Instant; +use tips_core::types::{BundleExtensions, BundleTxs, ParsedBundle}; use crate::TransactionResult; @@ -28,15 +29,14 @@ const BLOCK_TIME: u64 = 2; // 2 seconds per block pub fn meter_bundle( state_provider: SP, chain_spec: Arc, - decoded_txs: Vec, + bundle: ParsedBundle, header: &SealedHeader, - bundle_with_metadata: &tips_core::types::BundleWithMetadata, ) -> EyreResult<(Vec, u64, U256, B256, u128)> where SP: reth_provider::StateProvider, { - // Get bundle hash from BundleWithMetadata - let bundle_hash = bundle_with_metadata.bundle_hash(); + // Get bundle hash + let bundle_hash = bundle.bundle_hash(); // Create state database let state_db = reth::revm::database::StateProviderDatabase::new(state_provider); @@ -47,8 +47,7 @@ where // Set up next block attributes // Use bundle.min_timestamp if provided, otherwise use header timestamp + BLOCK_TIME - let timestamp = bundle_with_metadata - .bundle() + let timestamp = bundle .min_timestamp .unwrap_or_else(|| header.timestamp() + BLOCK_TIME); let attributes = OpNextBlockEnvAttributes { @@ -72,7 +71,7 @@ where builder.apply_pre_execution_changes()?; - for tx in decoded_txs { + for tx in bundle.transactions() { let tx_start = Instant::now(); let tx_hash = tx.tx_hash(); let from = tx.recover_signer()?; @@ -80,11 +79,8 @@ where let value = tx.value(); let gas_price = tx.max_fee_per_gas(); - let recovered_tx = - alloy_consensus::transaction::Recovered::new_unchecked(tx.clone(), from); - let gas_used = builder - .execute_transaction(recovered_tx) + .execute_transaction(tx.clone()) .map_err(|e| eyre!("Transaction {} execution failed: {}", tx_hash, e))?; let gas_fees = U256::from(gas_used) * U256::from(gas_price); diff --git a/crates/metering/src/rpc.rs b/crates/metering/src/rpc.rs index 616baae..98059fd 100644 --- a/crates/metering/src/rpc.rs +++ b/crates/metering/src/rpc.rs @@ -1,6 +1,5 @@ use alloy_consensus::Header; use alloy_eips::BlockNumberOrTag; -use alloy_eips::eip2718::Decodable2718; use alloy_primitives::U256; use jsonrpsee::{ core::{RpcResult, async_trait}, @@ -9,7 +8,7 @@ use jsonrpsee::{ use reth::providers::BlockReaderIdExt; use reth_optimism_chainspec::OpChainSpec; use reth_provider::{ChainSpecProvider, StateProviderFactory}; -use tips_core::types::{Bundle, BundleWithMetadata, MeterBundleResponse}; +use tips_core::types::{Bundle, MeterBundleResponse, ParsedBundle}; use tracing::{error, info}; use crate::meter_bundle; @@ -53,8 +52,8 @@ where { async fn meter_bundle(&self, bundle: Bundle) -> RpcResult { info!( - num_transactions = bundle.txs.len(), - block_number = bundle.block_number, + num_transactions = &bundle.txs.len(), + block_number = &bundle.block_number, "Starting bundle metering" ); @@ -77,26 +76,10 @@ where ) })?; - // Manually decode transactions to OpTxEnvelope (op-alloy 0.20) instead of using - // BundleWithMetadata.transactions() which returns op-alloy 0.21 types incompatible with reth. - // TODO: Remove this workaround after reth updates to op-alloy 0.21 (already on main, awaiting release) - let mut decoded_txs = Vec::new(); - for tx_bytes in &bundle.txs { - let mut reader = tx_bytes.as_ref(); - let tx = op_alloy_consensus::OpTxEnvelope::decode_2718(&mut reader).map_err(|e| { - jsonrpsee::types::ErrorObjectOwned::owned( - jsonrpsee::types::ErrorCode::InvalidParams.code(), - format!("Failed to decode transaction: {}", e), - None::<()>, - ) - })?; - decoded_txs.push(tx); - } - - let bundle_with_metadata = BundleWithMetadata::load(bundle.clone()).map_err(|e| { + let parsed_bundle = ParsedBundle::try_from(bundle).map_err(|e| { jsonrpsee::types::ErrorObjectOwned::owned( jsonrpsee::types::ErrorCode::InvalidParams.code(), - format!("Failed to load bundle metadata: {}", e), + format!("Failed to parse bundle: {}", e), None::<()>, ) })?; @@ -119,9 +102,8 @@ where meter_bundle( state_provider, self.provider.chain_spec().clone(), - decoded_txs, + parsed_bundle, &header, - &bundle_with_metadata, ) .map_err(|e| { error!(error = %e, "Bundle metering failed"); @@ -155,6 +137,7 @@ where gas_fees: total_gas_fees.to_string(), results, state_block_number: header.number, + state_flashblock_index: None, total_gas_used, total_execution_time_us: total_execution_time, }) diff --git a/crates/metering/src/tests/meter.rs b/crates/metering/src/tests/meter.rs index 571b022..0b10f44 100644 --- a/crates/metering/src/tests/meter.rs +++ b/crates/metering/src/tests/meter.rs @@ -17,7 +17,7 @@ use reth_primitives_traits::SealedHeader; use reth_provider::{HeaderProvider, StateProviderFactory, providers::BlockchainProvider}; use reth_testing_utils::generators::generate_keys; use reth_transaction_pool::test_utils::TransactionBuilder; -use tips_core::types::{Bundle, BundleWithMetadata}; +use tips_core::types::{Bundle, ParsedBundle}; use super::utils::create_provider_factory; use crate::meter_bundle; @@ -123,7 +123,7 @@ fn envelope_from_signed(tx: &OpTransactionSigned) -> eyre::Result Ok(tx.clone().into()) } -fn create_bundle_with_metadata(envelopes: Vec) -> eyre::Result { +fn create_parsed_bundle(envelopes: Vec) -> eyre::Result { let txs: Vec = envelopes .iter() .map(|env| Bytes::from(env.encoded_2718())) @@ -141,7 +141,7 @@ fn create_bundle_with_metadata(envelopes: Vec) -> eyre::Result eyre::Result<()> { .state_by_block_hash(harness.header.hash()) .context("getting state provider")?; - let bundle_with_metadata = create_bundle_with_metadata(Vec::new())?; + let parsed_bundle = create_parsed_bundle(Vec::new())?; let (results, total_gas_used, total_gas_fees, bundle_hash, total_execution_time) = meter_bundle( state_provider, harness.chain_spec.clone(), - Vec::new(), + parsed_bundle, &harness.header, - &bundle_with_metadata, )?; assert!(results.is_empty()); @@ -201,15 +200,14 @@ fn meter_bundle_single_transaction() -> eyre::Result<()> { .state_by_block_hash(harness.header.hash()) .context("getting state provider")?; - let bundle_with_metadata = create_bundle_with_metadata(vec![envelope.clone()])?; + let parsed_bundle = create_parsed_bundle(vec![envelope.clone()])?; let (results, total_gas_used, total_gas_fees, bundle_hash, total_execution_time) = meter_bundle( state_provider, harness.chain_spec.clone(), - vec![envelope], + parsed_bundle, &harness.header, - &bundle_with_metadata, )?; assert_eq!(results.len(), 1); @@ -296,16 +294,14 @@ fn meter_bundle_multiple_transactions() -> eyre::Result<()> { .state_by_block_hash(harness.header.hash()) .context("getting state provider")?; - let bundle_with_metadata = - create_bundle_with_metadata(vec![envelope_1.clone(), envelope_2.clone()])?; + let parsed_bundle = create_parsed_bundle(vec![envelope_1.clone(), envelope_2.clone()])?; let (results, total_gas_used, total_gas_fees, bundle_hash, total_execution_time) = meter_bundle( state_provider, harness.chain_spec.clone(), - vec![envelope_1, envelope_2], + parsed_bundle, &harness.header, - &bundle_with_metadata, )?; assert_eq!(results.len(), 2);