Skip to content

Commit

Permalink
Merge pull request #59 from Vid201/feat/estimate_gas
Browse files Browse the repository at this point in the history
eth_getSupportedEntryPoints and eth_estimateUserOperationGas
  • Loading branch information
Vid201 authored Feb 17, 2023
2 parents a99894a + b8ac6af commit 9748128
Show file tree
Hide file tree
Showing 13 changed files with 303 additions and 80 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ jobs:
toolchain: stable
components: rustfmt, clippy

- name: Setup Rust cache
uses: Swatinem/rust-cache@v2

- name: Install cargo sort
run: |
cargo install cargo-sort
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
- name: Fetch third-party dependencies
run: |
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ build:
cargo build

run-bundler:
cargo run -- --eth-client-address http://127.0.0.1:8545 --mnemonic-file ${HOME}/.aa-bundler/0x129D197b2a989C6798601A49D89a4AEC822A17a3 --beneficiary 0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990 --gas-factor 600 --min-balance 1 --entry-points 0x0000000000000000000000000000000000000000 --helper 0x0000000000000000000000000000000000000000 --min-stake 1 --min-unstake-delay 0 --min-priority-fee-per-gas 0 --max-verification-gas 1500000
cargo run -- --eth-client-address http://127.0.0.1:8545 --mnemonic-file ${HOME}/.aa-bundler/0x129D197b2a989C6798601A49D89a4AEC822A17a3 --beneficiary 0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990 --gas-factor 600 --min-balance 1 --entry-points 0x1306b01bC3e4AD202612D3843387e94737673F53 --helper 0x0000000000000000000000000000000000000000 --min-stake 1 --min-unstake-delay 0 --min-priority-fee-per-gas 0 --max-verification-gas 1500000

run-bundler-uopool:
cargo run --bin bundler-uopool -- --eth-client-address http://127.0.0.1:8545 --entry-points 0x0000000000000000000000000000000000000000 --min-stake 1 --min-unstake-delay 0 --min-priority-fee-per-gas 0 --max-verification-gas 1500000
cargo run --bin bundler-uopool -- --eth-client-address http://127.0.0.1:8545 --entry-points 0x1306b01bC3e4AD202612D3843387e94737673F53 --min-stake 1 --min-unstake-delay 0 --min-priority-fee-per-gas 0 --max-verification-gas 1500000

run-bundler-rpc:
cargo run --bin bundler-rpc
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ cargo run --bin create-wallet -- --output-path ${HOME}/.aa-bundler --chain-id 5
Run bundler (with user operation pool and JSON-RPC API):

```bash
cargo run -- --mnemonic-file ${HOME}/.aa-bundler/0x129D197b2a989C6798601A49D89a4AEC822A17a3 --beneficiary 0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990 --gas-factor 600 --min-balance 1 --eth-client-address http://127.0.0.1:8545 --entry-points 0x0000000000000000000000000000000000000000 --helper 0x0000000000000000000000000000000000000000 --min-stake 1 --min-unstake-delay 0 --min-priority-fee-per-gas 0 --max-verification-gas 1500000
cargo run -- --eth-client-address http://127.0.0.1:8545 --mnemonic-file ${HOME}/.aa-bundler/0x129D197b2a989C6798601A49D89a4AEC822A17a3 --beneficiary 0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990 --gas-factor 600 --min-balance 1 --entry-points 0x1306b01bC3e4AD202612D3843387e94737673F53 --helper 0x0000000000000000000000000000000000000000 --min-stake 1 --min-unstake-delay 0 --min-priority-fee-per-gas 0 --max-verification-gas 1500000
```

Run only user operation pool:

```bash
cargo run --bin bundler-uopool -- --eth-client-address http://127.0.0.1:8545 --entry-points 0x0000000000000000000000000000000000000000 --min-stake 1 --min-unstake-delay 0 --min-priority-fee-per-gas 0 --max-verification-gas 1500000
cargo run --bin bundler-uopool -- --eth-client-address http://127.0.0.1:8545 --entry-points 0x1306b01bC3e4AD202612D3843387e94737673F53 --min-stake 1 --min-unstake-delay 0 --min-priority-fee-per-gas 0 --max-verification-gas 1500000
```

Run only JSON-RPC API:
Expand Down
8 changes: 7 additions & 1 deletion bin/bundler-uopool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ use aa_bundler::utils::{parse_address, parse_u256};
use anyhow::Result;
use clap::Parser;
use ethers::{
providers::{Http, Provider},
providers::{Http, Middleware, Provider},
types::{Address, U256},
};
use jsonrpsee::tracing::info;
use std::{future::pending, sync::Arc};

#[derive(Parser)]
Expand Down Expand Up @@ -34,6 +35,11 @@ async fn main() -> Result<()> {
tracing_subscriber::fmt::init();

let eth_provider = Arc::new(Provider::<Http>::try_from(opt.eth_client_address.clone())?);
info!(
"Connected to Ethereum execution client at {}: {}",
opt.eth_client_address,
eth_provider.client_version().await?
);

aa_bundler::uopool::run(
opt.uopool_opts,
Expand Down
2 changes: 1 addition & 1 deletion bundler-spec-test/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ services:
bundler:
build:
context: ../ # https://github.com/Vid201/aa-bundler.git
command: --rpc-listen-address 0.0.0.0:3000 --eth-client-address http://geth-dev:8545 --mnemonic-file /root/${BUNDLER_ACCOUNT} --beneficiary 0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990 --gas-factor 600 --min-balance 1 --entry-points 0x0000000000000000000000000000000000000000 --helper 0x0000000000000000000000000000000000000000 --min-stake 1 --min-unstake-delay 0 --min-priority-fee-per-gas 0 --max-verification-gas 1500000
command: --rpc-listen-address 0.0.0.0:3000 --eth-client-address http://geth-dev:8545 --mnemonic-file /root/${BUNDLER_ACCOUNT} --beneficiary 0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990 --gas-factor 600 --min-balance 1 --entry-points 0x1306b01bC3e4AD202612D3843387e94737673F53 --helper 0x0000000000000000000000000000000000000000 --min-stake 1 --min-unstake-delay 0 --min-priority-fee-per-gas 0 --max-verification-gas 1500000
ports: [ '3000:3000' ]
volumes:
- ./keys:/root
Expand Down
8 changes: 7 additions & 1 deletion src/contracts/entrypoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ where
let request_result = self
.entry_point_api
.simulate_validation(user_operation.into())
.call()
.await;
match request_result {
Ok(_) => Err(EntryPointErr::UnknownErr(
Expand Down Expand Up @@ -121,6 +122,7 @@ where
) -> Result<(), EntryPointErr<M>> {
self.entry_point_api
.handle_ops(ops.into_iter().map(|u| u.into()).collect(), beneficiary)
.call()
.await
.or_else(|e| {
let err_msg = e.to_string();
Expand Down Expand Up @@ -157,7 +159,11 @@ where
&self,
initcode: Bytes,
) -> Result<SenderAddressResult, EntryPointErr<M>> {
let result = self.entry_point_api.get_sender_address(initcode).await;
let result = self
.entry_point_api
.get_sender_address(initcode)
.call()
.await;

match result {
Ok(_) => Err(EntryPointErr::UnknownErr(
Expand Down
34 changes: 23 additions & 11 deletions src/proto/uopool/uopool.proto
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
syntax = "proto3";

import "google/protobuf/empty.proto";
import "types/types.proto";

package uopool;
Expand Down Expand Up @@ -32,16 +33,27 @@ message RemoveResponse {
RemoveResult result = 1;
}

message GetChainIdRequest {}
message GetChainIdResponse {
uint64 chain_id = 1;
}

enum GetChainIdResult {
GOT_CHAIN_ID = 0;
NOT_GOT_CHAIN_ID = 1;
message GetSupportedEntryPointsResponse {
repeated types.H160 eps = 1;
}

message GetChainIdResponse {
GetChainIdResult result = 1;
uint64 chain_id = 2;
message EstimateUserOperationGasRequest {
types.UserOperation uo = 1;
types.H160 ep = 2;
}

enum EstimateUserOperationGasResult {
ESTIMATED = 0;
NOT_ESTIMATED = 1;
}

message EstimateUserOperationGasResponse {
EstimateUserOperationGasResult result = 1;
string data = 2;
}

enum GetAllResult {
Expand All @@ -63,8 +75,6 @@ enum ClearResult {
NOT_CLEARED = 1;
}

message ClearRequest {}

message ClearResponse {
ClearResult result = 1;
}
Expand Down Expand Up @@ -100,11 +110,13 @@ message SetReputationResponse {
service UoPool {
rpc Add(AddRequest) returns (AddResponse);
rpc Remove(RemoveRequest) returns (RemoveResponse);
rpc GetChainId(GetChainIdRequest) returns (GetChainIdResponse);
rpc GetChainId(google.protobuf.Empty) returns (GetChainIdResponse);
rpc GetSupportedEntryPoints(google.protobuf.Empty) returns (GetSupportedEntryPointsResponse);
rpc EstimateUserOperationGas(EstimateUserOperationGasRequest) returns (EstimateUserOperationGasResponse);

// debug
rpc GetAll(GetAllRequest) returns (GetAllResponse);
rpc Clear(ClearRequest) returns (ClearResponse);
rpc Clear(google.protobuf.Empty) returns (ClearResponse);
rpc GetAllReputation(GetAllReputationRequest) returns (GetAllReputationResponse);
rpc SetReputation(SetReputationRequest) returns (SetReputationResponse);
}
9 changes: 3 additions & 6 deletions src/rpc/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ use super::debug_api::DebugApiServer;
use crate::{
types::{reputation::ReputationEntry, user_operation::UserOperation},
uopool::server::uopool::{
uo_pool_client::UoPoolClient, ClearRequest, ClearResult, GetAllReputationRequest,
GetAllReputationResult, GetAllRequest, GetAllResult, SetReputationRequest,
SetReputationResult,
uo_pool_client::UoPoolClient, ClearResult, GetAllReputationRequest, GetAllReputationResult,
GetAllRequest, GetAllResult, SetReputationRequest, SetReputationResult,
},
};
use anyhow::format_err;
Expand All @@ -23,10 +22,8 @@ impl DebugApiServer for DebugApiServerImpl {
async fn clear_state(&self) -> RpcResult<()> {
let mut uopool_grpc_client = self.uopool_grpc_client.clone();

let request = tonic::Request::new(ClearRequest {});

let response = uopool_grpc_client
.clear(request)
.clear(tonic::Request::new(()))
.await
.map_err(|status| format_err!("GRPC error (uopool): {}", status.message()))?
.into_inner();
Expand Down
78 changes: 53 additions & 25 deletions src/rpc/eth.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
use crate::{
rpc::eth_api::{EstimateUserOperationGasResponse, EthApiServer},
types::user_operation::{UserOperation, UserOperationHash, UserOperationReceipt},
rpc::eth_api::EthApiServer,
types::user_operation::{
UserOperation, UserOperationGasEstimation, UserOperationHash, UserOperationPartial,
UserOperationReceipt,
},
uopool::server::uopool::{
uo_pool_client::UoPoolClient, AddRequest, AddResult, GetChainIdRequest, GetChainIdResult,
uo_pool_client::UoPoolClient, AddRequest, AddResult, EstimateUserOperationGasRequest,
EstimateUserOperationGasResult,
},
};
use anyhow::format_err;
use async_trait::async_trait;
use ethers::types::{Address, U256, U64};
use ethers::{
types::{Address, U64},
utils::to_checksum,
};
use jsonrpsee::{
core::RpcResult,
tracing::info,
Expand All @@ -25,25 +32,29 @@ impl EthApiServer for EthApiServerImpl {
async fn chain_id(&self) -> RpcResult<U64> {
let mut uopool_grpc_client = self.uopool_grpc_client.clone();

let request = tonic::Request::new(GetChainIdRequest {});

let response = uopool_grpc_client
.get_chain_id(request)
.get_chain_id(tonic::Request::new(()))
.await
.map_err(|status| format_err!("GRPC error (uopool): {}", status.message()))?
.into_inner();

if response.result == GetChainIdResult::GotChainId as i32 {
return Ok(response.chain_id.into());
}

Err(jsonrpsee::core::Error::Call(CallError::Failed(
anyhow::format_err!("failed to get chain id"),
)))
return Ok(response.chain_id.into());
}

async fn supported_entry_points(&self) -> RpcResult<Vec<Address>> {
Ok(vec![Address::default()])
async fn supported_entry_points(&self) -> RpcResult<Vec<String>> {
let mut uopool_grpc_client = self.uopool_grpc_client.clone();

let response = uopool_grpc_client
.get_supported_entry_points(tonic::Request::new(()))
.await
.map_err(|status| format_err!("GRPC error (uopool): {}", status.message()))?
.into_inner();

return Ok(response
.eps
.into_iter()
.map(|entry_point| to_checksum(&entry_point.into(), None))
.collect());
}

async fn send_user_operation(
Expand Down Expand Up @@ -81,16 +92,33 @@ impl EthApiServer for EthApiServerImpl {

async fn estimate_user_operation_gas(
&self,
user_operation: UserOperation,
user_operation: UserOperationPartial,
entry_point: Address,
) -> RpcResult<EstimateUserOperationGasResponse> {
info!("{:?}", user_operation);
info!("{:?}", entry_point);
Ok(EstimateUserOperationGasResponse {
pre_verification_gas: U256::from(0),
verification_gas_limit: U256::from(0),
call_gas_limit: U256::from(self.call_gas_limit),
})
) -> RpcResult<UserOperationGasEstimation> {
let mut uopool_grpc_client = self.uopool_grpc_client.clone();

let request = tonic::Request::new(EstimateUserOperationGasRequest {
uo: Some(UserOperation::from(user_operation).into()),
ep: Some(entry_point.into()),
});

let response = uopool_grpc_client
.estimate_user_operation_gas(request)
.await
.map_err(|status| format_err!("GRPC error (uopool): {}", status.message()))?
.into_inner();

if response.result == EstimateUserOperationGasResult::Estimated as i32 {
let user_operation_gas_estimation = serde_json::from_str::<UserOperationGasEstimation>(
&response.data,
)
.map_err(|err| format_err!("error parsing user operation gas estimation: {}", err))?;
return Ok(user_operation_gas_estimation);
}

Err(jsonrpsee::core::Error::Call(CallError::Failed(
anyhow::format_err!("failed to gas estimation for user operation"),
)))
}

async fn get_user_operation_receipt(
Expand Down
21 changes: 8 additions & 13 deletions src/rpc/eth_api.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
use ethers::types::{Address, U256, U64};
use ethers::types::{Address, U64};
use jsonrpsee::{core::RpcResult, proc_macros::rpc};
use serde::{Deserialize, Serialize};

use crate::types::user_operation::{UserOperation, UserOperationHash, UserOperationReceipt};

#[derive(Serialize, Deserialize)]
pub struct EstimateUserOperationGasResponse {
pub pre_verification_gas: U256,
pub verification_gas_limit: U256,
pub call_gas_limit: U256,
}
use crate::types::user_operation::{
UserOperation, UserOperationGasEstimation, UserOperationHash, UserOperationPartial,
UserOperationReceipt,
};

#[rpc(server, namespace = "eth")]
pub trait EthApi {
#[method(name = "chainId")]
async fn chain_id(&self) -> RpcResult<U64>;

#[method(name = "supportedEntryPoints")]
async fn supported_entry_points(&self) -> RpcResult<Vec<Address>>;
async fn supported_entry_points(&self) -> RpcResult<Vec<String>>;

#[method(name = "sendUserOperation")]
async fn send_user_operation(
Expand All @@ -29,9 +24,9 @@ pub trait EthApi {
#[method(name = "estimateUserOperationGas")]
async fn estimate_user_operation_gas(
&self,
user_operation: UserOperation,
user_operation: UserOperationPartial,
entry_point: Address,
) -> RpcResult<EstimateUserOperationGasResponse>;
) -> RpcResult<UserOperationGasEstimation>;

#[method(name = "getUserOperationReceipt")]
async fn get_user_operation_receipt(
Expand Down
Loading

0 comments on commit 9748128

Please sign in to comment.