fix: add full block and tx context to call (#10)

This commit is contained in:
Noah Citron 2022-09-02 15:29:51 -04:00 committed by GitHub
parent dbeeffb9f9
commit 95daee7186
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 21 deletions

View File

@ -80,13 +80,13 @@ impl Client {
pub fn call(&self, opts: &CallOpts, block: &Option<u64>) -> Result<Vec<u8>> {
let payload = self.get_payload(block)?;
let mut evm = Evm::new(self.execution.clone(), payload);
let mut evm = Evm::new(self.execution.clone(), payload, self.chain_id());
evm.call(opts)
}
pub fn estimate_gas(&self, opts: &CallOpts) -> Result<u64> {
let payload = self.get_payload(&None)?;
let mut evm = Evm::new(self.execution.clone(), payload);
let mut evm = Evm::new(self.execution.clone(), payload, self.chain_id());
evm.estimate_gas(opts)
}

View File

@ -14,26 +14,20 @@ use super::ExecutionClient;
pub struct Evm {
evm: EVM<ProofDB>,
chain_id: u64,
}
impl Evm {
pub fn new(execution: ExecutionClient, payload: ExecutionPayload) -> Self {
pub fn new(execution: ExecutionClient, payload: ExecutionPayload, chain_id: u64) -> Self {
let mut evm: EVM<ProofDB> = EVM::new();
let db = ProofDB::new(execution, payload);
evm.database(db);
Evm { evm }
Evm { evm, chain_id }
}
pub fn call(&mut self, opts: &CallOpts) -> Result<Vec<u8>> {
let mut env = Env::default();
env.tx.transact_to = TransactTo::Call(opts.to);
env.tx.caller = opts.from.unwrap_or(Address::zero());
env.tx.value = opts.value.unwrap_or(U256::from(0));
env.tx.data = Bytes::from(opts.data.clone().unwrap_or(vec![]));
self.evm.env = env;
self.evm.env = self.get_env(opts);
let output = self.evm.transact().1;
if let Some(err) = &self.evm.db.as_ref().unwrap().error {
@ -48,21 +42,36 @@ impl Evm {
}
pub fn estimate_gas(&mut self, opts: &CallOpts) -> Result<u64> {
let mut env = Env::default();
env.tx.transact_to = TransactTo::Call(opts.to);
env.tx.caller = opts.from.unwrap_or(Address::zero());
env.tx.value = opts.value.unwrap_or(U256::from(0));
env.tx.data = Bytes::from(opts.data.clone().unwrap_or(vec![]));
self.evm.env = env;
self.evm.env = self.get_env(opts);
let gas = self.evm.transact().2;
if let Some(err) = &self.evm.db.as_ref().unwrap().error {
return Err(eyre::eyre!(err.clone()));
}
Ok(gas)
let gas_scaled = (1.10 * gas as f64) as u64;
Ok(gas_scaled)
}
fn get_env(&self, opts: &CallOpts) -> Env {
let mut env = Env::default();
let payload = &self.evm.db.as_ref().unwrap().payload;
env.tx.transact_to = TransactTo::Call(opts.to);
env.tx.caller = opts.from.unwrap_or(Address::zero());
env.tx.value = opts.value.unwrap_or(U256::from(0));
env.tx.data = Bytes::from(opts.data.clone().unwrap_or(vec![]));
env.tx.gas_limit = opts.gas.map(|v| v.as_u64()).unwrap_or(u64::MAX);
env.tx.gas_price = opts.gas_price.unwrap_or(U256::zero());
env.block.number = U256::from(payload.block_number);
env.block.coinbase = Address::from_slice(&payload.fee_recipient);
env.block.timestamp = U256::from(payload.timestamp);
env.block.difficulty = U256::from_little_endian(&payload.prev_randao);
env.cfg.chain_id = self.chain_id.into();
env
}
}

View File

@ -73,10 +73,12 @@ pub struct ExecutionBlock {
}
#[derive(Deserialize, Serialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct CallOpts {
pub from: Option<Address>,
pub to: Address,
pub gas: Option<U256>,
pub gas_price: Option<U256>,
pub value: Option<U256>,
#[serde(default, deserialize_with = "bytes_deserialize")]
pub data: Option<Vec<u8>>,