Skip to content

Commit

Permalink
feat(rpc): modify rpc to use alloy types
Browse files Browse the repository at this point in the history
  • Loading branch information
dancoombs committed Sep 30, 2024
1 parent 38c7337 commit 95871b7
Show file tree
Hide file tree
Showing 22 changed files with 434 additions and 404 deletions.
5 changes: 4 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,18 @@
// 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_json_rpc::RequestPacket;
/// Method extractor
use rundler_types::task::traits::RequestExtractor;
use alloy_json_rpc::RequestPacket;

/// Method extractor for Alloy providers
#[derive(Clone, Copy)]
pub struct AlloyMethodExtractor;

impl RequestExtractor<RequestPacket> for RPCMethodExtractor {
impl RequestExtractor<RequestPacket> for AlloyMethodExtractor {
fn get_method_name(req: &RequestPacket) -> String {
match req {
RequestPacket::Single(request) => {
request.method().to_string()
}
RequestPacket::Single(request) => request.method().to_string(),
_ => {
// can't extract method name for batch.
"batch".to_string()
Expand Down
1 change: 1 addition & 0 deletions crates/provider/src/alloy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@

pub(crate) mod entry_point;
pub(crate) mod evm;
pub(crate) mod metrics;
1 change: 1 addition & 0 deletions crates/provider/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub use alloy::{
},
},
evm::AlloyEvmProvider,
metrics::AlloyMethodExtractor,
};

mod traits;
Expand Down
6 changes: 5 additions & 1 deletion crates/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@ 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-trait.workspace = true
ethers.workspace = true
jsonrpsee = { workspace = true , features = ["client", "macros", "server"] }
metrics.workspace = true
thiserror.workspace = true
Expand All @@ -32,6 +35,7 @@ futures-util.workspace = true

[dev-dependencies]
mockall.workspace = true
alloy-consensus.workspace = true
rundler-provider = { path = "../provider", features = ["test-utils"]}
rundler-sim = { path = "../sim", features = ["test-utils"] }
rundler-types= { path = "../types", features = ["test-utils"]}
4 changes: 2 additions & 2 deletions crates/rpc/src/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
// 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;
use anyhow::Context;
use async_trait::async_trait;
use ethers::types::Address;
use jsonrpsee::{core::RpcResult, proc_macros::rpc};
use rundler_types::pool::Pool;

Expand Down Expand Up @@ -51,7 +51,7 @@ impl<P> AdminApi<P> {
#[async_trait]
impl<P> AdminApiServer for AdminApi<P>
where
P: Pool,
P: Pool + 'static,
{
async fn clear_state(&self, clear_params: RpcAdminClearState) -> RpcResult<String> {
utils::safe_call_rpc_handler(
Expand Down
24 changes: 14 additions & 10 deletions crates/rpc/src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
// 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, U64};
use anyhow::Context;
use async_trait::async_trait;
use ethers::types::{Address, H256};
use futures_util::StreamExt;
use jsonrpsee::{core::RpcResult, proc_macros::rpc};
use rundler_types::{
Expand Down Expand Up @@ -48,7 +48,7 @@ pub trait DebugApi {
///
/// Note that the bundling mode must be set to `Manual` else this will fail.
#[method(name = "bundler_sendBundleNow")]
async fn bundler_send_bundle_now(&self) -> RpcResult<H256>;
async fn bundler_send_bundle_now(&self) -> RpcResult<B256>;

/// Sets the bundling mode.
#[method(name = "bundler_setBundlingMode")]
Expand Down Expand Up @@ -103,8 +103,8 @@ impl<P, B> DebugApi<P, B> {
#[async_trait]
impl<P, B> DebugApiServer for DebugApi<P, B>
where
P: Pool,
B: Builder,
P: Pool + 'static,
B: Builder + 'static,
{
async fn bundler_clear_state(&self) -> RpcResult<String> {
utils::safe_call_rpc_handler("bundler_clearState", DebugApi::bundler_clear_state(self))
Expand All @@ -127,7 +127,7 @@ where
.await
}

async fn bundler_send_bundle_now(&self) -> RpcResult<H256> {
async fn bundler_send_bundle_now(&self) -> RpcResult<B256> {
utils::safe_call_rpc_handler(
"bundler_sendBundleNow",
DebugApi::bundler_send_bundle_now(self),
Expand Down Expand Up @@ -235,7 +235,7 @@ where
.collect::<Vec<RpcUserOperation>>())
}

async fn bundler_send_bundle_now(&self) -> InternalRpcResult<H256> {
async fn bundler_send_bundle_now(&self) -> InternalRpcResult<B256> {
tracing::debug!("Sending bundle");

let mut new_heads = self
Expand Down Expand Up @@ -318,8 +318,8 @@ where

let reputation = RpcReputationOutput {
address: r.address,
ops_seen: r.ops_seen.into(),
ops_included: r.ops_included.into(),
ops_seen: U64::from(r.ops_seen),
ops_included: U64::from(r.ops_included),
status,
};

Expand All @@ -344,8 +344,12 @@ where
is_staked: result.is_staked,
stake_info: RpcStakeInfo {
addr: address,
stake: result.stake_info.stake.as_u128(),
unstake_delay_sec: result.stake_info.unstake_delay_sec.as_u32(),
stake: result
.stake_info
.stake
.try_into()
.context("stake should fit in u128")?,
unstake_delay_sec: result.stake_info.unstake_delay_sec,
},
})
}
Expand Down
81 changes: 40 additions & 41 deletions crates/rpc/src/eth/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@

use std::{future::Future, pin::Pin};

use ethers::{
types::{spoof, Address, H256, U64},
utils::to_checksum,
};
use alloy_primitives::{Address, B256, U64};
use futures_util::future;
use rundler_provider::StateOverride;
use rundler_types::{
chain::ChainSpec, pool::Pool, UserOperation, UserOperationOptionalGas, UserOperationVariant,
};
Expand Down Expand Up @@ -68,7 +66,7 @@ where
&self,
op: UserOperationVariant,
entry_point: Address,
) -> EthResult<H256> {
) -> EthResult<B256> {
let bundle_size = op.single_uo_bundle_size_bytes();
if bundle_size > self.chain_spec.max_transaction_size_bytes {
return Err(EthRpcError::InvalidParams(format!(
Expand All @@ -90,7 +88,7 @@ where
&self,
op: UserOperationOptionalGas,
entry_point: Address,
state_override: Option<spoof::State>,
state_override: Option<StateOverride>,
) -> EthResult<RpcGasEstimate> {
let bundle_size = op.single_uo_bundle_size_bytes();
if bundle_size > self.chain_spec.max_transaction_size_bytes {
Expand All @@ -107,9 +105,9 @@ where

pub(crate) async fn get_user_operation_by_hash(
&self,
hash: H256,
hash: B256,
) -> EthResult<Option<RpcUserOperationByHash>> {
if hash == H256::zero() {
if hash == B256::ZERO {
return Err(EthRpcError::InvalidParams(
"Missing/invalid userOpHash".to_string(),
));
Expand All @@ -132,9 +130,9 @@ where

pub(crate) async fn get_user_operation_receipt(
&self,
hash: H256,
hash: B256,
) -> EthResult<Option<RpcUserOperationReceipt>> {
if hash == H256::zero() {
if hash == B256::ZERO {
return Err(EthRpcError::InvalidParams(
"Missing/invalid userOpHash".to_string(),
));
Expand All @@ -153,17 +151,17 @@ where
Ok(self
.router
.entry_points()
.map(|ep| to_checksum(ep, None))
.map(|ep| ep.to_checksum(None))
.collect())
}

pub(crate) async fn chain_id(&self) -> EthResult<U64> {
Ok(self.chain_spec.id.into())
Ok(U64::from(self.chain_spec.id))
}

async fn get_pending_user_operation_by_hash(
&self,
hash: H256,
hash: B256,
) -> EthResult<Option<RpcUserOperationByHash>> {
let res = self
.pool
Expand All @@ -185,15 +183,13 @@ where
mod tests {
use std::sync::Arc;

use ethers::{
abi::AbiEncode,
types::{Bytes, Log, Transaction},
};
use alloy_primitives::{Log as PrimitiveLog, LogData, U256};
use alloy_sol_types::SolInterface;
use mockall::predicate::eq;
use rundler_provider::{MockEntryPointV0_6, MockProvider};
use rundler_contracts::v0_6::IEntryPoint::{handleOpsCall, IEntryPointCalls};
use rundler_provider::{Log, MockEntryPointV0_6, MockEvmProvider, Transaction};
use rundler_sim::MockGasEstimator;
use rundler_types::{
contracts::v0_6::i_entry_point::{HandleOpsCall, IEntryPointCalls},
pool::{MockPool, PoolOperation},
v0_6::UserOperation,
EntityInfos, UserOperation as UserOperationTrait, ValidTimeRange,
Expand All @@ -215,8 +211,8 @@ mod tests {
entry_point: ep,
aggregator: None,
valid_time_range: ValidTimeRange::default(),
expected_code_hash: H256::random(),
sim_block_hash: H256::random(),
expected_code_hash: B256::random(),
sim_block_hash: B256::random(),
sim_block_number: 1000,
account_is_staked: false,
entity_infos: EntityInfos::default(),
Expand All @@ -228,12 +224,12 @@ mod tests {
.times(1)
.returning(move |_| Ok(Some(po.clone())));

let mut provider = MockProvider::default();
let mut provider = MockEvmProvider::default();
provider.expect_get_logs().returning(move |_| Ok(vec![]));
provider.expect_get_block_number().returning(|| Ok(1000));

let mut entry_point = MockEntryPointV0_6::default();
entry_point.expect_address().returning(move || ep);
entry_point.expect_address().return_const(ep);

let api = create_api(provider, entry_point, pool, MockGasEstimator::default());
let res = api.get_user_operation_by_hash(hash).await.unwrap();
Expand All @@ -257,53 +253,56 @@ mod tests {
let uo = UserOperation::default();
let hash = uo.hash(ep, 1);
let block_number = 1000;
let block_hash = H256::random();
let block_hash = B256::random();

let mut pool = MockPool::default();
pool.expect_get_op_by_hash()
.with(eq(hash))
.returning(move |_| Ok(None));

let mut provider = MockProvider::default();
let mut provider = MockEvmProvider::default();
provider.expect_get_block_number().returning(|| Ok(1000));

let tx_data: Bytes = IEntryPointCalls::HandleOps(HandleOpsCall {
beneficiary: Address::zero(),
ops: vec![uo.clone()],
let tx_data = IEntryPointCalls::handleOps(handleOpsCall {
ops: vec![uo.clone().into()],
beneficiary: Address::ZERO,
})
.encode()
.into();
.abi_encode();

let tx = Transaction {
to: Some(ep),
input: tx_data,
block_number: Some(block_number.into()),
input: tx_data.into(),
block_number: Some(block_number),
block_hash: Some(block_hash),
..Default::default()
};
let tx_hash = tx.hash();
let tx_hash = tx.hash;
let log = Log {
address: ep,
transaction_hash: Some(tx_hash),
inner: PrimitiveLog {
address: ep,
data: LogData::default(),
},
transaction_hash: Some(tx.hash),
..Default::default()
};

provider
.expect_get_logs()
.returning(move |_| Ok(vec![log.clone()]));
provider
.expect_get_transaction()
.expect_get_transaction_by_hash()
.with(eq(tx_hash))
.returning(move |_| Ok(Some(tx.clone())));

let mut entry_point = MockEntryPointV0_6::default();
entry_point.expect_address().returning(move || ep);
entry_point.expect_address().return_const(ep);

let api = create_api(provider, entry_point, pool, MockGasEstimator::default());
let res = api.get_user_operation_by_hash(hash).await.unwrap();
let ro = RpcUserOperationByHash {
user_operation: UserOperationVariant::from(uo).into(),
entry_point: ep.into(),
block_number: Some(block_number.into()),
block_number: Some(U256::from(block_number)),
block_hash: Some(block_hash),
transaction_hash: Some(tx_hash),
};
Expand All @@ -322,20 +321,20 @@ mod tests {
.times(1)
.returning(move |_| Ok(None));

let mut provider = MockProvider::default();
let mut provider = MockEvmProvider::default();
provider.expect_get_logs().returning(move |_| Ok(vec![]));
provider.expect_get_block_number().returning(|| Ok(1000));

let mut entry_point = MockEntryPointV0_6::default();
entry_point.expect_address().returning(move || ep);
entry_point.expect_address().return_const(ep);

let api = create_api(provider, entry_point, pool, MockGasEstimator::default());
let res = api.get_user_operation_by_hash(hash).await.unwrap();
assert_eq!(res, None);
}

fn create_api(
provider: MockProvider,
provider: MockEvmProvider,
ep: MockEntryPointV0_6,
pool: MockPool,
gas_estimator: MockGasEstimator,
Expand Down
Loading

0 comments on commit 95871b7

Please sign in to comment.