From c5adf2dd074db0ca6b7b007d04e74130c2507ecd Mon Sep 17 00:00:00 2001 From: dancoombs Date: Tue, 24 Sep 2024 14:50:04 -0500 Subject: [PATCH] feat(pool): update pool to use alloy types --- Cargo.lock | 4 +- crates/pool/Cargo.toml | 5 +- crates/pool/proto/op_pool/op_pool.proto | 8 +- crates/pool/src/chain.rs | 611 ++++++++++-------- crates/pool/src/emit.rs | 10 +- crates/pool/src/mempool/mod.rs | 24 +- crates/pool/src/mempool/paymaster.rs | 137 ++-- crates/pool/src/mempool/pool.rs | 94 ++- crates/pool/src/mempool/reputation.rs | 2 +- crates/pool/src/mempool/uo_pool.rs | 138 ++-- crates/pool/src/server/local.rs | 34 +- crates/pool/src/server/remote/client.rs | 44 +- crates/pool/src/server/remote/error.rs | 23 +- crates/pool/src/server/remote/protos.rs | 16 +- crates/pool/src/server/remote/server.rs | 15 +- crates/pool/src/task.rs | 85 +-- .../src/alloy/entry_point/optimism.rs | 4 +- crates/provider/src/alloy/entry_point/v0_6.rs | 18 +- crates/provider/src/alloy/entry_point/v0_7.rs | 10 +- crates/sim/src/simulation/v0_6/context.rs | 3 +- crates/types/src/validation_results.rs | 12 +- 21 files changed, 702 insertions(+), 595 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c9a47818..6bb63e05a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5138,10 +5138,11 @@ dependencies = [ name = "rundler-pool" version = "0.3.0" dependencies = [ + "alloy-primitives", + "alloy-sol-types", "anyhow", "async-stream", "async-trait", - "ethers", "futures", "futures-util", "itertools 0.13.0", @@ -5149,6 +5150,7 @@ dependencies = [ "mockall", "parking_lot", "prost", + "rundler-contracts", "rundler-provider", "rundler-sim", "rundler-task", diff --git a/crates/pool/Cargo.toml b/crates/pool/Cargo.toml index 7109de005..629545930 100644 --- a/crates/pool/Cargo.toml +++ b/crates/pool/Cargo.toml @@ -8,16 +8,19 @@ repository.workspace = true publish = false [dependencies] +rundler-contracts = { path = "../contracts" } rundler-provider = { path = "../provider" } rundler-sim = { path = "../sim" } rundler-task = { path = "../task" } rundler-types = { path = "../types" } rundler-utils = { path = "../utils" } +alloy-primitives.workspace = true +alloy-sol-types.workspace = true + anyhow.workspace = true async-stream = "0.3.5" async-trait.workspace = true -ethers.workspace = true futures.workspace = true futures-util.workspace = true itertools.workspace = true diff --git a/crates/pool/proto/op_pool/op_pool.proto b/crates/pool/proto/op_pool/op_pool.proto index 32d1dfa54..c07c74c3b 100644 --- a/crates/pool/proto/op_pool/op_pool.proto +++ b/crates/pool/proto/op_pool/op_pool.proto @@ -302,7 +302,7 @@ message GetStakeStatusSuccess { } message StakeInfo { - uint64 stake = 1; + bytes stake = 1; uint32 unstake_delay_sec= 2; } @@ -708,7 +708,7 @@ message NotStaked { bytes accessed_address = 4; bytes slot = 5; bytes min_stake = 6; - bytes min_unstake_delay = 7; + uint32 min_unstake_delay = 7; } message UnintendedRevert { @@ -752,6 +752,7 @@ message ValidationRevert { EntryPointRevert entry_point = 1; OperationRevert operation = 2; UnknownRevert unknown = 3; + PanicRevert panic = 4; } } message EntryPointRevert { @@ -765,6 +766,9 @@ message OperationRevert { message UnknownRevert { bytes revert_bytes = 1; } +message PanicRevert { + bytes code = 1; +} message AccessedUnsupportedContractType { string contract_type = 1; diff --git a/crates/pool/src/chain.rs b/crates/pool/src/chain.rs index e570ee59e..f9f9d0046 100644 --- a/crates/pool/src/chain.rs +++ b/crates/pool/src/chain.rs @@ -17,23 +17,26 @@ use std::{ time::Duration, }; +use alloy_primitives::{Address, B256, U256}; +use alloy_sol_types::SolEvent; use anyhow::{ensure, Context}; -use ethers::{ - contract::EthLogDecode, - prelude::EthEvent, - types::{Address, Block, Filter, Log, H256, U256}, -}; use futures::future; -use rundler_provider::Provider; -use rundler_task::block_watcher; -use rundler_types::{ - contracts::{v0_6::i_entry_point as entry_point_v0_6, v0_7::i_entry_point as entry_point_v0_7}, - EntryPointVersion, Timestamp, UserOperationId, +use rundler_contracts::{ + v0_6::IEntryPoint::{ + Deposited as DepositedV06, UserOperationEvent as UserOperationEventV06, + Withdrawn as WithdrawnV06, + }, + v0_7::IEntryPoint::{ + Deposited as DepositedV07, UserOperationEvent as UserOperationEventV07, + Withdrawn as WithdrawnV07, + }, }; +use rundler_provider::{Block, EvmProvider, Filter, Log}; +use rundler_task::block_watcher; +use rundler_types::{EntryPointVersion, Timestamp, UserOperationId}; use tokio::{ select, sync::{broadcast, Semaphore}, - task::JoinHandle, time, }; use tokio_util::sync::CancellationToken; @@ -47,8 +50,8 @@ const MAX_LOAD_OPS_CONCURRENCY: usize = 64; /// Will update itself when `.sync_to_block_number` is called, at which point it /// will query a node to determine the new state of the chain. #[derive(Debug)] -pub(crate) struct Chain { - provider: Arc

, +pub(crate) struct Chain { + provider: P, settings: Settings, /// Blocks are stored from earliest to latest, so the oldest block is at the /// front of this deque and the newest at the back. @@ -62,7 +65,7 @@ pub(crate) struct Chain { #[derive(Default, Debug, Eq, PartialEq)] pub struct ChainUpdate { pub latest_block_number: u64, - pub latest_block_hash: H256, + pub latest_block_hash: B256, pub latest_block_timestamp: Timestamp, /// Blocks before this number are no longer tracked in this `Chain`, so no /// further updates related to them will be sent. @@ -81,7 +84,7 @@ pub struct ChainUpdate { #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct MinedOp { - pub hash: H256, + pub hash: B256, pub entry_point: Address, pub sender: Address, pub nonce: U256, @@ -117,15 +120,15 @@ pub(crate) struct Settings { #[derive(Debug)] struct BlockSummary { number: u64, - hash: H256, + hash: B256, timestamp: Timestamp, - parent_hash: H256, + parent_hash: B256, ops: Vec, entity_balance_updates: Vec, } -impl Chain

{ - pub(crate) fn new(provider: Arc

, settings: Settings) -> Self { +impl Chain

{ + pub(crate) fn new(provider: P, settings: Settings) -> Self { let history_size = settings.history_size as usize; assert!(history_size > 0, "history size should be positive"); @@ -136,18 +139,18 @@ impl Chain

{ .values() .any(|v| *v == EntryPointVersion::V0_6) { - events.push(entry_point_v0_6::UserOperationEventFilter::abi_signature()); - events.push(entry_point_v0_6::DepositedFilter::abi_signature()); - events.push(entry_point_v0_6::WithdrawnFilter::abi_signature()); + events.push(UserOperationEventV06::SIGNATURE_HASH); + events.push(DepositedV06::SIGNATURE_HASH); + events.push(WithdrawnV06::SIGNATURE_HASH); } if settings .entry_point_addresses .values() .any(|v| *v == EntryPointVersion::V0_7) { - events.push(entry_point_v0_7::UserOperationEventFilter::abi_signature()); - events.push(entry_point_v0_7::DepositedFilter::abi_signature()); - events.push(entry_point_v0_7::WithdrawnFilter::abi_signature()); + events.push(UserOperationEventV07::SIGNATURE_HASH); + events.push(DepositedV07::SIGNATURE_HASH); + events.push(WithdrawnV07::SIGNATURE_HASH); } let filter_template = Filter::new() @@ -158,7 +161,7 @@ impl Chain

{ .cloned() .collect::>(), ) - .events(events.iter().map(|e| e.as_ref())); + .events(events.iter()); Self { provider, @@ -169,24 +172,22 @@ impl Chain

{ } } - pub(crate) fn spawn_watcher( + pub(crate) async fn watch( mut self, sender: broadcast::Sender>, shutdown_token: CancellationToken, - ) -> JoinHandle<()> { - tokio::spawn(async move { - loop { - select! { - update = self.wait_for_update() => { - let _ = sender.send(Arc::new(update)); - } - _ = shutdown_token.cancelled() => { - info!("Shutting down chain watcher"); - break; - } + ) { + loop { + select! { + update = self.wait_for_update() => { + let _ = sender.send(Arc::new(update)); + } + _ = shutdown_token.cancelled() => { + info!("Shutting down chain watcher"); + break; } } - }) + } } async fn wait_for_update(&mut self) -> ChainUpdate { @@ -197,7 +198,7 @@ impl Chain

{ .unwrap_or_default(); loop { let (hash, block) = block_watcher::wait_for_new_block( - &*self.provider, + &self.provider, block_hash, self.settings.poll_interval, ) @@ -228,10 +229,7 @@ impl Chain

{ } } - pub(crate) async fn sync_to_block( - &mut self, - new_head: Block, - ) -> anyhow::Result { + pub(crate) async fn sync_to_block(&mut self, new_head: Block) -> anyhow::Result { let new_head = BlockSummary::try_from_block_without_ops(new_head, None)?; let Some(current_block) = self.blocks.back() else { return self.reset_and_initialize(new_head).await; @@ -381,7 +379,7 @@ impl Chain

{ // chain, until it does. let block = self .provider - .get_block(earliest_new_block.parent_hash) + .get_block(earliest_new_block.parent_hash.into()) .await .context("should load parent block when handling reorg")? .context("block with parent hash of known block should exist")?; @@ -408,7 +406,7 @@ impl Chain

{ let parent_hash = blocks[0].parent_hash; let parent = self .provider - .get_block(parent_hash) + .get_block(parent_hash.into()) .await .context("should load parent block by hash")? .context("block with parent hash of known block should exist")?; @@ -443,7 +441,7 @@ impl Chain

{ async fn load_ops_in_block_with_hash( &self, - block_hash: H256, + block_hash: B256, ) -> anyhow::Result<(Vec, Vec)> { let _permit = self .load_ops_semaphore @@ -461,7 +459,7 @@ impl Chain

{ let mut mined_ops = vec![]; let mut entity_balance_updates = vec![]; for log in logs { - match self.settings.entry_point_addresses.get(&log.address) { + match self.settings.entry_point_addresses.get(&log.address()) { Some(EntryPointVersion::V0_6) => { Self::load_v0_6(log, &mut mined_ops, &mut entity_balance_updates) } @@ -471,7 +469,7 @@ impl Chain

{ Some(EntryPointVersion::Unspecified) | None => { warn!( "Log with unknown entry point address: {:?}. Ignoring.", - log.address + log.address() ); } } @@ -481,87 +479,125 @@ impl Chain

{ } fn load_v0_6(log: Log, mined_ops: &mut Vec, balance_updates: &mut Vec) { - let address = log.address; - if let Ok(event) = entry_point_v0_6::IEntryPointEvents::decode_log(&log.into()) { - match event { - entry_point_v0_6::IEntryPointEvents::UserOperationEventFilter(event) => { - let paymaster = if event.paymaster.is_zero() { - None - } else { - Some(event.paymaster) - }; - let mined = MinedOp { - hash: event.user_op_hash.into(), - entry_point: address, - sender: event.sender, - nonce: event.nonce, - actual_gas_cost: event.actual_gas_cost, - paymaster, - }; - mined_ops.push(mined); - } - entry_point_v0_6::IEntryPointEvents::DepositedFilter(event) => { - let info = BalanceUpdate { - entrypoint: address, - address: event.account, - amount: event.total_deposit, - is_addition: true, - }; - balance_updates.push(info); - } - entry_point_v0_6::IEntryPointEvents::WithdrawnFilter(event) => { - let info = BalanceUpdate { - entrypoint: address, - address: event.account, - amount: event.amount, - is_addition: false, - }; - balance_updates.push(info); - } - _ => {} + let address = log.address(); + + match log.topic0() { + Some(&UserOperationEventV06::SIGNATURE_HASH) => { + let Ok(decoded) = log.log_decode::() else { + warn!("Failed to decode v0.6 UserOperationEvent: {:?}", log); + return; + }; + let event = decoded.data(); + + let paymaster = if event.paymaster.is_zero() { + None + } else { + Some(event.paymaster) + }; + let mined = MinedOp { + hash: event.userOpHash, + entry_point: address, + sender: event.sender, + nonce: event.nonce, + actual_gas_cost: event.actualGasCost, + paymaster, + }; + mined_ops.push(mined); + } + Some(&DepositedV06::SIGNATURE_HASH) => { + let Ok(decoded) = log.log_decode::() else { + warn!("Failed to decode v0.6 Deposited: {:?}", log); + return; + }; + let event = decoded.data(); + + let info = BalanceUpdate { + entrypoint: address, + address: event.account, + amount: event.totalDeposit, + is_addition: true, + }; + balance_updates.push(info); + } + Some(&WithdrawnV06::SIGNATURE_HASH) => { + let Ok(decoded) = log.log_decode::() else { + warn!("Failed to decode v0.6 Withdrawn: {:?}", log); + return; + }; + let event = decoded.data(); + + let info = BalanceUpdate { + entrypoint: address, + address: event.account, + amount: event.amount, + is_addition: false, + }; + balance_updates.push(info); + } + _ => { + warn!("Unknown event signature: {:?}", log.topic0()); } } } fn load_v0_7(log: Log, mined_ops: &mut Vec, balance_updates: &mut Vec) { - let address = log.address; - if let Ok(event) = entry_point_v0_7::IEntryPointEvents::decode_log(&log.into()) { - match event { - entry_point_v0_7::IEntryPointEvents::UserOperationEventFilter(event) => { - let paymaster = if event.paymaster.is_zero() { - None - } else { - Some(event.paymaster) - }; - let mined = MinedOp { - hash: event.user_op_hash.into(), - entry_point: address, - sender: event.sender, - nonce: event.nonce, - actual_gas_cost: event.actual_gas_cost, - paymaster, - }; - mined_ops.push(mined); - } - entry_point_v0_7::IEntryPointEvents::DepositedFilter(event) => { - let info = BalanceUpdate { - entrypoint: address, - address: event.account, - amount: event.total_deposit, - is_addition: true, - }; - balance_updates.push(info); - } - entry_point_v0_7::IEntryPointEvents::WithdrawnFilter(event) => { - let info = BalanceUpdate { - entrypoint: address, - address: event.account, - amount: event.amount, - is_addition: false, - }; - balance_updates.push(info); - } - _ => {} + let address = log.address(); + + match log.topic0() { + Some(&UserOperationEventV07::SIGNATURE_HASH) => { + let Ok(decoded) = log.log_decode::() else { + warn!("Failed to decode v0.7 UserOperationEvent: {:?}", log); + return; + }; + let event = decoded.data(); + + let paymaster = if event.paymaster.is_zero() { + None + } else { + Some(event.paymaster) + }; + let mined = MinedOp { + hash: event.userOpHash, + entry_point: address, + sender: event.sender, + nonce: event.nonce, + actual_gas_cost: event.actualGasCost, + paymaster, + }; + mined_ops.push(mined); + } + Some(&DepositedV07::SIGNATURE_HASH) => { + let Ok(decoded) = log.log_decode::() else { + warn!("Failed to decode v0.7 Deposited: {:?}", log); + return; + }; + let event = decoded.data(); + + let info = BalanceUpdate { + entrypoint: address, + address: event.account, + amount: event.totalDeposit, + is_addition: true, + }; + balance_updates.push(info); + } + Some(&WithdrawnV07::SIGNATURE_HASH) => { + let Ok(decoded) = log.log_decode::() else { + warn!("Failed to decode v0.7 Withdrawn: {:?}", log); + return; + }; + let event = decoded.data(); + + let info = BalanceUpdate { + entrypoint: address, + address: event.account, + amount: event.amount, + is_addition: false, + }; + balance_updates.push(info); + } + _ => { + warn!("Unknown event signature: {:?}", log.topic0()); } } } @@ -611,27 +647,22 @@ impl BlockSummary { /// it's better to catch it now than run into panics from bad indexing math /// later. fn try_from_block_without_ops( - block: Block, + block: Block, expected_block_number: Option, ) -> anyhow::Result { - let number = block - .number - .context("block number should be present")? - .as_u64(); if let Some(expected_block_number) = expected_block_number { ensure!( - number == expected_block_number, - "block number {number} should match expected {expected_block_number}" + block.header.number == expected_block_number, + "block number {} should match expected {}", + block.header.number, + expected_block_number ); } Ok(Self { - number: block - .number - .context("block number should be present")? - .as_u64(), - hash: block.hash.context("block hash should exist")?, - timestamp: block.timestamp.as_u64().into(), - parent_hash: block.parent_hash, + number: block.header.number, + hash: block.header.hash, + timestamp: block.header.timestamp.into(), + parent_hash: block.header.parent_hash, ops: Vec::new(), entity_balance_updates: Vec::new(), }) @@ -696,37 +727,34 @@ impl ChainMetrics { mod tests { use std::ops::DerefMut; - use ethers::{ - abi::AbiEncode, - prelude::EthEvent, - types::{FilterBlockOption, Log, H160}, - utils, - }; + use alloy_primitives::{address, Log as PrimitiveLog, LogData}; use parking_lot::RwLock; - use rundler_provider::MockProvider; + use rundler_provider::{ + BlockHeader, BlockId, FilterBlockOption, MockEvmProvider, RpcBlockHash, + }; use super::*; const HISTORY_SIZE: u64 = 3; - const ENTRY_POINT_ADDRESS_V0_6: Address = H160(*b"01234567890123456789"); - const ENTRY_POINT_ADDRESS_V0_7: Address = H160(*b"98765432109876543210"); + const ENTRY_POINT_ADDRESS_V0_6: Address = address!("0123456789012345678901234567890123456789"); + const ENTRY_POINT_ADDRESS_V0_7: Address = address!("9876543210987654321098765432109876543210"); #[derive(Clone, Debug)] struct MockBlock { - hash: H256, + hash: B256, events: Vec, } #[derive(Clone, Debug, Default)] struct MockEntryPointEvents { address: Address, - op_hashes: Vec, + op_hashes: Vec, deposit_addresses: Vec

, withdrawal_addresses: Vec
, } impl MockBlock { - fn new(hash: H256) -> Self { + fn new(hash: B256) -> Self { Self { hash, events: vec![], @@ -736,7 +764,7 @@ mod tests { fn add_ep( mut self, address: Address, - op_hashes: Vec, + op_hashes: Vec, deposit_addresses: Vec
, withdrawal_addresses: Vec
, ) -> Self { @@ -764,28 +792,39 @@ mod tests { self.blocks.write() } - fn get_head(&self) -> Block { + fn get_head(&self) -> Block { let hash = self.blocks.read().last().unwrap().hash; - self.get_block_by_hash(hash).unwrap() + self.get_block(hash.into()).unwrap() } - fn get_block_by_hash(&self, hash: H256) -> Option> { + fn get_block(&self, id: BlockId) -> Option { + let BlockId::Hash(RpcBlockHash { + block_hash: hash, + require_canonical: _, + }) = id + else { + panic!("get_block only supports hash ids"); + }; + let blocks = self.blocks.read(); let number = blocks.iter().position(|block| block.hash == hash)?; let parent_hash = if number > 0 { blocks[number - 1].hash } else { - H256::zero() + B256::ZERO }; Some(Block { - hash: Some(hash), - parent_hash, - number: Some(number.into()), + header: BlockHeader { + hash, + parent_hash, + number: number as u64, + ..Default::default() + }, ..Default::default() }) } - fn get_logs_by_block_hash(&self, block_hash: H256) -> Vec { + fn get_logs_by_block_hash(&self, block_hash: B256) -> Vec { let blocks = self.blocks.read(); let block = blocks.iter().find(|block| block.hash == block_hash); let Some(block) = block else { @@ -953,7 +992,7 @@ mod tests { MockBlock::new(hash(2)).add_ep( ENTRY_POINT_ADDRESS_V0_6, vec![hash(102)], - vec![Address::zero()], + vec![Address::ZERO], vec![addr(1)], ), ]); @@ -1000,13 +1039,13 @@ mod tests { unmined_ops: vec![fake_mined_op(102, ENTRY_POINT_ADDRESS_V0_6)], entity_balance_updates: vec![fake_mined_balance_update( addr(3), - 0.into(), + 0, false, ENTRY_POINT_ADDRESS_V0_6 )], unmined_entity_balance_updates: vec![ - fake_mined_balance_update(addr(0), 0.into(), true, ENTRY_POINT_ADDRESS_V0_6), - fake_mined_balance_update(addr(1), 0.into(), false, ENTRY_POINT_ADDRESS_V0_6), + fake_mined_balance_update(addr(0), 0, true, ENTRY_POINT_ADDRESS_V0_6), + fake_mined_balance_update(addr(1), 0, false, ENTRY_POINT_ADDRESS_V0_6), ], reorg_larger_than_history: false, } @@ -1063,7 +1102,7 @@ mod tests { ChainUpdate { entity_balance_updates: vec![fake_mined_balance_update( addr(2), - 0.into(), + 0, true, ENTRY_POINT_ADDRESS_V0_6 )], @@ -1081,8 +1120,8 @@ mod tests { fake_mined_op(102, ENTRY_POINT_ADDRESS_V0_6) ], unmined_entity_balance_updates: vec![ - fake_mined_balance_update(addr(1), 0.into(), true, ENTRY_POINT_ADDRESS_V0_6), - fake_mined_balance_update(addr(9), 0.into(), false, ENTRY_POINT_ADDRESS_V0_6), + fake_mined_balance_update(addr(1), 0, true, ENTRY_POINT_ADDRESS_V0_6), + fake_mined_balance_update(addr(9), 0, false, ENTRY_POINT_ADDRESS_V0_6), ], reorg_larger_than_history: false, } @@ -1132,7 +1171,7 @@ mod tests { latest_block_number: 1, entity_balance_updates: vec![fake_mined_balance_update( addr(1), - 0.into(), + 0, true, ENTRY_POINT_ADDRESS_V0_6 )], @@ -1365,14 +1404,14 @@ mod tests { ], unmined_ops: vec![], entity_balance_updates: vec![ - fake_mined_balance_update(addr(1), 0.into(), true, ENTRY_POINT_ADDRESS_V0_6), - fake_mined_balance_update(addr(2), 0.into(), true, ENTRY_POINT_ADDRESS_V0_6), - fake_mined_balance_update(addr(3), 0.into(), false, ENTRY_POINT_ADDRESS_V0_6), - fake_mined_balance_update(addr(4), 0.into(), false, ENTRY_POINT_ADDRESS_V0_6), - fake_mined_balance_update(addr(5), 0.into(), true, ENTRY_POINT_ADDRESS_V0_7), - fake_mined_balance_update(addr(6), 0.into(), true, ENTRY_POINT_ADDRESS_V0_7), - fake_mined_balance_update(addr(7), 0.into(), false, ENTRY_POINT_ADDRESS_V0_7), - fake_mined_balance_update(addr(8), 0.into(), false, ENTRY_POINT_ADDRESS_V0_7), + fake_mined_balance_update(addr(1), 0, true, ENTRY_POINT_ADDRESS_V0_6), + fake_mined_balance_update(addr(2), 0, true, ENTRY_POINT_ADDRESS_V0_6), + fake_mined_balance_update(addr(3), 0, false, ENTRY_POINT_ADDRESS_V0_6), + fake_mined_balance_update(addr(4), 0, false, ENTRY_POINT_ADDRESS_V0_6), + fake_mined_balance_update(addr(5), 0, true, ENTRY_POINT_ADDRESS_V0_7), + fake_mined_balance_update(addr(6), 0, true, ENTRY_POINT_ADDRESS_V0_7), + fake_mined_balance_update(addr(7), 0, false, ENTRY_POINT_ADDRESS_V0_7), + fake_mined_balance_update(addr(8), 0, false, ENTRY_POINT_ADDRESS_V0_7), ], unmined_entity_balance_updates: vec![], reorg_larger_than_history: false, @@ -1380,7 +1419,7 @@ mod tests { ); } - fn new_chain() -> (Chain, ProviderController) { + fn new_chain() -> (Chain, ProviderController) { let (provider, controller) = new_mock_provider(); let chain = Chain::new( Arc::new(provider), @@ -1397,15 +1436,15 @@ mod tests { (chain, controller) } - fn new_mock_provider() -> (impl Provider, ProviderController) { + fn new_mock_provider() -> (impl EvmProvider, ProviderController) { let controller = ProviderController { blocks: Arc::new(RwLock::new(vec![])), }; - let mut provider = MockProvider::new(); + let mut provider = MockEvmProvider::new(); - provider.expect_get_block::().returning({ + provider.expect_get_block().returning({ let controller = controller.clone(); - move |hash| Ok(controller.get_block_by_hash(hash)) + move |id| Ok(controller.get_block(id)) }); provider.expect_get_logs().returning({ @@ -1421,116 +1460,150 @@ mod tests { (provider, controller) } - fn fake_mined_log_v0_6(op_hash: H256) -> Log { + fn fake_mined_log_v0_6(op_hash: B256) -> Log { + let mut log_data = LogData::default(); + log_data.set_topics_unchecked(vec![ + UserOperationEventV06::SIGNATURE_HASH, + op_hash, + B256::ZERO, // sender + B256::ZERO, // paymaster + ]); + log_data.data = UserOperationEventV06 { + userOpHash: op_hash, + sender: Address::ZERO, + paymaster: Address::ZERO, + nonce: U256::ZERO, + success: true, + actualGasCost: U256::ZERO, + actualGasUsed: U256::ZERO, + } + .encode_data() + .into(); + Log { - address: ENTRY_POINT_ADDRESS_V0_6, - topics: vec![ - H256::from(utils::keccak256( - entry_point_v0_6::UserOperationEventFilter::abi_signature().as_bytes(), - )), - op_hash, - H256::zero(), // sender - H256::zero(), // paymaster - ], - data: AbiEncode::encode(( - U256::zero(), // nonce - true, // success - U256::zero(), // actual_gas_cost - U256::zero(), // actual_gas_used - )) - .into(), + inner: PrimitiveLog { + address: ENTRY_POINT_ADDRESS_V0_6, + data: log_data, + }, ..Default::default() } } fn fake_deposit_log_v0_6(deposit_address: Address) -> Log { + let mut log_data = LogData::default(); + log_data.set_topics_unchecked(vec![ + DepositedV06::SIGNATURE_HASH, + deposit_address.into_word(), + ]); + log_data.data = DepositedV06 { + totalDeposit: U256::ZERO, + account: deposit_address, + } + .encode_data() + .into(); + Log { - address: ENTRY_POINT_ADDRESS_V0_6, - topics: vec![ - H256::from(utils::keccak256( - entry_point_v0_6::DepositedFilter::abi_signature().as_bytes(), - )), - H256::from(deposit_address), - ], - data: AbiEncode::encode(( - U256::zero(), // totalDeposits - )) - .into(), + inner: PrimitiveLog { + address: ENTRY_POINT_ADDRESS_V0_6, + data: log_data, + }, ..Default::default() } } fn fake_withdrawal_log_v0_6(withdrawal_address: Address) -> Log { + let mut log_data = LogData::default(); + log_data.set_topics_unchecked(vec![ + WithdrawnV06::SIGNATURE_HASH, + withdrawal_address.into_word(), + ]); + log_data.data = WithdrawnV06 { + amount: U256::ZERO, + account: withdrawal_address, + withdrawAddress: Address::ZERO, + } + .encode_data() + .into(); + Log { - address: ENTRY_POINT_ADDRESS_V0_6, - topics: vec![ - H256::from(utils::keccak256( - entry_point_v0_6::WithdrawnFilter::abi_signature().as_bytes(), - )), - H256::from(withdrawal_address), - ], - data: AbiEncode::encode(( - Address::zero(), // withdrawAddress - U256::zero(), // amount - )) - .into(), + inner: PrimitiveLog { + address: ENTRY_POINT_ADDRESS_V0_6, + data: log_data, + }, ..Default::default() } } - fn fake_mined_log_v0_7(op_hash: H256) -> Log { + fn fake_mined_log_v0_7(op_hash: B256) -> Log { + let mut log_data = LogData::default(); + log_data.set_topics_unchecked(vec![ + UserOperationEventV07::SIGNATURE_HASH, + op_hash, + B256::ZERO, // sender + B256::ZERO, // paymaster + ]); + log_data.data = UserOperationEventV07 { + userOpHash: op_hash, + sender: Address::ZERO, + paymaster: Address::ZERO, + nonce: U256::ZERO, + success: true, + actualGasCost: U256::ZERO, + actualGasUsed: U256::ZERO, + } + .encode_data() + .into(); + Log { - address: ENTRY_POINT_ADDRESS_V0_7, - topics: vec![ - H256::from(utils::keccak256( - entry_point_v0_7::UserOperationEventFilter::abi_signature().as_bytes(), - )), - op_hash, - H256::zero(), // sender - H256::zero(), // paymaster - ], - data: AbiEncode::encode(( - U256::zero(), // nonce - true, // success - U256::zero(), // actual_gas_cost - U256::zero(), // actual_gas_used - )) - .into(), + inner: PrimitiveLog { + address: ENTRY_POINT_ADDRESS_V0_7, + data: log_data, + }, ..Default::default() } } fn fake_deposit_log_v0_7(deposit_address: Address) -> Log { + let mut log_data = LogData::default(); + log_data.set_topics_unchecked(vec![ + DepositedV07::SIGNATURE_HASH, + deposit_address.into_word(), + ]); + log_data.data = DepositedV07 { + totalDeposit: U256::ZERO, + account: deposit_address, + } + .encode_data() + .into(); + Log { - address: ENTRY_POINT_ADDRESS_V0_7, - topics: vec![ - H256::from(utils::keccak256( - entry_point_v0_7::DepositedFilter::abi_signature().as_bytes(), - )), - H256::from(deposit_address), - ], - data: AbiEncode::encode(( - U256::zero(), // totalDeposits - )) - .into(), + inner: PrimitiveLog { + address: ENTRY_POINT_ADDRESS_V0_7, + data: log_data, + }, ..Default::default() } } fn fake_withdrawal_log_v0_7(withdrawal_address: Address) -> Log { + let mut log_data = LogData::default(); + log_data.set_topics_unchecked(vec![ + WithdrawnV07::SIGNATURE_HASH, + withdrawal_address.into_word(), + ]); + log_data.data = WithdrawnV06 { + amount: U256::ZERO, + account: withdrawal_address, + withdrawAddress: Address::ZERO, + } + .encode_data() + .into(); + Log { - address: ENTRY_POINT_ADDRESS_V0_7, - topics: vec![ - H256::from(utils::keccak256( - entry_point_v0_7::WithdrawnFilter::abi_signature().as_bytes(), - )), - H256::from(withdrawal_address), - ], - data: AbiEncode::encode(( - Address::zero(), // withdrawAddress - U256::zero(), // amount - )) - .into(), + inner: PrimitiveLog { + address: ENTRY_POINT_ADDRESS_V0_7, + data: log_data, + }, ..Default::default() } } @@ -1539,37 +1612,37 @@ mod tests { MinedOp { hash: hash(n), entry_point: ep, - sender: Address::zero(), - nonce: U256::zero(), - actual_gas_cost: U256::zero(), + sender: Address::ZERO, + nonce: U256::ZERO, + actual_gas_cost: U256::ZERO, paymaster: None, } } fn fake_mined_balance_update( address: Address, - amount: U256, + amount: u128, is_addition: bool, ep: Address, ) -> BalanceUpdate { BalanceUpdate { address, entrypoint: ep, - amount, + amount: U256::from(amount), is_addition, } } // Helper that makes fake hashes. - fn hash(n: u8) -> H256 { - let mut hash = H256::zero(); + fn hash(n: u8) -> B256 { + let mut hash = B256::ZERO; hash.0[0] = n; hash } // Helper that makes fake addresses. fn addr(n: u8) -> Address { - let mut address = Address::zero(); + let mut address = Address::ZERO; address.0[0] = n; address } diff --git a/crates/pool/src/emit.rs b/crates/pool/src/emit.rs index 40b4c87e7..554591f3d 100644 --- a/crates/pool/src/emit.rs +++ b/crates/pool/src/emit.rs @@ -13,7 +13,7 @@ use std::fmt::Display; -use ethers::types::{Address, H256}; +use alloy_primitives::{Address, B256}; use rundler_types::{Entity, EntityType, Timestamp, UserOperation, UserOperationVariant}; use rundler_utils::strs; @@ -25,7 +25,7 @@ pub enum OpPoolEvent { /// An operation was received and added to the pool ReceivedOp { /// Operation hash - op_hash: H256, + op_hash: B256, /// The full operation op: UserOperationVariant, /// Block number the operation was added to the pool @@ -42,7 +42,7 @@ pub enum OpPoolEvent { /// An operation was removed from the pool RemovedOp { /// Operation hash - op_hash: H256, + op_hash: B256, /// Removal reason reason: OpRemovalReason, }, @@ -100,9 +100,9 @@ pub enum OpRemovalReason { /// Mined at block number block_number: u64, /// Mined at block hash - block_hash: H256, + block_hash: B256, /// Mined in transaction hash - tx_hash: H256, + tx_hash: B256, }, /// Op was associated with a throttled entity and was removed /// because it was too old diff --git a/crates/pool/src/mempool/mod.rs b/crates/pool/src/mempool/mod.rs index d6b57e7bd..2fa4af045 100644 --- a/crates/pool/src/mempool/mod.rs +++ b/crates/pool/src/mempool/mod.rs @@ -28,7 +28,7 @@ use std::{ sync::Arc, }; -use ethers::types::{Address, H256}; +use alloy_primitives::{Address, B256}; #[cfg(test)] use mockall::automock; use rundler_sim::{MempoolConfig, PrecheckSettings, SimulationSettings}; @@ -48,7 +48,7 @@ pub(crate) type MempoolResult = std::result::Result; #[cfg_attr(test, automock)] #[async_trait] /// In-memory operation pool -pub trait Mempool: Send + Sync + 'static { +pub trait Mempool: Send + Sync { /// Call to update the mempool with a new chain update async fn on_chain_update(&self, update: &ChainUpdate); @@ -63,13 +63,13 @@ pub trait Mempool: Send + Sync + 'static { &self, origin: OperationOrigin, op: UserOperationVariant, - ) -> MempoolResult; + ) -> MempoolResult; /// Removes a set of operations from the pool. - fn remove_operations(&self, hashes: &[H256]); + fn remove_operations(&self, hashes: &[B256]); /// Removes an operation from the pool by its ID. - fn remove_op_by_id(&self, id: &UserOperationId) -> MempoolResult>; + fn remove_op_by_id(&self, id: &UserOperationId) -> MempoolResult>; /// Updates the reputation of an entity. fn update_entity(&self, entity_update: EntityUpdate); @@ -92,7 +92,7 @@ pub trait Mempool: Send + Sync + 'static { fn all_operations(&self, max: usize) -> Vec>; /// Looks up a user operation by hash, returns None if not found - fn get_user_operation_by_hash(&self, hash: H256) -> Option>; + fn get_user_operation_by_hash(&self, hash: B256) -> Option>; /// Debug methods @@ -134,7 +134,7 @@ pub struct PoolConfig { pub same_sender_mempool_count: usize, /// The minimum fee bump required to replace an operation in the mempool /// Applies to both priority fee and fee. Expressed as an integer percentage value - pub min_replacement_fee_increase_percentage: u64, + pub min_replacement_fee_increase_percentage: u32, /// After this threshold is met, we will start to drop the worst userops from the mempool pub max_size_of_pool_bytes: usize, /// Operations that are always banned from the mempool @@ -146,7 +146,7 @@ pub struct PoolConfig { /// Settings for simulation validation pub sim_settings: SimulationSettings, /// Configuration for the mempool channels, by channel ID - pub mempool_channel_configs: HashMap, + pub mempool_channel_configs: HashMap, /// Number of mempool shards to use. A mempool shard is a disjoint subset of the mempool /// that is used to ensure that two bundle builders don't attempt to but bundle the same /// operations. The mempool is divided into shards by taking the hash of the operation @@ -197,16 +197,16 @@ mod tests { let po = PoolOperation { uo: UserOperation { sender, - paymaster_and_data: paymaster.as_fixed_bytes().into(), - init_code: factory.as_fixed_bytes().into(), + paymaster_and_data: paymaster.to_vec().into(), + init_code: factory.to_vec().into(), ..Default::default() } .into(), entry_point: Address::random(), aggregator: Some(aggregator), valid_time_range: ValidTimeRange::all_time(), - expected_code_hash: H256::random(), - sim_block_hash: H256::random(), + expected_code_hash: B256::random(), + sim_block_hash: B256::random(), sim_block_number: 0, account_is_staked: true, entity_infos: EntityInfos { diff --git a/crates/pool/src/mempool/paymaster.rs b/crates/pool/src/mempool/paymaster.rs index af2a8a483..e03df586f 100644 --- a/crates/pool/src/mempool/paymaster.rs +++ b/crates/pool/src/mempool/paymaster.rs @@ -15,8 +15,8 @@ //! Tracks a size value. use std::collections::HashMap; +use alloy_primitives::{Address, U256}; use anyhow::Context; -use ethers::{abi::Address, types::U256}; use parking_lot::RwLock; use rundler_provider::EntryPoint; use rundler_types::{ @@ -38,7 +38,7 @@ pub(crate) struct PaymasterTracker { #[derive(Debug)] pub(crate) struct PaymasterConfig { - min_stake_value: u128, + min_stake_value: U256, min_unstake_delay: u32, tracker_enabled: bool, cache_length: u32, @@ -46,7 +46,7 @@ pub(crate) struct PaymasterConfig { impl PaymasterConfig { pub(crate) fn new( - min_stake_value: u128, + min_stake_value: U256, min_unstake_delay: u32, tracker_enabled: bool, cache_length: u32, @@ -76,7 +76,11 @@ where } pub(crate) async fn get_stake_status(&self, address: Address) -> MempoolResult { - let deposit_info = self.entry_point.get_deposit_info(address).await?; + let deposit_info = self + .entry_point + .get_deposit_info(address) + .await + .context("provider error")?; let is_staked = deposit_info.stake.ge(&self.config.min_stake_value) && deposit_info @@ -85,8 +89,8 @@ where let stake_status = StakeStatus { stake_info: StakeInfo { - stake: deposit_info.stake.into(), - unstake_delay_sec: deposit_info.unstake_delay_sec.into(), + stake: deposit_info.stake, + unstake_delay_sec: deposit_info.unstake_delay_sec, }, is_staked, }; @@ -123,7 +127,7 @@ where // Save paymaster balance after first lookup self.state .write() - .add_new_paymaster(paymaster, balance, 0.into()); + .add_new_paymaster(paymaster, balance, U256::ZERO); Ok(paymaster_meta) } @@ -156,7 +160,11 @@ where &self, addresses: &[Address], ) -> MempoolResult<()> { - let balances = self.entry_point.get_balances(addresses.to_vec()).await?; + let balances = self + .entry_point + .get_balances(addresses.to_vec()) + .await + .context("provider error")?; self.state .write() @@ -171,7 +179,8 @@ where let balances = self .entry_point .get_balances(paymaster_addresses.clone()) - .await?; + .await + .context("provider error")?; self.state .write() @@ -498,7 +507,7 @@ impl PaymasterBalance { #[cfg(test)] mod tests { - use ethers::types::{Address, H256, U256}; + use alloy_primitives::{Address, B256, U256}; use rundler_provider::{DepositInfo, MockEntryPointV0_6}; use rundler_types::{ pool::{PaymasterMetadata, PoolOperation}, @@ -515,8 +524,8 @@ mod tests { entry_point: Address::random(), aggregator: None, valid_time_range: ValidTimeRange::all_time(), - expected_code_hash: H256::random(), - sim_block_hash: H256::random(), + expected_code_hash: B256::random(), + sim_block_hash: B256::random(), account_is_staked: true, entity_infos: EntityInfos::default(), sim_block_number: 0, @@ -531,11 +540,11 @@ mod tests { let sender = Address::random(); let uo = UserOperation { sender, - call_gas_limit: 10.into(), - pre_verification_gas: 10.into(), - paymaster_and_data: paymaster.as_bytes().to_vec().into(), - verification_gas_limit: 10.into(), - max_fee_per_gas: 1.into(), + call_gas_limit: 10, + pre_verification_gas: 10, + paymaster_and_data: paymaster.to_vec().into(), + verification_gas_limit: 10, + max_fee_per_gas: 1, ..Default::default() }; @@ -550,7 +559,7 @@ mod tests { .await .unwrap(); - assert_eq!(balance.confirmed_balance, 1000.into(),); + assert_eq!(balance.confirmed_balance, U256::from(1000)); assert_eq!( balance.pending_balance, @@ -571,11 +580,11 @@ mod tests { let uo = UserOperation { sender, - call_gas_limit: 10.into(), - paymaster_and_data: paymaster.as_bytes().to_vec().into(), - pre_verification_gas: 10.into(), - verification_gas_limit: 10.into(), - max_fee_per_gas: 1.into(), + call_gas_limit: 10, + paymaster_and_data: paymaster.to_vec().into(), + pre_verification_gas: 10, + verification_gas_limit: 10, + max_fee_per_gas: 1, ..Default::default() }; @@ -597,10 +606,10 @@ mod tests { let confirmed_balance = U256::from(5); let uo = UserOperation { sender, - call_gas_limit: 10.into(), - pre_verification_gas: 10.into(), - verification_gas_limit: 10.into(), - max_fee_per_gas: 1.into(), + call_gas_limit: 10, + pre_verification_gas: 10, + verification_gas_limit: 10, + max_fee_per_gas: 1, ..Default::default() }; @@ -629,11 +638,11 @@ mod tests { let uo = UserOperation { sender, - call_gas_limit: 100.into(), - paymaster_and_data: paymaster.as_bytes().to_vec().into(), - pre_verification_gas: 100.into(), - verification_gas_limit: 100.into(), - max_fee_per_gas: 1.into(), + call_gas_limit: 100, + paymaster_and_data: paymaster.to_vec().into(), + pre_verification_gas: 100, + verification_gas_limit: 100, + max_fee_per_gas: 1, ..Default::default() }; @@ -648,16 +657,16 @@ mod tests { let paymaster_tracker = new_paymaster_tracker(); let paymaster_0 = Address::random(); - let paymaster_0_confimed = 1000.into(); + let paymaster_0_confimed = U256::from(1000); - paymaster_tracker.add_new_paymaster(paymaster_0, paymaster_0_confimed, 0.into()); + paymaster_tracker.add_new_paymaster(paymaster_0, paymaster_0_confimed, U256::ZERO); let balance_0 = paymaster_tracker .paymaster_balance(paymaster_0) .await .unwrap(); - assert_eq!(balance_0.confirmed_balance, 1000.into()); + assert_eq!(balance_0.confirmed_balance, U256::from(1000)); let _ = paymaster_tracker.reset_confirmed_balances().await; @@ -666,7 +675,7 @@ mod tests { .await .unwrap(); - assert_eq!(balance_0.confirmed_balance, 50.into()); + assert_eq!(balance_0.confirmed_balance, U256::from(50)); } #[tokio::test] @@ -674,16 +683,16 @@ mod tests { let paymaster_tracker = new_paymaster_tracker(); let paymaster_0 = Address::random(); - let paymaster_0_confimed = 1000.into(); + let paymaster_0_confimed = U256::from(1000); - paymaster_tracker.add_new_paymaster(paymaster_0, paymaster_0_confimed, 0.into()); + paymaster_tracker.add_new_paymaster(paymaster_0, paymaster_0_confimed, U256::ZERO); let balance_0 = paymaster_tracker .paymaster_balance(paymaster_0) .await .unwrap(); - assert_eq!(balance_0.confirmed_balance, 1000.into()); + assert_eq!(balance_0.confirmed_balance, U256::from(1000)); let _ = paymaster_tracker .reset_confirmed_balances_for(&[paymaster_0]) @@ -694,7 +703,7 @@ mod tests { .await .unwrap(); - assert_eq!(balance_0.confirmed_balance, 50.into()); + assert_eq!(balance_0.confirmed_balance, U256::from(50)); } #[tokio::test] @@ -713,11 +722,11 @@ mod tests { let sender = Address::random(); let uo = UserOperation { sender, - call_gas_limit: 10.into(), - pre_verification_gas: 10.into(), - verification_gas_limit: 10.into(), - paymaster_and_data: paymaster.as_bytes().to_vec().into(), - max_fee_per_gas: 1.into(), + call_gas_limit: 10, + pre_verification_gas: 10, + verification_gas_limit: 10, + paymaster_and_data: paymaster.to_vec().into(), + max_fee_per_gas: 1, ..Default::default() }; @@ -754,23 +763,23 @@ mod tests { let sender = Address::random(); let uo = UserOperation { sender, - call_gas_limit: 10.into(), - pre_verification_gas: 10.into(), - paymaster_and_data: paymaster_0.as_bytes().to_vec().into(), - verification_gas_limit: 10.into(), - max_fee_per_gas: 1.into(), + call_gas_limit: 10, + pre_verification_gas: 10, + paymaster_and_data: paymaster_0.to_vec().into(), + verification_gas_limit: 10, + max_fee_per_gas: 1, ..Default::default() }; let mut uo_1 = uo.clone(); - uo_1.max_fee_per_gas = 2.into(); - uo_1.paymaster_and_data = paymaster_1.as_bytes().to_vec().into(); + uo_1.max_fee_per_gas = 2; + uo_1.paymaster_and_data = paymaster_1.to_vec().into(); let max_op_cost_0 = uo.max_gas_cost(); let max_op_cost_1 = uo_1.max_gas_cost(); - paymaster_tracker.add_new_paymaster(paymaster_0, paymaster_balance_0, 0.into()); - paymaster_tracker.add_new_paymaster(paymaster_1, paymaster_balance_1, 0.into()); + paymaster_tracker.add_new_paymaster(paymaster_0, paymaster_balance_0, U256::ZERO); + paymaster_tracker.add_new_paymaster(paymaster_1, paymaster_balance_1, U256::ZERO); let po_0 = demo_pool_op(uo); @@ -849,17 +858,17 @@ mod tests { .await .unwrap(); - paymaster_tracker.add_new_user_op(&existing_id, &meta, 30.into()); + paymaster_tracker.add_new_user_op(&existing_id, &meta, U256::from(30)); // replacement_uo let uo = UserOperation { sender, nonce, - call_gas_limit: 100.into(), - pre_verification_gas: 100.into(), - verification_gas_limit: 100.into(), - paymaster_and_data: paymaster.as_bytes().to_vec().into(), - max_fee_per_gas: 1.into(), + call_gas_limit: 100, + pre_verification_gas: 100, + verification_gas_limit: 100, + paymaster_and_data: paymaster.to_vec().into(), + max_fee_per_gas: 1, ..Default::default() }; @@ -924,9 +933,9 @@ mod tests { entrypoint.expect_get_deposit_info().returning(|_| { Ok(DepositInfo { - deposit: 1000.into(), + deposit: U256::from(1000), staked: true, - stake: 10000, + stake: U256::from(10000), unstake_delay_sec: 100, withdraw_time: 10, }) @@ -934,13 +943,13 @@ mod tests { entrypoint .expect_get_balances() - .returning(|_| Ok(vec![50.into()])); + .returning(|_| Ok(vec![U256::from(50)])); entrypoint .expect_balance_of() .returning(|_, _| Ok(U256::from(1000))); - let config = PaymasterConfig::new(1001, 99, true, u32::MAX); + let config = PaymasterConfig::new(U256::from(1001), 99, true, u32::MAX); PaymasterTracker::new(entrypoint, config) } diff --git a/crates/pool/src/mempool/pool.rs b/crates/pool/src/mempool/pool.rs index 101357013..074ef4052 100644 --- a/crates/pool/src/mempool/pool.rs +++ b/crates/pool/src/mempool/pool.rs @@ -18,11 +18,8 @@ use std::{ time::{Duration, SystemTime, UNIX_EPOCH}, }; +use alloy_primitives::{Address, B256}; use anyhow::Context; -use ethers::{ - abi::Address, - types::{H256, U256}, -}; use rundler_types::{ pool::{MempoolError, PoolOperation}, Entity, EntityType, GasFees, Timestamp, UserOperation, UserOperationId, UserOperationVariant, @@ -38,7 +35,7 @@ pub(crate) struct PoolInnerConfig { entry_point: Address, chain_id: u64, max_size_of_pool_bytes: usize, - min_replacement_fee_increase_percentage: u64, + min_replacement_fee_increase_percentage: u32, throttled_entity_mempool_count: u64, throttled_entity_live_blocks: u64, } @@ -62,20 +59,20 @@ pub(crate) struct PoolInner { /// Pool settings config: PoolInnerConfig, /// Operations by hash - by_hash: HashMap, + by_hash: HashMap, /// Operations by operation ID by_id: HashMap, /// Best operations, sorted by gas price best: BTreeSet, /// Time to mine info - time_to_mine: HashMap, + time_to_mine: HashMap, /// Removed operations, temporarily kept around in case their blocks are /// reorged away. Stored along with the block number at which it was /// removed. - mined_at_block_number_by_hash: HashMap, + mined_at_block_number_by_hash: HashMap, /// Removed operation hashes sorted by block number, so we can forget them /// when enough new blocks have passed. - mined_hashes_with_block_numbers: BTreeSet<(u64, H256)>, + mined_hashes_with_block_numbers: BTreeSet<(u64, B256)>, /// Count of operations by entity address count_by_address: HashMap, /// Submission ID counter @@ -113,7 +110,7 @@ impl PoolInner { pub(crate) fn check_replacement( &self, op: &UserOperationVariant, - ) -> MempoolResult> { + ) -> MempoolResult> { // Check if operation already known if self .by_hash @@ -145,7 +142,7 @@ impl PoolInner { } } - pub(crate) fn add_operation(&mut self, op: PoolOperation) -> MempoolResult { + pub(crate) fn add_operation(&mut self, op: PoolOperation) -> MempoolResult { let ret = self.add_operation_internal(Arc::new(op), None); self.update_metrics(); ret @@ -167,8 +164,8 @@ impl PoolInner { block_number: u64, block_timestamp: Timestamp, candidate_gas_fees: GasFees, - base_fee: U256, - ) -> Vec<(H256, Timestamp)> { + base_fee: u128, + ) -> Vec<(B256, Timestamp)> { let sys_block_time = SystemTime::now() .duration_since(UNIX_EPOCH) .expect("time should be after epoch"); @@ -218,7 +215,7 @@ impl PoolInner { 0 } - pub(crate) fn get_operation_by_hash(&self, hash: H256) -> Option> { + pub(crate) fn get_operation_by_hash(&self, hash: B256) -> Option> { self.by_hash.get(&hash).map(|o| o.po.clone()) } @@ -226,7 +223,7 @@ impl PoolInner { self.by_id.get(id).map(|o| o.po.clone()) } - pub(crate) fn remove_operation_by_hash(&mut self, hash: H256) -> Option> { + pub(crate) fn remove_operation_by_hash(&mut self, hash: B256) -> Option> { let ret = self.remove_operation_internal(hash, None); self.update_metrics(); ret @@ -332,7 +329,7 @@ impl PoolInner { &mut self, entity: Entity, current_block_number: u64, - ) -> Vec { + ) -> Vec { let mut uos_kept = self.config.throttled_entity_mempool_count; let to_remove = self .best @@ -361,7 +358,7 @@ impl PoolInner { /// Removes all operations using the given entity, returning the hashes of /// the removed operations. - pub(crate) fn remove_entity(&mut self, entity: Entity) -> Vec { + pub(crate) fn remove_entity(&mut self, entity: Entity) -> Vec { let to_remove = self .by_hash .iter() @@ -402,7 +399,7 @@ impl PoolInner { self.update_metrics(); } - fn enforce_size(&mut self) -> anyhow::Result> { + fn enforce_size(&mut self) -> anyhow::Result> { let mut removed = Vec::new(); while self.pool_size > self.config.max_size_of_pool_bytes { @@ -422,7 +419,7 @@ impl PoolInner { Ok(removed) } - fn put_back_unmined_operation(&mut self, op: OrderedPoolOperation) -> MempoolResult { + fn put_back_unmined_operation(&mut self, op: OrderedPoolOperation) -> MempoolResult { self.add_operation_internal(op.po, Some(op.submission_id)) } @@ -430,7 +427,7 @@ impl PoolInner { &mut self, op: Arc, submission_id: Option, - ) -> MempoolResult { + ) -> MempoolResult { // Check if operation already known or replacing an existing operation // if replacing, remove the existing operation if let Some(hash) = self.check_replacement(&op.uo)? { @@ -474,7 +471,7 @@ impl PoolInner { fn remove_operation_internal( &mut self, - hash: H256, + hash: B256, block_number: Option, ) -> Option> { let op = self.by_hash.remove(&hash)?; @@ -514,7 +511,7 @@ impl PoolInner { id } - fn get_min_replacement_fees(&self, op: &UserOperationVariant) -> (U256, U256) { + fn get_min_replacement_fees(&self, op: &UserOperationVariant) -> (u128, u128) { let replacement_priority_fee = math::increase_by_percent( op.max_priority_fee_per_gas(), self.config.min_replacement_fee_increase_percentage, @@ -642,6 +639,7 @@ impl PoolMetrics { #[cfg(test)] mod tests { + use alloy_primitives::U256; use rundler_types::{ v0_6::UserOperation, EntityInfo, EntityInfos, UserOperation as UserOperationTrait, ValidTimeRange, @@ -669,7 +667,7 @@ mod tests { let get_op = pool.get_operation_by_hash(hash).unwrap(); assert_eq!(op, *get_op); - assert_eq!(pool.get_operation_by_hash(H256::random()), None); + assert_eq!(pool.get_operation_by_hash(B256::random()), None); } #[test] @@ -684,7 +682,7 @@ mod tests { let bad_id = UserOperationId { sender: Address::random(), - nonce: 0.into(), + nonce: U256::ZERO, }; assert_eq!(pool.get_operation_by_id(&bad_id), None); @@ -803,7 +801,7 @@ mod tests { let mined_op = MinedOp { paymaster: None, - actual_gas_cost: U256::zero(), + actual_gas_cost: U256::ZERO, hash, entry_point: pool.config.entry_point, sender, @@ -833,7 +831,7 @@ mod tests { let mined_op = MinedOp { paymaster: None, - actual_gas_cost: U256::zero(), + actual_gas_cost: U256::ZERO, hash, entry_point: pool.config.entry_point, sender, @@ -884,7 +882,7 @@ mod tests { for mut op in ops.into_iter() { let uo: &mut UserOperation = op.uo.as_mut(); - uo.paymaster_and_data = paymaster.as_bytes().to_vec().into(); + uo.paymaster_and_data = paymaster.to_vec().into(); op.entity_infos.paymaster = Some(EntityInfo { entity: Entity::paymaster(paymaster), is_staked: false, @@ -909,12 +907,12 @@ mod tests { let mut op = create_op(sender, 0, 1); let uo: &mut UserOperation = op.uo.as_mut(); - uo.paymaster_and_data = paymaster.as_bytes().to_vec().into(); + uo.paymaster_and_data = paymaster.to_vec().into(); op.entity_infos.paymaster = Some(EntityInfo { entity: Entity::paymaster(paymaster), is_staked: false, }); - uo.init_code = factory.as_bytes().to_vec().into(); + uo.init_code = factory.to_vec().into(); op.entity_infos.factory = Some(EntityInfo { entity: Entity::factory(factory), is_staked: false, @@ -930,7 +928,7 @@ mod tests { for i in 0..count { let mut op = op.clone(); let uo: &mut UserOperation = op.uo.as_mut(); - uo.nonce = i.into(); + uo.nonce = U256::from(i); hashes.push(pool.add_operation(op).unwrap()); } @@ -954,7 +952,7 @@ mod tests { let args = conf(); let mut pool = PoolInner::new(args.clone()); for i in 0..20 { - let op = create_op(Address::random(), i, i + 1); + let op = create_op(Address::random(), i, (i + 1) as u128); pool.add_operation(op).unwrap(); } @@ -969,7 +967,7 @@ mod tests { let args = conf(); let mut pool = PoolInner::new(args.clone()); for i in 0..20 { - let op = create_op(Address::random(), i, i + 1); + let op = create_op(Address::random(), i, (i + 1) as u128); pool.add_operation(op).unwrap(); } @@ -988,18 +986,18 @@ mod tests { let sender = Address::random(); let mut po1 = create_op(sender, 0, 100); let uo1: &mut UserOperation = po1.uo.as_mut(); - uo1.max_priority_fee_per_gas = 100.into(); + uo1.max_priority_fee_per_gas = 100; let _ = pool.add_operation(po1.clone()).unwrap(); let mut po2 = create_op(sender, 0, 101); let uo2: &mut UserOperation = po2.uo.as_mut(); - uo2.max_priority_fee_per_gas = 101.into(); + uo2.max_priority_fee_per_gas = 101; let res = pool.add_operation(po2); assert!(res.is_err()); match res.err().unwrap() { MempoolError::ReplacementUnderpriced(a, b) => { - assert_eq!(a, 100.into()); - assert_eq!(b, 100.into()); + assert_eq!(a, 100); + assert_eq!(b, 100); } _ => panic!("wrong error"), } @@ -1022,8 +1020,8 @@ mod tests { let paymaster1 = Address::random(); let mut po1 = create_op(sender, 0, 10); let uo1: &mut UserOperation = po1.uo.as_mut(); - uo1.max_priority_fee_per_gas = 10.into(); - uo1.paymaster_and_data = paymaster1.as_bytes().to_vec().into(); + uo1.max_priority_fee_per_gas = 10; + uo1.paymaster_and_data = paymaster1.to_vec().into(); po1.entity_infos.paymaster = Some(EntityInfo { entity: Entity::paymaster(paymaster1), is_staked: false, @@ -1034,8 +1032,8 @@ mod tests { let paymaster2 = Address::random(); let mut po2 = create_op(sender, 0, 11); let uo2: &mut UserOperation = po2.uo.as_mut(); - uo2.max_priority_fee_per_gas = 11.into(); - uo2.paymaster_and_data = paymaster2.as_bytes().to_vec().into(); + uo2.max_priority_fee_per_gas = 11; + uo2.paymaster_and_data = paymaster2.to_vec().into(); po2.entity_infos.paymaster = Some(EntityInfo { entity: Entity::paymaster(paymaster2), is_staked: false, @@ -1061,7 +1059,7 @@ mod tests { let sender = Address::random(); let mut po1 = create_op(sender, 0, 10); let uo1: &mut UserOperation = po1.uo.as_mut(); - uo1.max_priority_fee_per_gas = 10.into(); + uo1.max_priority_fee_per_gas = 10; let _ = pool.add_operation(po1.clone()).unwrap(); let res = pool.add_operation(po1); @@ -1081,7 +1079,7 @@ mod tests { po1.valid_time_range.valid_until = Timestamp::from(1); let _ = pool.add_operation(po1.clone()).unwrap(); - let res = pool.do_maintenance(0, Timestamp::from(2), GasFees::default(), 0.into()); + let res = pool.do_maintenance(0, Timestamp::from(2), GasFees::default(), 0); assert_eq!(res.len(), 1); assert_eq!(res[0].0, po1.uo.hash(conf.entry_point, conf.chain_id)); assert_eq!(res[0].1, Timestamp::from(1)); @@ -1103,7 +1101,7 @@ mod tests { po3.valid_time_range.valid_until = 9.into(); let _ = pool.add_operation(po3.clone()).unwrap(); - let res = pool.do_maintenance(0, Timestamp::from(10), GasFees::default(), 0.into()); + let res = pool.do_maintenance(0, Timestamp::from(10), GasFees::default(), 0); assert_eq!(res.len(), 2); assert!(res.contains(&(po1.uo.hash(conf.entry_point, conf.chain_id), 5.into()))); @@ -1129,12 +1127,12 @@ mod tests { .mem_size() } - fn create_op(sender: Address, nonce: usize, max_fee_per_gas: usize) -> PoolOperation { + fn create_op(sender: Address, nonce: usize, max_fee_per_gas: u128) -> PoolOperation { PoolOperation { uo: UserOperation { sender, - nonce: nonce.into(), - max_fee_per_gas: max_fee_per_gas.into(), + nonce: U256::from(nonce), + max_fee_per_gas, ..UserOperation::default() } .into(), @@ -1150,8 +1148,8 @@ mod tests { entry_point: Address::random(), valid_time_range: ValidTimeRange::default(), aggregator: None, - expected_code_hash: H256::random(), - sim_block_hash: H256::random(), + expected_code_hash: B256::random(), + sim_block_hash: B256::random(), sim_block_number: 0, account_is_staked: false, } diff --git a/crates/pool/src/mempool/reputation.rs b/crates/pool/src/mempool/reputation.rs index aa81a0d28..ea1a8b3fe 100644 --- a/crates/pool/src/mempool/reputation.rs +++ b/crates/pool/src/mempool/reputation.rs @@ -16,7 +16,7 @@ use std::{ time::Duration, }; -use ethers::types::Address; +use alloy_primitives::Address; use parking_lot::RwLock; use rundler_types::pool::{Reputation, ReputationStatus}; use tokio::time::interval; diff --git a/crates/pool/src/mempool/uo_pool.rs b/crates/pool/src/mempool/uo_pool.rs index 2805def3a..b797e241f 100644 --- a/crates/pool/src/mempool/uo_pool.rs +++ b/crates/pool/src/mempool/uo_pool.rs @@ -13,10 +13,7 @@ use std::{collections::HashSet, marker::PhantomData, sync::Arc}; -use ethers::{ - types::{Address, H256, U256}, - utils::format_units, -}; +use alloy_primitives::{utils::format_units, Address, B256, U256}; use itertools::Itertools; use parking_lot::RwLock; use rundler_provider::EntryPoint; @@ -60,10 +57,10 @@ pub(crate) struct UoPool, + throttled_ops: HashSet, block_number: u64, gas_fees: GasFees, - base_fee: U256, + base_fee: u128, } impl UoPool @@ -87,7 +84,7 @@ where throttled_ops: HashSet::new(), block_number: 0, gas_fees: GasFees::default(), - base_fee: U256::zero(), + base_fee: 0, }), reputation, paymaster, @@ -384,7 +381,7 @@ where &self, origin: OperationOrigin, op: UserOperationVariant, - ) -> MempoolResult { + ) -> MempoolResult { // TODO(danc) aggregator reputation is not implemented // TODO(danc) catch ops with aggregators prior to simulation and reject @@ -540,7 +537,7 @@ where Ok(hash) } - fn remove_operations(&self, hashes: &[H256]) { + fn remove_operations(&self, hashes: &[B256]) { let mut count = 0; let mut removed_hashes = vec![]; { @@ -563,7 +560,7 @@ where UoPoolMetrics::increment_removed_operations(count, self.config.entry_point); } - fn remove_op_by_id(&self, id: &UserOperationId) -> MempoolResult> { + fn remove_op_by_id(&self, id: &UserOperationId) -> MempoolResult> { // Check for the operation in the pool and its age let po = { let state = self.state.read(); @@ -635,12 +632,13 @@ where Ok(ordered_ops .into_iter() .filter(|op| { + let sender_num = U256::from_be_bytes(op.uo.sender().into_word().into()); + // short-circuit the mod if there is only 1 shard ((self.config.num_shards == 1) || - (U256::from_little_endian(op.uo.sender().as_bytes()) - .div_mod(self.config.num_shards.into()) - .1 - == shard_index.into())) && + (sender_num + % U256::from(self.config.num_shards) + == U256::from(shard_index))) && // filter out ops from unstaked senders we've already seen if !op.account_is_staked { senders.insert(op.uo.sender()) @@ -657,7 +655,7 @@ where self.state.read().pool.best_operations().take(max).collect() } - fn get_user_operation_by_hash(&self, hash: H256) -> Option> { + fn get_user_operation_by_hash(&self, hash: B256) -> Option> { self.state.read().pool.get_operation_by_hash(hash) } @@ -733,7 +731,7 @@ impl UoPoolMetrics { mod tests { use std::collections::HashMap; - use ethers::types::{Bytes, H160}; + use alloy_primitives::Bytes; use mockall::Sequence; use rundler_provider::{DepositInfo, MockEntryPointV0_6}; use rundler_sim::{ @@ -828,7 +826,7 @@ mod tests { // after updates entrypoint .expect_get_balances() - .returning(|_| Ok(vec![1110.into()])); + .returning(|_| Ok(vec![U256::from(1110)])); let (pool, uos) = create_pool_with_entrypoint_insert_ops( vec![ @@ -843,7 +841,7 @@ mod tests { pool.on_chain_update(&ChainUpdate { latest_block_number: 1, - latest_block_hash: H256::random(), + latest_block_hash: B256::random(), latest_block_timestamp: 0.into(), earliest_remembered_block_number: 0, reorg_depth: 0, @@ -852,19 +850,19 @@ mod tests { hash: uos[0].hash(pool.config.entry_point, 1), sender: uos[0].sender(), nonce: uos[0].nonce(), - actual_gas_cost: U256::zero(), + actual_gas_cost: U256::ZERO, paymaster: None, }], unmined_ops: vec![], entity_balance_updates: vec![BalanceUpdate { address: paymaster, - amount: 100.into(), + amount: U256::from(100), entrypoint: pool.config.entry_point, is_addition: true, }], unmined_entity_balance_updates: vec![BalanceUpdate { address: paymaster, - amount: 10.into(), + amount: U256::from(10), entrypoint: pool.config.entry_point, is_addition: false, }], @@ -875,7 +873,7 @@ mod tests { check_ops(pool.best_operations(3, 0).unwrap(), uos[1..].to_vec()); let paymaster_balance = pool.paymaster.paymaster_balance(paymaster).await.unwrap(); - assert_eq!(paymaster_balance.confirmed_balance, 1110.into()); + assert_eq!(paymaster_balance.confirmed_balance, U256::from(1110)); } #[tokio::test] @@ -891,10 +889,10 @@ mod tests { // add pending max cost of 50 for each uo for op in &mut ops { let uo: &mut UserOperation = op.op.as_mut(); - uo.call_gas_limit = 10.into(); - uo.verification_gas_limit = 10.into(); - uo.pre_verification_gas = 10.into(); - uo.max_fee_per_gas = 1.into(); + uo.call_gas_limit = 10; + uo.verification_gas_limit = 10; + uo.pre_verification_gas = 10; + uo.max_fee_per_gas = 1; } let mut entrypoint = MockEntryPointV0_6::new(); @@ -910,25 +908,25 @@ mod tests { .expect_get_balances() .once() .in_sequence(&mut seq) - .returning(|_| Ok(vec![1080.into()])); + .returning(|_| Ok(vec![U256::from(1080)])); // Unmine UO of 10, unmine deposit of 100 // confirmed = 1080 + 10 - 100 = 990. Pending = 990 - 50*3 = 840 entrypoint .expect_get_balances() .once() .in_sequence(&mut seq) - .returning(|_| Ok(vec![990.into()])); + .returning(|_| Ok(vec![U256::from(990)])); let (pool, uos) = create_pool_with_entrypoint_insert_ops(ops, entrypoint).await; let metadata = pool.paymaster.paymaster_balance(paymaster).await.unwrap(); - assert_eq!(metadata.pending_balance, 850.into()); + assert_eq!(metadata.pending_balance, U256::from(850)); check_ops(pool.best_operations(3, 0).unwrap(), uos.clone()); // mine the first op with actual gas cost of 10 pool.on_chain_update(&ChainUpdate { latest_block_number: 1, - latest_block_hash: H256::random(), + latest_block_hash: B256::random(), latest_block_timestamp: 0.into(), earliest_remembered_block_number: 0, reorg_depth: 0, @@ -937,19 +935,19 @@ mod tests { hash: uos[0].hash(pool.config.entry_point, 1), sender: uos[0].sender(), nonce: uos[0].nonce(), - actual_gas_cost: 10.into(), + actual_gas_cost: U256::from(10), paymaster: Some(paymaster), }], unmined_ops: vec![], entity_balance_updates: vec![BalanceUpdate { address: paymaster, - amount: 100.into(), + amount: U256::from(100), entrypoint: pool.config.entry_point, is_addition: true, }], unmined_entity_balance_updates: vec![BalanceUpdate { address: paymaster, - amount: 10.into(), + amount: U256::from(10), entrypoint: pool.config.entry_point, is_addition: false, }], @@ -963,11 +961,11 @@ mod tests { ); let metadata = pool.paymaster.paymaster_balance(paymaster).await.unwrap(); - assert_eq!(metadata.pending_balance, 980.into()); + assert_eq!(metadata.pending_balance, U256::from(980)); pool.on_chain_update(&ChainUpdate { latest_block_number: 1, - latest_block_hash: H256::random(), + latest_block_hash: B256::random(), latest_block_timestamp: 0.into(), earliest_remembered_block_number: 0, reorg_depth: 0, @@ -977,13 +975,13 @@ mod tests { hash: uos[0].hash(pool.config.entry_point, 1), sender: uos[0].sender(), nonce: uos[0].nonce(), - actual_gas_cost: 10.into(), + actual_gas_cost: U256::from(10), paymaster: None, }], entity_balance_updates: vec![], unmined_entity_balance_updates: vec![BalanceUpdate { address: paymaster, - amount: 100.into(), + amount: U256::from(100), entrypoint: pool.config.entry_point, is_addition: true, }], @@ -992,7 +990,7 @@ mod tests { .await; let metadata = pool.paymaster.paymaster_balance(paymaster).await.unwrap(); - assert_eq!(metadata.pending_balance, 840.into()); + assert_eq!(metadata.pending_balance, U256::from(840)); check_ops(pool.best_operations(3, 0).unwrap(), uos); } @@ -1009,7 +1007,7 @@ mod tests { pool.on_chain_update(&ChainUpdate { latest_block_number: 1, - latest_block_hash: H256::random(), + latest_block_hash: B256::random(), latest_block_timestamp: 0.into(), earliest_remembered_block_number: 0, reorg_depth: 0, @@ -1018,7 +1016,7 @@ mod tests { hash: uos[0].hash(pool.config.entry_point, 1), sender: uos[0].sender(), nonce: uos[0].nonce(), - actual_gas_cost: U256::zero(), + actual_gas_cost: U256::ZERO, paymaster: None, }], unmined_ops: vec![], @@ -1051,7 +1049,7 @@ mod tests { pool.on_chain_update(&ChainUpdate { latest_block_number: 1, - latest_block_hash: H256::random(), + latest_block_hash: B256::random(), latest_block_timestamp: 0.into(), earliest_remembered_block_number: 0, reorg_depth: 0, @@ -1060,7 +1058,7 @@ mod tests { hash: uos[0].hash(pool.config.entry_point, 1), sender: uos[0].sender(), nonce: uos[0].nonce(), - actual_gas_cost: U256::zero(), + actual_gas_cost: U256::ZERO, paymaster: None, }], unmined_ops: vec![], @@ -1127,7 +1125,7 @@ mod tests { // Mine first op pool.on_chain_update(&ChainUpdate { latest_block_number: 1, - latest_block_hash: H256::random(), + latest_block_hash: B256::random(), latest_block_timestamp: 0.into(), earliest_remembered_block_number: 0, reorg_depth: 0, @@ -1136,7 +1134,7 @@ mod tests { hash: uos[0].hash(pool.config.entry_point, 1), sender: uos[0].sender(), nonce: uos[0].nonce(), - actual_gas_cost: U256::zero(), + actual_gas_cost: U256::ZERO, paymaster: None, }], entity_balance_updates: vec![], @@ -1191,10 +1189,10 @@ mod tests { let paymaster = Address::random(); let mut op = create_op(Address::random(), 0, 0, Some(paymaster)); let uo: &mut UserOperation = op.op.as_mut(); - uo.call_gas_limit = 1000.into(); - uo.verification_gas_limit = 1000.into(); - uo.pre_verification_gas = 1000.into(); - uo.max_fee_per_gas = 1.into(); + uo.call_gas_limit = 1000; + uo.verification_gas_limit = 1000; + uo.pre_verification_gas = 1000; + uo.max_fee_per_gas = 1; let mut entrypoint = MockEntryPointV0_6::new(); entrypoint @@ -1286,7 +1284,7 @@ mod tests { let mut replacement = op.op.clone(); let r: &mut UserOperation = replacement.as_mut(); - r.max_fee_per_gas = r.max_fee_per_gas + 1; + r.max_fee_per_gas += 1; let err = pool .add_operation(OperationOrigin::Local, replacement) @@ -1303,16 +1301,16 @@ mod tests { let mut entrypoint = MockEntryPointV0_6::new(); entrypoint.expect_get_deposit_info().returning(|_| { Ok(DepositInfo { - deposit: 1000.into(), + deposit: U256::from(1000), staked: true, - stake: 10000, + stake: U256::from(10000), unstake_delay_sec: 100, withdraw_time: 10, }) }); let mut pool = create_pool_with_entry_point(vec![], entrypoint); - pool.config.sim_settings.min_stake_value = 10001; + pool.config.sim_settings.min_stake_value = U256::from(10001); pool.config.sim_settings.min_unstake_delay = 101; let status = pool.get_stake_status(Address::random()).await.unwrap(); @@ -1326,10 +1324,10 @@ mod tests { let mut op = create_op(Address::random(), 0, 5, Some(paymaster)); let uo: &mut UserOperation = op.op.as_mut(); - uo.call_gas_limit = 10.into(); - uo.verification_gas_limit = 10.into(); - uo.pre_verification_gas = 10.into(); - uo.max_fee_per_gas = 1.into(); + uo.call_gas_limit = 10; + uo.verification_gas_limit = 10; + uo.pre_verification_gas = 10; + uo.max_fee_per_gas = 1; let mut entrypoint = MockEntryPointV0_6::new(); entrypoint @@ -1344,7 +1342,7 @@ mod tests { let mut replacement = op.op.clone(); let r: &mut UserOperation = replacement.as_mut(); - r.max_fee_per_gas = r.max_fee_per_gas + 1; + r.max_fee_per_gas += 1; let _ = pool .add_operation(OperationOrigin::Local, replacement.clone()) @@ -1431,7 +1429,7 @@ mod tests { assert!(matches!( pool.remove_op_by_id(&UserOperationId { sender: Address::random(), - nonce: 0.into() + nonce: U256::ZERO }), Ok(None) )); @@ -1469,14 +1467,14 @@ mod tests { .await .unwrap(); - let pool_op = pool.get_user_operation_by_hash(H256::random()); + let pool_op = pool.get_user_operation_by_hash(B256::random()); assert_eq!(pool_op, None); } #[tokio::test] async fn too_many_ops_for_unstaked_sender() { let mut ops = vec![]; - let addr = H160::random(); + let addr = Address::random(); for i in 0..5 { ops.push(create_op(addr, i, 1, None)) } @@ -1579,10 +1577,10 @@ mod tests { prechecker.expect_update_fees().returning(|| { Ok(( GasFees { - max_fee_per_gas: 0.into(), - max_priority_fee_per_gas: 0.into(), + max_fee_per_gas: 0, + max_priority_fee_per_gas: 0, }, - 0.into(), + 0, )) }); @@ -1674,20 +1672,20 @@ mod tests { fn create_op( sender: Address, nonce: usize, - max_fee_per_gas: usize, + max_fee_per_gas: u128, paymaster: Option
, ) -> OpWithErrors { let mut paymaster_and_data = Bytes::new(); if let Some(paymaster) = paymaster { - paymaster_and_data = paymaster.to_fixed_bytes().into(); + paymaster_and_data = paymaster.to_vec().into(); } OpWithErrors { op: UserOperation { sender, - nonce: nonce.into(), - max_fee_per_gas: max_fee_per_gas.into(), + nonce: U256::from(nonce), + max_fee_per_gas, paymaster_and_data, ..UserOperation::default() } @@ -1702,7 +1700,7 @@ mod tests { fn create_op_with_errors( sender: Address, nonce: usize, - max_fee_per_gas: usize, + max_fee_per_gas: u128, precheck_error: Option, simulation_error: Option, staked: bool, @@ -1710,8 +1708,8 @@ mod tests { OpWithErrors { op: UserOperation { sender, - nonce: nonce.into(), - max_fee_per_gas: max_fee_per_gas.into(), + nonce: U256::from(nonce), + max_fee_per_gas, ..UserOperation::default() } .into(), diff --git a/crates/pool/src/server/local.rs b/crates/pool/src/server/local.rs index f7413b2d6..b6ac9f663 100644 --- a/crates/pool/src/server/local.rs +++ b/crates/pool/src/server/local.rs @@ -13,9 +13,9 @@ use std::{collections::HashMap, future::Future, pin::Pin, sync::Arc}; +use alloy_primitives::{Address, B256}; use async_stream::stream; use async_trait::async_trait; -use ethers::types::{Address, H256}; use futures::future; use futures_util::Stream; use rundler_task::server::{HealthCheck, ServerStatus}; @@ -128,7 +128,7 @@ impl Pool for LocalPoolHandle { } } - async fn add_op(&self, entry_point: Address, op: UserOperationVariant) -> PoolResult { + async fn add_op(&self, entry_point: Address, op: UserOperationVariant) -> PoolResult { let req = ServerRequestKind::AddOp { entry_point, op, @@ -159,7 +159,7 @@ impl Pool for LocalPoolHandle { } } - async fn get_op_by_hash(&self, hash: H256) -> PoolResult> { + async fn get_op_by_hash(&self, hash: B256) -> PoolResult> { let req = ServerRequestKind::GetOpByHash { hash }; let resp = self.send(req).await?; match resp { @@ -168,7 +168,7 @@ impl Pool for LocalPoolHandle { } } - async fn remove_ops(&self, entry_point: Address, ops: Vec) -> PoolResult<()> { + async fn remove_ops(&self, entry_point: Address, ops: Vec) -> PoolResult<()> { let req = ServerRequestKind::RemoveOps { entry_point, ops }; let resp = self.send(req).await?; match resp { @@ -181,7 +181,7 @@ impl Pool for LocalPoolHandle { &self, entry_point: Address, id: UserOperationId, - ) -> PoolResult> { + ) -> PoolResult> { let req = ServerRequestKind::RemoveOpById { entry_point, id }; let resp = self.send(req).await?; match resp { @@ -393,7 +393,7 @@ impl LocalPoolServerRunner { .collect()) } - fn get_op_by_hash(&self, hash: H256) -> PoolResult> { + fn get_op_by_hash(&self, hash: B256) -> PoolResult> { for mempool in self.mempools.values() { if let Some(op) = mempool.get_user_operation_by_hash(hash) { return Ok(Some((*op).clone())); @@ -402,7 +402,7 @@ impl LocalPoolServerRunner { Ok(None) } - fn remove_ops(&self, entry_point: Address, ops: &[H256]) -> PoolResult<()> { + fn remove_ops(&self, entry_point: Address, ops: &[B256]) -> PoolResult<()> { let mempool = self.get_pool(entry_point)?; mempool.remove_operations(ops); Ok(()) @@ -412,7 +412,7 @@ impl LocalPoolServerRunner { &self, entry_point: Address, id: &UserOperationId, - ) -> PoolResult> { + ) -> PoolResult> { let mempool = self.get_pool(entry_point)?; mempool.remove_op_by_id(id).map_err(|e| e.into()) } @@ -711,11 +711,11 @@ enum ServerRequestKind { shard_index: u64, }, GetOpByHash { - hash: H256, + hash: B256, }, RemoveOps { entry_point: Address, - ops: Vec, + ops: Vec, }, RemoveOpById { entry_point: Address, @@ -765,7 +765,7 @@ enum ServerResponse { entry_points: Vec
, }, AddOp { - hash: H256, + hash: B256, }, GetOps { ops: Vec, @@ -775,7 +775,7 @@ enum ServerResponse { }, RemoveOps, RemoveOpById { - hash: Option, + hash: Option, }, UpdateEntities, DebugClearState, @@ -814,7 +814,7 @@ mod tests { #[tokio::test] async fn test_add_op() { let mut mock_pool = MockMempool::new(); - let hash0 = H256::random(); + let hash0 = B256::random(); mock_pool .expect_entry_point_version() .returning(|| EntryPointVersion::V0_6); @@ -841,7 +841,7 @@ mod tests { let mut sub = state.handle.subscribe_new_heads().await.unwrap(); - let hash = H256::random(); + let hash = B256::random(); let number = 1234; state .chain_update_tx @@ -881,9 +881,9 @@ mod tests { async fn test_multiple_entry_points() { let eps = [Address::random(), Address::random(), Address::random()]; let mut pools = [MockMempool::new(), MockMempool::new(), MockMempool::new()]; - let h0 = H256::random(); - let h1 = H256::random(); - let h2 = H256::random(); + let h0 = B256::random(); + let h1 = B256::random(); + let h2 = B256::random(); let hashes = [h0, h1, h2]; pools[0] .expect_entry_point_version() diff --git a/crates/pool/src/server/remote/client.rs b/crates/pool/src/server/remote/client.rs index faf8e13f3..532fa185e 100644 --- a/crates/pool/src/server/remote/client.rs +++ b/crates/pool/src/server/remote/client.rs @@ -13,8 +13,8 @@ use std::{pin::Pin, str::FromStr}; +use alloy_primitives::{Address, B256}; use anyhow::Context; -use ethers::types::{Address, H256}; use futures_util::Stream; use rundler_task::{ grpc::protos::{from_bytes, ConversionError, ToProtoBytes}, @@ -145,12 +145,12 @@ impl Pool for RemotePoolClient { .map_err(anyhow::Error::from)?) } - async fn add_op(&self, entry_point: Address, op: UserOperationVariant) -> PoolResult { + async fn add_op(&self, entry_point: Address, op: UserOperationVariant) -> PoolResult { let res = self .op_pool_client .clone() .add_op(AddOpRequest { - entry_point: entry_point.as_bytes().to_vec(), + entry_point: entry_point.to_vec(), op: Some(protos::UserOperation::from(&op)), }) .await @@ -159,7 +159,7 @@ impl Pool for RemotePoolClient { .result; match res { - Some(add_op_response::Result::Success(s)) => Ok(H256::from_slice(&s.hash)), + Some(add_op_response::Result::Success(s)) => Ok(B256::from_slice(&s.hash)), Some(add_op_response::Result::Failure(f)) => Err(f.try_into()?), None => Err(PoolError::Other(anyhow::anyhow!( "should have received result from op pool" @@ -177,7 +177,7 @@ impl Pool for RemotePoolClient { .op_pool_client .clone() .get_ops(GetOpsRequest { - entry_point: entry_point.as_bytes().to_vec(), + entry_point: entry_point.to_vec(), max_ops, shard_index, }) @@ -203,12 +203,12 @@ impl Pool for RemotePoolClient { } } - async fn get_op_by_hash(&self, hash: H256) -> PoolResult> { + async fn get_op_by_hash(&self, hash: B256) -> PoolResult> { let res = self .op_pool_client .clone() .get_op_by_hash(protos::GetOpByHashRequest { - hash: hash.as_bytes().to_vec(), + hash: hash.to_proto_bytes(), }) .await .map_err(anyhow::Error::from)? @@ -235,13 +235,13 @@ impl Pool for RemotePoolClient { } } - async fn remove_ops(&self, entry_point: Address, ops: Vec) -> PoolResult<()> { + async fn remove_ops(&self, entry_point: Address, ops: Vec) -> PoolResult<()> { let res = self .op_pool_client .clone() .remove_ops(RemoveOpsRequest { - entry_point: entry_point.as_bytes().to_vec(), - hashes: ops.into_iter().map(|h| h.as_bytes().to_vec()).collect(), + entry_point: entry_point.to_vec(), + hashes: ops.into_iter().map(|h| h.to_proto_bytes()).collect(), }) .await .map_err(anyhow::Error::from)? @@ -261,7 +261,7 @@ impl Pool for RemotePoolClient { &self, entry_point: Address, id: UserOperationId, - ) -> PoolResult> { + ) -> PoolResult> { let res = self .op_pool_client .clone() @@ -280,7 +280,7 @@ impl Pool for RemotePoolClient { if s.hash.is_empty() { Ok(None) } else { - Ok(Some(H256::from_slice(&s.hash))) + Ok(Some(B256::from_slice(&s.hash))) } } Some(remove_op_by_id_response::Result::Failure(f)) => Err(f.try_into()?), @@ -299,7 +299,7 @@ impl Pool for RemotePoolClient { .op_pool_client .clone() .update_entities(UpdateEntitiesRequest { - entry_point: entry_point.as_bytes().to_vec(), + entry_point: entry_point.to_vec(), entity_updates: entity_updates .iter() .map(protos::EntityUpdate::from) @@ -357,7 +357,7 @@ impl Pool for RemotePoolClient { .op_pool_client .clone() .admin_set_tracking(AdminSetTrackingRequest { - entry_point: entry_point.as_bytes().to_vec(), + entry_point: entry_point.to_vec(), reputation, paymaster, }) @@ -380,7 +380,7 @@ impl Pool for RemotePoolClient { .op_pool_client .clone() .debug_dump_mempool(DebugDumpMempoolRequest { - entry_point: entry_point.as_bytes().to_vec(), + entry_point: entry_point.to_vec(), }) .await .map_err(anyhow::Error::from)? @@ -413,7 +413,7 @@ impl Pool for RemotePoolClient { .op_pool_client .clone() .debug_set_reputation(DebugSetReputationRequest { - entry_point: entry_point.as_bytes().to_vec(), + entry_point: entry_point.to_vec(), reputations: reputations .into_iter() .map(protos::Reputation::from) @@ -438,7 +438,7 @@ impl Pool for RemotePoolClient { .op_pool_client .clone() .debug_dump_reputation(DebugDumpReputationRequest { - entry_point: entry_point.as_bytes().to_vec(), + entry_point: entry_point.to_vec(), }) .await .map_err(anyhow::Error::from)? @@ -467,7 +467,7 @@ impl Pool for RemotePoolClient { .op_pool_client .clone() .debug_dump_paymaster_balances(DebugDumpPaymasterBalancesRequest { - entry_point: entry_point.as_bytes().to_vec(), + entry_point: entry_point.to_vec(), }) .await .map_err(anyhow::Error::from)? @@ -497,8 +497,8 @@ impl Pool for RemotePoolClient { .op_pool_client .clone() .get_reputation_status(GetReputationStatusRequest { - entry_point: entry_point.as_bytes().to_vec(), - address: address.as_bytes().to_vec(), + entry_point: entry_point.to_vec(), + address: address.to_vec(), }) .await .map_err(anyhow::Error::from)? @@ -528,8 +528,8 @@ impl Pool for RemotePoolClient { .op_pool_client .clone() .get_stake_status(GetStakeStatusRequest { - entry_point: entry_point.as_bytes().to_vec(), - address: address.as_bytes().to_vec(), + entry_point: entry_point.to_vec(), + address: address.to_vec(), }) .await .map_err(anyhow::Error::from)? diff --git a/crates/pool/src/server/remote/error.rs b/crates/pool/src/server/remote/error.rs index 4a616ddf2..30809e7be 100644 --- a/crates/pool/src/server/remote/error.rs +++ b/crates/pool/src/server/remote/error.rs @@ -11,6 +11,7 @@ // You should have received a copy of the GNU General Public License along with Rundler. // If not, see https://www.gnu.org/licenses/. +use alloy_sol_types::Panic; use anyhow::{bail, Context}; use rundler_task::grpc::protos::{from_bytes, ToProtoBytes}; use rundler_types::{ @@ -30,7 +31,7 @@ use super::protos::{ InvalidAccountSignature, InvalidPaymasterSignature, InvalidSignature, InvalidStorageAccess, InvalidTimeRange, MaxFeePerGasTooLow, MaxOperationsReachedError, MaxPriorityFeePerGasTooLow, MempoolError as ProtoMempoolError, MultipleRolesViolation, NotStaked, - OperationAlreadyKnownError, OperationDropTooSoon, OperationRevert, OutOfGas, + OperationAlreadyKnownError, OperationDropTooSoon, OperationRevert, OutOfGas, PanicRevert, PaymasterBalanceTooLow, PaymasterDepositTooLow, PaymasterIsNotContract, PreVerificationGasTooLow, PrecheckViolationError as ProtoPrecheckViolationError, ReplacementUnderpricedError, SenderAddressUsedAsAlternateEntity, SenderFundsTooLow, @@ -535,7 +536,7 @@ impl From for ProtoSimulationViolationError { accessed_entity: EntityType::from(stake_data.accessed_entity) as i32, slot: stake_data.slot.to_proto_bytes(), min_stake: stake_data.min_stake.to_proto_bytes(), - min_unstake_delay: stake_data.min_unstake_delay.to_proto_bytes(), + min_unstake_delay: stake_data.min_unstake_delay, }, )), }, @@ -750,7 +751,7 @@ impl TryFrom for SimulationViolation { accessed_entity, slot: from_bytes(&e.slot)?, min_stake: from_bytes(&e.min_stake)?, - min_unstake_delay: from_bytes(&e.min_unstake_delay)?, + min_unstake_delay: e.min_unstake_delay, })) } Some(simulation_violation_error::Violation::UnintendedRevert(e)) => { @@ -845,6 +846,9 @@ impl From for ProtoValidationRevert { revert_bytes: revert_bytes.to_vec(), }) } + ValidationRevert::Panic(panic) => validation_revert::Revert::Panic(PanicRevert { + code: panic.code.to_proto_bytes(), + }), }; ProtoValidationRevert { revert: Some(inner), @@ -868,6 +872,9 @@ impl TryFrom for ValidationRevert { Some(validation_revert::Revert::Unknown(e)) => { ValidationRevert::Unknown(e.revert_bytes.into()) } + Some(validation_revert::Revert::Panic(e)) => ValidationRevert::Panic(Panic { + code: from_bytes(&e.code)?, + }), None => { bail!("unknown proto validation revert") } @@ -877,6 +884,8 @@ impl TryFrom for ValidationRevert { #[cfg(test)] mod tests { + use alloy_primitives::U256; + use super::*; #[test] @@ -893,15 +902,15 @@ mod tests { #[test] fn test_precheck_error() { let error = MempoolError::PrecheckViolation(PrecheckViolation::SenderFundsTooLow( - 0.into(), - 0.into(), + U256::ZERO, + U256::ZERO, )); let proto_error: ProtoMempoolError = error.into(); let error2 = proto_error.try_into().unwrap(); match error2 { MempoolError::PrecheckViolation(PrecheckViolation::SenderFundsTooLow(x, y)) => { - assert_eq!(x, 0.into()); - assert_eq!(y, 0.into()); + assert_eq!(x, U256::ZERO); + assert_eq!(y, U256::ZERO); } _ => panic!("wrong error type"), } diff --git a/crates/pool/src/server/remote/protos.rs b/crates/pool/src/server/remote/protos.rs index f4ba84133..9d7466481 100644 --- a/crates/pool/src/server/remote/protos.rs +++ b/crates/pool/src/server/remote/protos.rs @@ -11,8 +11,8 @@ // You should have received a copy of the GNU General Public License along with Rundler. // If not, see https://www.gnu.org/licenses/. +use alloy_primitives::{Address, B256}; use anyhow::{anyhow, Context}; -use ethers::types::{Address, H256}; use rundler_task::grpc::protos::{from_bytes, ConversionError, ToProtoBytes}; use rundler_types::{ chain::ChainSpec, @@ -322,8 +322,8 @@ impl TryFrom for RundlerStakeStatus { return Ok(RundlerStakeStatus { is_staked: stake_status.is_staked, stake_info: RundlerStakeInfo { - stake: stake_info.stake.into(), - unstake_delay_sec: stake_info.unstake_delay_sec.into(), + stake: from_bytes(&stake_info.stake)?, + unstake_delay_sec: stake_info.unstake_delay_sec, }, }); } @@ -337,8 +337,8 @@ impl From for StakeStatus { StakeStatus { is_staked: stake_status.is_staked, stake_info: Some(StakeInfo { - stake: stake_status.stake_info.stake.as_u64(), - unstake_delay_sec: stake_status.stake_info.unstake_delay_sec.as_u32(), + stake: stake_status.stake_info.stake.to_proto_bytes(), + unstake_delay_sec: stake_status.stake_info.unstake_delay_sec, }), } } @@ -377,8 +377,8 @@ impl TryUoFromProto for PoolOperation { let valid_time_range = ValidTimeRange::new(op.valid_after.into(), op.valid_until.into()); - let expected_code_hash = H256::from_slice(&op.expected_code_hash); - let sim_block_hash = H256::from_slice(&op.sim_block_hash); + let expected_code_hash = B256::from_slice(&op.expected_code_hash); + let sim_block_hash = B256::from_slice(&op.sim_block_hash); Ok(PoolOperation { uo, @@ -429,7 +429,7 @@ impl TryFrom for PoolPaymasterMetadata { impl From for PaymasterBalance { fn from(paymaster_metadata: PoolPaymasterMetadata) -> Self { Self { - address: paymaster_metadata.address.as_bytes().to_vec(), + address: paymaster_metadata.address.to_vec(), confirmed_balance: paymaster_metadata.confirmed_balance.to_proto_bytes(), pending_balance: paymaster_metadata.pending_balance.to_proto_bytes(), } diff --git a/crates/pool/src/server/remote/server.rs b/crates/pool/src/server/remote/server.rs index 51679591a..13953dfe4 100644 --- a/crates/pool/src/server/remote/server.rs +++ b/crates/pool/src/server/remote/server.rs @@ -19,8 +19,8 @@ use std::{ }, }; +use alloy_primitives::{Address, B256}; use async_trait::async_trait; -use ethers::types::{Address, H256}; use futures_util::StreamExt; use rundler_task::grpc::{metrics::GrpcMetricsLayer, protos::from_bytes}; use rundler_types::{ @@ -127,10 +127,7 @@ impl OpPool for OpPoolImpl { let resp = match self.local_pool.get_supported_entry_points().await { Ok(entry_points) => GetSupportedEntryPointsResponse { chain_id: self.chain_spec.id, - entry_points: entry_points - .into_iter() - .map(|ep| ep.as_bytes().to_vec()) - .collect(), + entry_points: entry_points.into_iter().map(|ep| ep.to_vec()).collect(), }, Err(e) => { return Err(Status::internal(format!("Failed to get entry points: {e}"))); @@ -155,7 +152,7 @@ impl OpPool for OpPoolImpl { let resp = match self.local_pool.add_op(ep, uo).await { Ok(hash) => AddOpResponse { result: Some(add_op_response::Result::Success(AddOpSuccess { - hash: hash.as_bytes().to_vec(), + hash: hash.to_vec(), })), }, Err(error) => AddOpResponse { @@ -221,14 +218,14 @@ impl OpPool for OpPoolImpl { let req = request.into_inner(); let ep = self.get_entry_point(&req.entry_point)?; - let hashes: Vec = req + let hashes: Vec = req .hashes .into_iter() .map(|h| { if h.len() != 32 { return Err(Status::invalid_argument("Hash must be 32 bytes long")); } - Ok(H256::from_slice(&h)) + Ok(B256::from_slice(&h)) }) .collect::, _>>()?; @@ -267,7 +264,7 @@ impl OpPool for OpPoolImpl { Ok(hash) => RemoveOpByIdResponse { result: Some(remove_op_by_id_response::Result::Success( RemoveOpByIdSuccess { - hash: hash.map_or(vec![], |h| h.as_bytes().to_vec()), + hash: hash.map_or(vec![], |h| h.to_vec()), }, )), }, diff --git a/crates/pool/src/task.rs b/crates/pool/src/task.rs index 4e1d5cc88..908b32f9e 100644 --- a/crates/pool/src/task.rs +++ b/crates/pool/src/task.rs @@ -15,8 +15,9 @@ use std::{collections::HashMap, net::SocketAddr, sync::Arc, time::Duration}; use anyhow::{bail, Context}; use async_trait::async_trait; -use rundler_provider::{EntryPointProvider, Provider}; +use rundler_provider::{EntryPointProvider, EvmProvider}; use rundler_sim::{ + gas::{self, FeeEstimatorImpl}, simulation::{self, UnsafeSimulator}, PrecheckerImpl, Simulator, }; @@ -68,7 +69,7 @@ pub struct PoolTask { args: Args, event_sender: broadcast::Sender>, pool_builder: LocalPoolBuilder, - provider: Arc

, + provider: P, ep_06: Option, ep_07: Option, } @@ -76,10 +77,14 @@ pub struct PoolTask { #[async_trait] impl Task for PoolTask where - P: Provider, - E06: EntryPointProvider, - E07: EntryPointProvider, + P: EvmProvider + Clone + 'static, + E06: EntryPointProvider + Clone + 'static, + E07: EntryPointProvider + Clone + 'static, { + fn boxed(self) -> Box { + Box::new(self) + } + async fn run(mut self: Box, shutdown_token: CancellationToken) -> anyhow::Result<()> { let chain_id = self.args.chain_spec.id; tracing::info!("Chain id: {chain_id}"); @@ -97,13 +102,14 @@ where .map(|config| (config.entry_point, config.entry_point_version)) .collect(), }; - let provider = rundler_provider::new_provider( - &self.args.http_url, - Some(self.args.chain_poll_interval), - )?; - let chain = Chain::new(provider.clone(), chain_settings); + + let chain = Chain::new(self.provider.clone(), chain_settings); let (update_sender, _) = broadcast::channel(self.args.chain_update_channel_capacity); - let chain_handle = chain.spawn_watcher(update_sender.clone(), shutdown_token.clone()); + let chain_handle = tokio::spawn({ + let update_sender = update_sender.clone(); + let shutdown_token = shutdown_token.clone(); + async move { chain.watch(update_sender, shutdown_token).await } + }); // create mempools let mut mempools = HashMap::new(); @@ -182,7 +188,7 @@ impl PoolTask { args: Args, event_sender: broadcast::Sender>, pool_builder: LocalPoolBuilder, - provider: Arc

, + provider: P, ep_06: Option, ep_07: Option, ) -> Self { @@ -197,24 +203,19 @@ impl PoolTask { } } -impl PoolTask +impl<'a, P, E06, E07> PoolTask where - P: Provider, - E06: EntryPointProvider, - E07: EntryPointProvider, + P: EvmProvider + Clone + 'a, + E06: EntryPointProvider + Clone + 'a, + E07: EntryPointProvider + Clone + 'a, { - /// Convert this task into a boxed task. - pub fn boxed(self) -> Box { - Box::new(self) - } - fn create_mempool_v0_6( &self, chain_spec: ChainSpec, pool_config: &PoolConfig, unsafe_mode: bool, event_sender: broadcast::Sender>, - ) -> anyhow::Result> { + ) -> anyhow::Result> { let ep = self .ep_06 .clone() @@ -222,7 +223,7 @@ where if unsafe_mode { let simulator = UnsafeSimulator::new( - Arc::clone(&self.provider), + self.provider.clone(), ep.clone(), pool_config.sim_settings.clone(), ); @@ -230,13 +231,13 @@ where chain_spec, pool_config, event_sender, - Arc::clone(&self.provider), + self.provider.clone(), ep.clone(), simulator, ) } else { let simulator = simulation::new_v0_6_simulator( - Arc::clone(&self.provider), + self.provider.clone(), ep.clone(), pool_config.sim_settings.clone(), pool_config.mempool_channel_configs.clone(), @@ -245,7 +246,7 @@ where chain_spec, pool_config, event_sender, - Arc::clone(&self.provider), + self.provider.clone(), ep.clone(), simulator, ) @@ -258,7 +259,7 @@ where pool_config: &PoolConfig, unsafe_mode: bool, event_sender: broadcast::Sender>, - ) -> anyhow::Result> { + ) -> anyhow::Result> { let ep = self .ep_07 .clone() @@ -266,7 +267,7 @@ where if unsafe_mode { let simulator = UnsafeSimulator::new( - Arc::clone(&self.provider), + self.provider.clone(), ep.clone(), pool_config.sim_settings.clone(), ); @@ -274,13 +275,13 @@ where chain_spec, pool_config, event_sender, - Arc::clone(&self.provider), + self.provider.clone(), ep.clone(), simulator, ) } else { let simulator = simulation::new_v0_7_simulator( - Arc::clone(&self.provider), + self.provider.clone(), ep.clone(), pool_config.sim_settings.clone(), pool_config.mempool_channel_configs.clone(), @@ -289,7 +290,7 @@ where chain_spec, pool_config, event_sender, - Arc::clone(&self.provider), + self.provider.clone(), ep.clone(), simulator, ) @@ -300,21 +301,31 @@ where chain_spec: ChainSpec, pool_config: &PoolConfig, event_sender: broadcast::Sender>, - provider: Arc

, + provider: P, ep: E, simulator: S, - ) -> anyhow::Result> + ) -> anyhow::Result> where UO: UserOperation + From + Into, UserOperationVariant: From, - P: Provider, - E: EntryPointProvider + Clone, - S: Simulator, + E: EntryPointProvider + Clone + 'a, + S: Simulator + 'a, { + let fee_oracle = gas::get_fee_oracle(&chain_spec, provider.clone()); + let fee_estimator = FeeEstimatorImpl::new( + provider.clone(), + fee_oracle, + pool_config.precheck_settings.priority_fee_mode, + pool_config + .precheck_settings + .bundle_priority_fee_overhead_percent, + ); + let prechecker = PrecheckerImpl::new( chain_spec, - Arc::clone(&provider), + provider.clone(), ep.clone(), + fee_estimator, pool_config.precheck_settings, ); diff --git a/crates/provider/src/alloy/entry_point/optimism.rs b/crates/provider/src/alloy/entry_point/optimism.rs index 61b2bb639..17a1e0742 100644 --- a/crates/provider/src/alloy/entry_point/optimism.rs +++ b/crates/provider/src/alloy/entry_point/optimism.rs @@ -11,7 +11,7 @@ // You should have received a copy of the GNU General Public License along with Rundler. // If not, see https://www.gnu.org/licenses/. -use alloy_primitives::{ruint::UintTryTo, Address, Bytes}; +use alloy_primitives::{Address, Bytes}; use alloy_provider::Provider as AlloyProvider; use alloy_sol_types::sol; use alloy_transport::Transport; @@ -40,7 +40,7 @@ pub(crate) async fn estimate_l1_gas, T: Transport + Clone>( .call() .await? ._0 - .uint_try_to() + .try_into() .context("failed to convert L1 fee to u128")?; Ok(l1_fee.checked_div(gas_price).unwrap_or(u128::MAX)) diff --git a/crates/provider/src/alloy/entry_point/v0_6.rs b/crates/provider/src/alloy/entry_point/v0_6.rs index 2486370f0..1832a438b 100644 --- a/crates/provider/src/alloy/entry_point/v0_6.rs +++ b/crates/provider/src/alloy/entry_point/v0_6.rs @@ -12,7 +12,7 @@ // If not, see https://www.gnu.org/licenses/. use alloy_contract::Error as ContractError; -use alloy_primitives::{ruint::UintTryTo, Address, Bytes, U256}; +use alloy_primitives::{Address, Bytes, U256}; use alloy_provider::Provider as AlloyProvider; use alloy_rpc_types_eth::{state::StateOverride, BlockId, TransactionRequest}; use alloy_sol_types::{ContractError as SolContractError, SolCall, SolError, SolInterface}; @@ -224,7 +224,7 @@ where } _ => Ok(HandleOpsOut::FailedOp( opIndex - .uint_try_to() + .try_into() .context("returned opIndex out of bounds")?, reason, )), @@ -497,15 +497,13 @@ impl TryFrom for ExecutionResult { fn try_from(result: ExecutionResultV0_6) -> Result { Ok(ExecutionResult { - pre_op_gas: UintTryTo::::uint_try_to(&result.preOpGas) + pre_op_gas: result + .preOpGas + .try_into() .context("preOpGas should fit in u128")?, paid: result.paid, - valid_after: UintTryTo::::uint_try_to(&result.validAfter) - .unwrap() - .into(), - valid_until: UintTryTo::::uint_try_to(&result.validUntil) - .unwrap() - .into(), + valid_after: result.validAfter.to::().into(), + valid_until: result.validUntil.to::().into(), target_success: result.targetSuccess, target_result: result.targetResult, }) @@ -519,7 +517,7 @@ impl From for DepositInfo { staked: deposit_info.staked, stake: U256::from(deposit_info.stake), unstake_delay_sec: deposit_info.unstakeDelaySec, - withdraw_time: UintTryTo::::uint_try_to(&deposit_info.withdrawTime).unwrap(), + withdraw_time: deposit_info.withdrawTime.to(), } } } diff --git a/crates/provider/src/alloy/entry_point/v0_7.rs b/crates/provider/src/alloy/entry_point/v0_7.rs index 67c0d1fe3..afc39f598 100644 --- a/crates/provider/src/alloy/entry_point/v0_7.rs +++ b/crates/provider/src/alloy/entry_point/v0_7.rs @@ -13,7 +13,7 @@ use alloy_contract::Error as ContractError; use alloy_json_rpc::ErrorPayload; -use alloy_primitives::{ruint::UintTryTo, Address, Bytes, U256}; +use alloy_primitives::{Address, Bytes, U256}; use alloy_provider::Provider as AlloyProvider; use alloy_rpc_types_eth::{ state::{AccountOverride, StateOverride}, @@ -229,7 +229,7 @@ where } _ => Ok(HandleOpsOut::FailedOp( opIndex - .uint_try_to() + .try_into() .context("returned opIndex out of bounds")?, reason, )), @@ -495,7 +495,7 @@ impl From for DepositInfo { staked: deposit_info.staked, stake: U256::from(deposit_info.stake), unstake_delay_sec: deposit_info.unstakeDelaySec, - withdraw_time: UintTryTo::::uint_try_to(&deposit_info.withdrawTime).unwrap(), + withdraw_time: deposit_info.withdrawTime.to(), } } } @@ -511,7 +511,9 @@ impl TryFrom for ExecutionResult { .intersect(paymaster.valid_time_range()); Ok(ExecutionResult { - pre_op_gas: UintTryTo::::uint_try_to(&result.preOpGas) + pre_op_gas: result + .preOpGas + .try_into() .context("preOpGas should fit in u128")?, paid: result.paid, valid_after: intersect_range.valid_after, diff --git a/crates/sim/src/simulation/v0_6/context.rs b/crates/sim/src/simulation/v0_6/context.rs index 032bd161c..439e7eb79 100644 --- a/crates/sim/src/simulation/v0_6/context.rs +++ b/crates/sim/src/simulation/v0_6/context.rs @@ -159,7 +159,8 @@ where // This is a special case to cover a bug in the 0.6 entrypoint contract where a specially // crafted UO can use extra verification gas that isn't caught during simulation, but when // it runs on chain causes the transaction to revert. - let verification_gas_used = entry_point_out.return_info.pre_op_gas - op.pre_verification_gas(); + let verification_gas_used = + entry_point_out.return_info.pre_op_gas - op.pre_verification_gas(); let verification_buffer = op .total_verification_gas_limit() .saturating_sub(verification_gas_used); diff --git a/crates/types/src/validation_results.rs b/crates/types/src/validation_results.rs index 59deb0819..d6fb37cd4 100644 --- a/crates/types/src/validation_results.rs +++ b/crates/types/src/validation_results.rs @@ -13,7 +13,7 @@ use std::{cmp::Ordering, ops::Add}; -use alloy_primitives::{address, ruint::UintTryTo, Address, Bytes, U256}; +use alloy_primitives::{address, Address, Bytes, U256}; use alloy_sol_types::{Panic, Revert, SolError}; use rundler_contracts::{ v0_6::{ @@ -279,13 +279,14 @@ impl TryFrom for ValidationReturnInfo { paymasterContext, } = value; Ok(Self { - pre_op_gas: UintTryTo::::uint_try_to(&preOpGas) + pre_op_gas: preOpGas + .try_into() .map_err(|_| "preOpGas is larger than u128")?, // In v0.6 if one signature fails both do account_sig_failed: sigFailed, paymaster_sig_failed: sigFailed, - valid_after: UintTryTo::::uint_try_to(&validAfter).unwrap().into(), - valid_until: UintTryTo::::uint_try_to(&validUntil).unwrap().into(), + valid_after: validAfter.to::().into(), + valid_until: validUntil.to::().into(), paymaster_context: paymasterContext, }) } @@ -311,7 +312,8 @@ impl TryFrom for ValidationReturnInfo { .intersect(paymaster.valid_time_range()); Ok(Self { - pre_op_gas: UintTryTo::::uint_try_to(&preOpGas) + pre_op_gas: preOpGas + .try_into() .map_err(|_| "preOpGas is larger than u128")?, account_sig_failed: !account.signature_valid(), paymaster_sig_failed: !paymaster.signature_valid(),