feat(rpc): initial work in eth_call+estimate (#1514)

This commit is contained in:
Matthias Seitz
2023-02-22 23:59:19 +01:00
committed by GitHub
parent 17dffba150
commit 3c77dd9e2f
4 changed files with 81 additions and 0 deletions

2
Cargo.lock generated
View File

@@ -4903,6 +4903,7 @@ dependencies = [
"jsonwebtoken",
"pin-project",
"rand 0.8.5",
"reth-executor",
"reth-interfaces",
"reth-network-api",
"reth-primitives",
@@ -4913,6 +4914,7 @@ dependencies = [
"reth-rpc-types",
"reth-tasks",
"reth-transaction-pool",
"revm",
"secp256k1 0.26.0",
"serde",
"serde_json",

View File

@@ -19,8 +19,12 @@ reth-provider = { path = "../../storage/provider", features = ["test-utils"] }
reth-transaction-pool = { path = "../../transaction-pool", features = ["test-utils"]}
reth-network-api = { path = "../../net/network-api", features = ["test-utils"] }
reth-rpc-engine-api = { path = "../rpc-engine-api" }
reth-executor = { path = "../../executor" }
reth-tasks = { path = "../../tasks" }
# eth
revm = "3.0.0"
# rpc
jsonrpsee = { version = "0.16" }
http = "0.2.8"

View File

@@ -0,0 +1,64 @@
//! Contains RPC handler implementations specific to endpoints that call/execute within evm.
#![allow(unused)] // TODO rm later
use crate::{eth::error::EthResult, EthApi};
use reth_executor::revm_wrap::{State, SubState};
use reth_primitives::{BlockId, U256};
use reth_provider::{BlockProvider, StateProvider, StateProviderFactory};
use reth_rpc_types::CallRequest;
use revm::primitives::{BlockEnv, Env, ResultAndState};
impl<Client, Pool, Network> EthApi<Client, Pool, Network>
where
Client: BlockProvider + StateProviderFactory + 'static,
{
/// Creates the [Env] used by the [EVM](revm::EVM) when executing a call.
fn build_call_env(&self, request: CallRequest, block_env: BlockEnv) -> Env {
todo!()
}
/// Executes the call request against the given `state` without committing any changes to the
/// database
pub(crate) fn call_with<S>(
&self,
request: CallRequest,
state: S,
block_env: BlockEnv,
// TODO add overrides
) -> EthResult<ResultAndState>
where
S: StateProvider,
{
// the revm database impl
let mut db = SubState::new(State::new(state));
let mut evm = revm::EVM::new();
evm.env = self.build_call_env(request, block_env);
evm.database(db);
// TODO error conversion from EMVError to EthApiErr
let res = evm.transact_ref().unwrap();
Ok(res)
}
/// Estimate gas needed for execution of the `request` at the [BlockId] .
pub(crate) fn estimate_gas_at(&self, mut request: CallRequest, at: BlockId) -> EthResult<U256> {
// TODO get a StateProvider for the given blockId and BlockEnv
todo!()
}
/// Estimates the gas usage of the `request` with the state.
fn estimate_gas_with<S>(
&self,
mut request: CallRequest,
state: S,
block_env: BlockEnv,
) -> EthResult<U256>
where
S: StateProvider,
{
// TODO: check if transfer
// binary search over range to find best gas
todo!()
}
}

View File

@@ -13,11 +13,14 @@ use reth_primitives::{
use reth_provider::{BlockProvider, StateProviderFactory};
use std::num::NonZeroUsize;
use crate::eth::error::EthResult;
use reth_provider::providers::ChainState;
use reth_rpc_types::FeeHistoryCache;
use reth_transaction_pool::TransactionPool;
use std::sync::Arc;
mod block;
mod call;
mod server;
mod state;
mod transactions;
@@ -100,6 +103,14 @@ where
self.client().convert_block_number(num)
}
/// Helper function to execute a closure with the database at a specific block.
pub(crate) fn with_state_at<F, T>(&self, _at: BlockId, _f: F) -> EthResult<T>
where
F: FnOnce(ChainState<'_>) -> T,
{
unimplemented!()
}
/// Returns the state at the given [BlockId] enum or the latest.
pub(crate) fn state_at_block_id_or_latest(
&self,