From 7d3dda14171b3973c7ab421943278fa09452aad0 Mon Sep 17 00:00:00 2001 From: William Law Date: Tue, 28 Oct 2025 11:53:10 -0400 Subject: [PATCH 1/5] spike --- Cargo.lock | 1 + crates/ingress-rpc/Cargo.toml | 1 + crates/ingress-rpc/src/service.rs | 60 ++++++++++++++++++++++++++++--- 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb461bd8..319f2e19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6919,6 +6919,7 @@ dependencies = [ "reth-optimism-evm", "reth-rpc-eth-types", "revm-context-interface", + "serde", "serde_json", "tips-audit", "tips-core", diff --git a/crates/ingress-rpc/Cargo.toml b/crates/ingress-rpc/Cargo.toml index 5df7ec6e..92ad844f 100644 --- a/crates/ingress-rpc/Cargo.toml +++ b/crates/ingress-rpc/Cargo.toml @@ -35,3 +35,4 @@ op-revm.workspace = true revm-context-interface.workspace = true alloy-signer-local.workspace = true reth-optimism-evm.workspace = true +serde.workspace = true diff --git a/crates/ingress-rpc/src/service.rs b/crates/ingress-rpc/src/service.rs index 3ea04081..d4b693b2 100644 --- a/crates/ingress-rpc/src/service.rs +++ b/crates/ingress-rpc/src/service.rs @@ -1,6 +1,6 @@ use alloy_consensus::transaction::Recovered; use alloy_consensus::{Transaction, transaction::SignerRecoverable}; -use alloy_primitives::{B256, Bytes}; +use alloy_primitives::{Address, B256, Bytes, TxHash}; use alloy_provider::{Provider, RootProvider, network::eip2718::Decodable2718}; use jsonrpsee::{ core::{RpcResult, async_trait}, @@ -9,6 +9,7 @@ use jsonrpsee::{ use op_alloy_consensus::OpTxEnvelope; use op_alloy_network::Optimism; use reth_rpc_eth_types::EthApiError; +use serde::{Deserialize, Serialize}; use std::time::{SystemTime, UNIX_EPOCH}; use tips_audit::{BundleEvent, BundleEventPublisher}; use tips_core::{Bundle, BundleHash, BundleWithMetadata, CancelBundle}; @@ -17,6 +18,38 @@ use tracing::{info, warn}; use crate::queue::QueuePublisher; use crate::validation::{AccountInfoLookup, L1BlockInfoLookup, validate_bundle, validate_tx}; +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TransactionResult { + pub coinbase_diff: String, + pub eth_sent_to_coinbase: String, + pub from_address: Address, + pub gas_fees: String, + pub gas_price: String, + pub gas_used: u64, + pub to_address: Option
, + pub tx_hash: TxHash, + pub value: String, + /// Resource metering: execution time for this tx in microseconds + pub execution_time_us: u128, +} + +/// Response for base_meterBundle +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct MeterBundleResponse { + pub bundle_gas_price: String, + pub bundle_hash: B256, + pub coinbase_diff: String, + pub eth_sent_to_coinbase: String, + pub gas_fees: String, + pub results: Vec, + pub state_block_number: u64, + pub total_gas_used: u64, + /// Resource metering: total execution time in microseconds + pub total_execution_time_us: u128, +} + #[rpc(server, namespace = "eth")] pub trait IngressApi { /// `eth_sendBundle` can be used to send your bundles to the builder. @@ -65,7 +98,8 @@ where Audit: BundleEventPublisher + Sync + Send + 'static, { async fn send_bundle(&self, bundle: Bundle) -> RpcResult { - let bundle_with_metadata = self.validate_bundle(bundle).await?; + let bundle_with_metadata = self.validate_bundle(&bundle).await?; + self.meter_bundle(&bundle).await?; let bundle_hash = bundle_with_metadata.bundle_hash(); if let Err(e) = self @@ -117,6 +151,7 @@ where reverting_tx_hashes: vec![transaction.tx_hash()], ..Default::default() }; + self.meter_bundle(&bundle).await?; let bundle_with_metadata = BundleWithMetadata::load(bundle) .map_err(|e| EthApiError::InvalidParams(e.to_string()).into_rpc_err())?; @@ -191,7 +226,7 @@ where Ok(transaction) } - async fn validate_bundle(&self, bundle: Bundle) -> RpcResult { + async fn validate_bundle(&self, bundle: &Bundle) -> RpcResult { if bundle.txs.is_empty() { return Err( EthApiError::InvalidParams("Bundle cannot have empty transactions".into()) @@ -208,8 +243,25 @@ where let transaction = self.validate_tx(tx_data).await?; total_gas = total_gas.saturating_add(transaction.gas_limit()); } - validate_bundle(&bundle, total_gas, tx_hashes)?; + validate_bundle(bundle, total_gas, tx_hashes)?; Ok(bundle_with_metadata) } + + async fn meter_bundle(&self, bundle: &Bundle) -> RpcResult<()> { + let res: MeterBundleResponse = self + .provider + .client() + .request("base_meterBundle", (bundle,)) + .await + .map_err(|e| EthApiError::InvalidParams(e.to_string()).into_rpc_err())?; + + // if simulation takes longer than 2s, we don't include and just error to user + if res.total_execution_time_us > 2000000 { + return Err( + EthApiError::InvalidParams("Bundle simulation took too long".into()).into_rpc_err(), + ); + } + Ok(()) + } } From 595d857d01d33c1ffb05a439ca3d0ce5e0f00206 Mon Sep 17 00:00:00 2001 From: William Law Date: Tue, 28 Oct 2025 14:09:46 -0400 Subject: [PATCH 2/5] use tips-core --- Cargo.lock | 1 - crates/core/src/lib.rs | 2 +- crates/ingress-rpc/Cargo.toml | 1 - crates/ingress-rpc/src/service.rs | 37 ++----------------------------- 4 files changed, 3 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 319f2e19..bb461bd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6919,7 +6919,6 @@ dependencies = [ "reth-optimism-evm", "reth-rpc-eth-types", "revm-context-interface", - "serde", "serde_json", "tips-audit", "tips-core", diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index 0b019008..d36e46f7 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -5,4 +5,4 @@ pub mod types; #[cfg(any(test, feature = "test-utils"))] pub mod test_utils; -pub use types::{Bundle, BundleHash, BundleWithMetadata, CancelBundle}; +pub use types::{Bundle, BundleHash, BundleWithMetadata, CancelBundle, MeterBundleResponse}; diff --git a/crates/ingress-rpc/Cargo.toml b/crates/ingress-rpc/Cargo.toml index 92ad844f..5df7ec6e 100644 --- a/crates/ingress-rpc/Cargo.toml +++ b/crates/ingress-rpc/Cargo.toml @@ -35,4 +35,3 @@ op-revm.workspace = true revm-context-interface.workspace = true alloy-signer-local.workspace = true reth-optimism-evm.workspace = true -serde.workspace = true diff --git a/crates/ingress-rpc/src/service.rs b/crates/ingress-rpc/src/service.rs index d4b693b2..e6434226 100644 --- a/crates/ingress-rpc/src/service.rs +++ b/crates/ingress-rpc/src/service.rs @@ -1,6 +1,6 @@ use alloy_consensus::transaction::Recovered; use alloy_consensus::{Transaction, transaction::SignerRecoverable}; -use alloy_primitives::{Address, B256, Bytes, TxHash}; +use alloy_primitives::{B256, Bytes}; use alloy_provider::{Provider, RootProvider, network::eip2718::Decodable2718}; use jsonrpsee::{ core::{RpcResult, async_trait}, @@ -9,47 +9,14 @@ use jsonrpsee::{ use op_alloy_consensus::OpTxEnvelope; use op_alloy_network::Optimism; use reth_rpc_eth_types::EthApiError; -use serde::{Deserialize, Serialize}; use std::time::{SystemTime, UNIX_EPOCH}; use tips_audit::{BundleEvent, BundleEventPublisher}; -use tips_core::{Bundle, BundleHash, BundleWithMetadata, CancelBundle}; +use tips_core::{Bundle, BundleHash, BundleWithMetadata, CancelBundle, MeterBundleResponse}; use tracing::{info, warn}; use crate::queue::QueuePublisher; use crate::validation::{AccountInfoLookup, L1BlockInfoLookup, validate_bundle, validate_tx}; -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct TransactionResult { - pub coinbase_diff: String, - pub eth_sent_to_coinbase: String, - pub from_address: Address, - pub gas_fees: String, - pub gas_price: String, - pub gas_used: u64, - pub to_address: Option
, - pub tx_hash: TxHash, - pub value: String, - /// Resource metering: execution time for this tx in microseconds - pub execution_time_us: u128, -} - -/// Response for base_meterBundle -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct MeterBundleResponse { - pub bundle_gas_price: String, - pub bundle_hash: B256, - pub coinbase_diff: String, - pub eth_sent_to_coinbase: String, - pub gas_fees: String, - pub results: Vec, - pub state_block_number: u64, - pub total_gas_used: u64, - /// Resource metering: total execution time in microseconds - pub total_execution_time_us: u128, -} - #[rpc(server, namespace = "eth")] pub trait IngressApi { /// `eth_sendBundle` can be used to send your bundles to the builder. From 9879c928ad18d954baa0ac20e744f0c10197e949 Mon Sep 17 00:00:00 2001 From: William Law Date: Thu, 30 Oct 2025 10:21:21 -0400 Subject: [PATCH 3/5] comments + add meterbundleres to bundlewmetadata --- crates/core/src/lib.rs | 4 +++- crates/core/src/types.rs | 9 +++++++++ crates/ingress-rpc/src/service.rs | 25 ++++++++++++++++--------- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index d36e46f7..5b7906cd 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -5,4 +5,6 @@ pub mod types; #[cfg(any(test, feature = "test-utils"))] pub mod test_utils; -pub use types::{Bundle, BundleHash, BundleWithMetadata, CancelBundle, MeterBundleResponse}; +pub use types::{ + BLOCK_TIME, Bundle, BundleHash, BundleWithMetadata, CancelBundle, MeterBundleResponse, +}; diff --git a/crates/core/src/types.rs b/crates/core/src/types.rs index f79a5ab0..9f2637aa 100644 --- a/crates/core/src/types.rs +++ b/crates/core/src/types.rs @@ -7,6 +7,9 @@ use op_alloy_flz::tx_estimated_size_fjord_bytes; use serde::{Deserialize, Serialize}; use uuid::Uuid; +/// Block time in microseconds +pub const BLOCK_TIME: u128 = 2_000_000; + #[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct Bundle { @@ -70,6 +73,7 @@ pub struct BundleWithMetadata { bundle: Bundle, uuid: Uuid, transactions: Vec, + meter_bundle_response: Option, } impl BundleWithMetadata { @@ -96,6 +100,7 @@ impl BundleWithMetadata { bundle, transactions, uuid, + meter_bundle_response: None, }) } @@ -140,6 +145,10 @@ impl BundleWithMetadata { .map(|t| tx_estimated_size_fjord_bytes(&t.encoded_2718())) .sum() } + + pub fn set_meter_bundle_response(&mut self, meter_bundle_response: MeterBundleResponse) { + self.meter_bundle_response = Some(meter_bundle_response); + } } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/crates/ingress-rpc/src/service.rs b/crates/ingress-rpc/src/service.rs index e6434226..e942ba79 100644 --- a/crates/ingress-rpc/src/service.rs +++ b/crates/ingress-rpc/src/service.rs @@ -11,7 +11,9 @@ use op_alloy_network::Optimism; use reth_rpc_eth_types::EthApiError; use std::time::{SystemTime, UNIX_EPOCH}; use tips_audit::{BundleEvent, BundleEventPublisher}; -use tips_core::{Bundle, BundleHash, BundleWithMetadata, CancelBundle, MeterBundleResponse}; +use tips_core::{ + BLOCK_TIME, Bundle, BundleHash, BundleWithMetadata, CancelBundle, MeterBundleResponse, +}; use tracing::{info, warn}; use crate::queue::QueuePublisher; @@ -65,8 +67,8 @@ where Audit: BundleEventPublisher + Sync + Send + 'static, { async fn send_bundle(&self, bundle: Bundle) -> RpcResult { - let bundle_with_metadata = self.validate_bundle(&bundle).await?; - self.meter_bundle(&bundle).await?; + let mut bundle_with_metadata = self.validate_bundle(&bundle).await?; + bundle_with_metadata.set_meter_bundle_response(self.meter_bundle(&bundle).await?); let bundle_hash = bundle_with_metadata.bundle_hash(); if let Err(e) = self @@ -118,10 +120,11 @@ where reverting_tx_hashes: vec![transaction.tx_hash()], ..Default::default() }; - self.meter_bundle(&bundle).await?; + let meter_bundle_response = self.meter_bundle(&bundle).await?; - let bundle_with_metadata = BundleWithMetadata::load(bundle) + let mut bundle_with_metadata = BundleWithMetadata::load(bundle) .map_err(|e| EthApiError::InvalidParams(e.to_string()).into_rpc_err())?; + bundle_with_metadata.set_meter_bundle_response(meter_bundle_response); let bundle_hash = bundle_with_metadata.bundle_hash(); if let Err(e) = self @@ -215,7 +218,10 @@ where Ok(bundle_with_metadata) } - async fn meter_bundle(&self, bundle: &Bundle) -> RpcResult<()> { + /// `meter_bundle` is used to determine how long a bundle will take to execute. A bundle that + /// is within `BLOCK_TIME` will return the `MeterBundleResponse` that can be passed along + /// to the builder. + async fn meter_bundle(&self, bundle: &Bundle) -> RpcResult { let res: MeterBundleResponse = self .provider .client() @@ -223,12 +229,13 @@ where .await .map_err(|e| EthApiError::InvalidParams(e.to_string()).into_rpc_err())?; - // if simulation takes longer than 2s, we don't include and just error to user - if res.total_execution_time_us > 2000000 { + // we can save some builder payload building computation by not including bundles + // that we know will take longer than the block time to execute + if res.total_execution_time_us > BLOCK_TIME { return Err( EthApiError::InvalidParams("Bundle simulation took too long".into()).into_rpc_err(), ); } - Ok(()) + Ok(res) } } From 6027a50227320f7c1e562ee4cac0b06f53d05f39 Mon Sep 17 00:00:00 2001 From: William Law Date: Thu, 30 Oct 2025 16:16:54 -0400 Subject: [PATCH 4/5] make meter_response not optional --- crates/core/src/test_utils.rs | 5 ++- crates/core/src/types.rs | 61 +++++++++++++++++++++---------- crates/ingress-rpc/src/queue.rs | 5 ++- crates/ingress-rpc/src/service.rs | 19 +++++----- 4 files changed, 57 insertions(+), 33 deletions(-) diff --git a/crates/core/src/test_utils.rs b/crates/core/src/test_utils.rs index a5763548..3763c073 100644 --- a/crates/core/src/test_utils.rs +++ b/crates/core/src/test_utils.rs @@ -1,4 +1,4 @@ -use crate::{Bundle, BundleWithMetadata}; +use crate::{Bundle, BundleWithMetadata, MeterBundleResponse}; use alloy_consensus::SignableTransaction; use alloy_primitives::{Address, U256}; use alloy_provider::network::TxSignerSync; @@ -38,6 +38,7 @@ pub fn create_test_bundle( max_timestamp, ..Default::default() }; + let meter_bundle_response = MeterBundleResponse::default(); - BundleWithMetadata::load(bundle).unwrap() + BundleWithMetadata::load(bundle, meter_bundle_response).unwrap() } diff --git a/crates/core/src/types.rs b/crates/core/src/types.rs index 9f2637aa..4af63b74 100644 --- a/crates/core/src/types.rs +++ b/crates/core/src/types.rs @@ -73,11 +73,14 @@ pub struct BundleWithMetadata { bundle: Bundle, uuid: Uuid, transactions: Vec, - meter_bundle_response: Option, + meter_bundle_response: MeterBundleResponse, } impl BundleWithMetadata { - pub fn load(mut bundle: Bundle) -> Result { + pub fn load( + mut bundle: Bundle, + meter_bundle_response: MeterBundleResponse, + ) -> Result { let uuid = bundle .replacement_uuid .clone() @@ -100,7 +103,7 @@ impl BundleWithMetadata { bundle, transactions, uuid, - meter_bundle_response: None, + meter_bundle_response, }) } @@ -145,10 +148,6 @@ impl BundleWithMetadata { .map(|t| tx_estimated_size_fjord_bytes(&t.encoded_2718())) .sum() } - - pub fn set_meter_bundle_response(&mut self, meter_bundle_response: MeterBundleResponse) { - self.meter_bundle_response = Some(meter_bundle_response); - } } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -187,6 +186,24 @@ pub struct MeterBundleResponse { pub state_root_time_us: u128, } +impl Default for MeterBundleResponse { + fn default() -> Self { + Self { + bundle_gas_price: "0".to_string(), + bundle_hash: B256::default(), + coinbase_diff: "0".to_string(), + eth_sent_to_coinbase: "0".to_string(), + gas_fees: "0".to_string(), + results: vec![], + state_block_number: 0, + state_flashblock_index: None, + total_gas_used: 0, + total_execution_time_us: 0, + state_root_time_us: 0, + } + } +} + #[cfg(test)] mod tests { use super::*; @@ -206,12 +223,15 @@ mod tests { let tx1_bytes = tx1.encoded_2718(); let tx2_bytes = tx2.encoded_2718(); - let bundle = BundleWithMetadata::load(Bundle { - replacement_uuid: None, - txs: vec![tx1_bytes.clone().into()], - block_number: 1, - ..Default::default() - }) + let bundle = BundleWithMetadata::load( + Bundle { + replacement_uuid: None, + txs: vec![tx1_bytes.clone().into()], + block_number: 1, + ..Default::default() + }, + MeterBundleResponse::default(), + ) .unwrap(); assert!(!bundle.uuid().is_nil()); @@ -234,12 +254,15 @@ mod tests { assert_eq!(bundle.bundle_hash(), expected_bundle_hash_single); let uuid = Uuid::new_v4(); - let bundle = BundleWithMetadata::load(Bundle { - replacement_uuid: Some(uuid.to_string()), - txs: vec![tx1_bytes.clone().into(), tx2_bytes.clone().into()], - block_number: 1, - ..Default::default() - }) + let bundle = BundleWithMetadata::load( + Bundle { + replacement_uuid: Some(uuid.to_string()), + txs: vec![tx1_bytes.clone().into(), tx2_bytes.clone().into()], + block_number: 1, + ..Default::default() + }, + MeterBundleResponse::default(), + ) .unwrap(); assert_eq!(*bundle.uuid(), uuid); diff --git a/crates/ingress-rpc/src/queue.rs b/crates/ingress-rpc/src/queue.rs index 28a70932..147586bd 100644 --- a/crates/ingress-rpc/src/queue.rs +++ b/crates/ingress-rpc/src/queue.rs @@ -75,7 +75,7 @@ impl QueuePublisher for KafkaQueuePublisher { mod tests { use super::*; use rdkafka::config::ClientConfig; - use tips_core::{Bundle, BundleWithMetadata}; + use tips_core::{Bundle, BundleWithMetadata, MeterBundleResponse}; use tokio::time::{Duration, Instant}; fn create_test_bundle() -> Bundle { @@ -93,7 +93,8 @@ mod tests { let publisher = KafkaQueuePublisher::new(producer, "tips-ingress-rpc".to_string()); let bundle = create_test_bundle(); - let bundle_with_metadata = BundleWithMetadata::load(bundle.clone()).unwrap(); + let bundle_with_metadata = + BundleWithMetadata::load(bundle.clone(), MeterBundleResponse::default()).unwrap(); let bundle_hash = bundle_with_metadata.bundle_hash(); let start = Instant::now(); diff --git a/crates/ingress-rpc/src/service.rs b/crates/ingress-rpc/src/service.rs index e942ba79..db38b867 100644 --- a/crates/ingress-rpc/src/service.rs +++ b/crates/ingress-rpc/src/service.rs @@ -67,8 +67,10 @@ where Audit: BundleEventPublisher + Sync + Send + 'static, { async fn send_bundle(&self, bundle: Bundle) -> RpcResult { - let mut bundle_with_metadata = self.validate_bundle(&bundle).await?; - bundle_with_metadata.set_meter_bundle_response(self.meter_bundle(&bundle).await?); + self.validate_bundle(&bundle).await?; + let meter_bundle_response = self.meter_bundle(&bundle).await?; + let bundle_with_metadata = BundleWithMetadata::load(bundle, meter_bundle_response) + .map_err(|e| EthApiError::InvalidParams(e.to_string()).into_rpc_err())?; let bundle_hash = bundle_with_metadata.bundle_hash(); if let Err(e) = self @@ -122,9 +124,8 @@ where }; let meter_bundle_response = self.meter_bundle(&bundle).await?; - let mut bundle_with_metadata = BundleWithMetadata::load(bundle) + let bundle_with_metadata = BundleWithMetadata::load(bundle, meter_bundle_response) .map_err(|e| EthApiError::InvalidParams(e.to_string()).into_rpc_err())?; - bundle_with_metadata.set_meter_bundle_response(meter_bundle_response); let bundle_hash = bundle_with_metadata.bundle_hash(); if let Err(e) = self @@ -196,7 +197,7 @@ where Ok(transaction) } - async fn validate_bundle(&self, bundle: &Bundle) -> RpcResult { + async fn validate_bundle(&self, bundle: &Bundle) -> RpcResult<()> { if bundle.txs.is_empty() { return Err( EthApiError::InvalidParams("Bundle cannot have empty transactions".into()) @@ -204,18 +205,16 @@ where ); } - let bundle_with_metadata = BundleWithMetadata::load(bundle.clone()) - .map_err(|e| EthApiError::InvalidParams(e.to_string()).into_rpc_err())?; - let tx_hashes = bundle_with_metadata.txn_hashes(); - let mut total_gas = 0u64; + let mut tx_hashes = Vec::new(); for tx_data in &bundle.txs { let transaction = self.validate_tx(tx_data).await?; total_gas = total_gas.saturating_add(transaction.gas_limit()); + tx_hashes.push(transaction.tx_hash()); } validate_bundle(bundle, total_gas, tx_hashes)?; - Ok(bundle_with_metadata) + Ok(()) } /// `meter_bundle` is used to determine how long a bundle will take to execute. A bundle that From 2a76ce36a09ab742ab62eb116d4201bbea0630e6 Mon Sep 17 00:00:00 2001 From: William Law Date: Thu, 30 Oct 2025 16:45:55 -0400 Subject: [PATCH 5/5] make it a fn not default --- crates/core/src/test_utils.rs | 20 ++++++++++++++++++-- crates/core/src/types.rs | 24 +++--------------------- crates/ingress-rpc/src/queue.rs | 4 ++-- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/crates/core/src/test_utils.rs b/crates/core/src/test_utils.rs index 3763c073..cb2c5ee6 100644 --- a/crates/core/src/test_utils.rs +++ b/crates/core/src/test_utils.rs @@ -1,6 +1,6 @@ use crate::{Bundle, BundleWithMetadata, MeterBundleResponse}; use alloy_consensus::SignableTransaction; -use alloy_primitives::{Address, U256}; +use alloy_primitives::{Address, B256, U256}; use alloy_provider::network::TxSignerSync; use alloy_provider::network::eip2718::Encodable2718; use alloy_signer_local::PrivateKeySigner; @@ -38,7 +38,23 @@ pub fn create_test_bundle( max_timestamp, ..Default::default() }; - let meter_bundle_response = MeterBundleResponse::default(); + let meter_bundle_response = create_test_meter_bundle_response(); BundleWithMetadata::load(bundle, meter_bundle_response).unwrap() } + +pub fn create_test_meter_bundle_response() -> MeterBundleResponse { + MeterBundleResponse { + bundle_gas_price: "0".to_string(), + bundle_hash: B256::default(), + coinbase_diff: "0".to_string(), + eth_sent_to_coinbase: "0".to_string(), + gas_fees: "0".to_string(), + results: vec![], + state_block_number: 0, + state_flashblock_index: None, + total_gas_used: 0, + total_execution_time_us: 0, + state_root_time_us: 0, + } +} diff --git a/crates/core/src/types.rs b/crates/core/src/types.rs index 4af63b74..97ca1684 100644 --- a/crates/core/src/types.rs +++ b/crates/core/src/types.rs @@ -186,28 +186,10 @@ pub struct MeterBundleResponse { pub state_root_time_us: u128, } -impl Default for MeterBundleResponse { - fn default() -> Self { - Self { - bundle_gas_price: "0".to_string(), - bundle_hash: B256::default(), - coinbase_diff: "0".to_string(), - eth_sent_to_coinbase: "0".to_string(), - gas_fees: "0".to_string(), - results: vec![], - state_block_number: 0, - state_flashblock_index: None, - total_gas_used: 0, - total_execution_time_us: 0, - state_root_time_us: 0, - } - } -} - #[cfg(test)] mod tests { use super::*; - use crate::test_utils::create_transaction; + use crate::test_utils::{create_test_meter_bundle_response, create_transaction}; use alloy_primitives::Keccak256; use alloy_provider::network::eip2718::Encodable2718; use alloy_signer_local::PrivateKeySigner; @@ -230,7 +212,7 @@ mod tests { block_number: 1, ..Default::default() }, - MeterBundleResponse::default(), + create_test_meter_bundle_response(), ) .unwrap(); @@ -261,7 +243,7 @@ mod tests { block_number: 1, ..Default::default() }, - MeterBundleResponse::default(), + create_test_meter_bundle_response(), ) .unwrap(); diff --git a/crates/ingress-rpc/src/queue.rs b/crates/ingress-rpc/src/queue.rs index 147586bd..0f605208 100644 --- a/crates/ingress-rpc/src/queue.rs +++ b/crates/ingress-rpc/src/queue.rs @@ -75,7 +75,7 @@ impl QueuePublisher for KafkaQueuePublisher { mod tests { use super::*; use rdkafka::config::ClientConfig; - use tips_core::{Bundle, BundleWithMetadata, MeterBundleResponse}; + use tips_core::{Bundle, BundleWithMetadata, test_utils::create_test_meter_bundle_response}; use tokio::time::{Duration, Instant}; fn create_test_bundle() -> Bundle { @@ -94,7 +94,7 @@ mod tests { let publisher = KafkaQueuePublisher::new(producer, "tips-ingress-rpc".to_string()); let bundle = create_test_bundle(); let bundle_with_metadata = - BundleWithMetadata::load(bundle.clone(), MeterBundleResponse::default()).unwrap(); + BundleWithMetadata::load(bundle.clone(), create_test_meter_bundle_response()).unwrap(); let bundle_hash = bundle_with_metadata.bundle_hash(); let start = Instant::now();