fix: add full block and tx context to call (#10)
This commit is contained in:
parent
dbeeffb9f9
commit
95daee7186
|
@ -80,13 +80,13 @@ impl Client {
|
||||||
|
|
||||||
pub fn call(&self, opts: &CallOpts, block: &Option<u64>) -> Result<Vec<u8>> {
|
pub fn call(&self, opts: &CallOpts, block: &Option<u64>) -> Result<Vec<u8>> {
|
||||||
let payload = self.get_payload(block)?;
|
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)
|
evm.call(opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn estimate_gas(&self, opts: &CallOpts) -> Result<u64> {
|
pub fn estimate_gas(&self, opts: &CallOpts) -> Result<u64> {
|
||||||
let payload = self.get_payload(&None)?;
|
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)
|
evm.estimate_gas(opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,26 +14,20 @@ use super::ExecutionClient;
|
||||||
|
|
||||||
pub struct Evm {
|
pub struct Evm {
|
||||||
evm: EVM<ProofDB>,
|
evm: EVM<ProofDB>,
|
||||||
|
chain_id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Evm {
|
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 mut evm: EVM<ProofDB> = EVM::new();
|
||||||
let db = ProofDB::new(execution, payload);
|
let db = ProofDB::new(execution, payload);
|
||||||
evm.database(db);
|
evm.database(db);
|
||||||
|
|
||||||
Evm { evm }
|
Evm { evm, chain_id }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call(&mut self, opts: &CallOpts) -> Result<Vec<u8>> {
|
pub fn call(&mut self, opts: &CallOpts) -> Result<Vec<u8>> {
|
||||||
let mut env = Env::default();
|
self.evm.env = self.get_env(opts);
|
||||||
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;
|
|
||||||
|
|
||||||
let output = self.evm.transact().1;
|
let output = self.evm.transact().1;
|
||||||
|
|
||||||
if let Some(err) = &self.evm.db.as_ref().unwrap().error {
|
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> {
|
pub fn estimate_gas(&mut self, opts: &CallOpts) -> Result<u64> {
|
||||||
let mut env = Env::default();
|
self.evm.env = self.get_env(opts);
|
||||||
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;
|
|
||||||
|
|
||||||
let gas = self.evm.transact().2;
|
let gas = self.evm.transact().2;
|
||||||
|
|
||||||
if let Some(err) = &self.evm.db.as_ref().unwrap().error {
|
if let Some(err) = &self.evm.db.as_ref().unwrap().error {
|
||||||
return Err(eyre::eyre!(err.clone()));
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,10 +73,12 @@ pub struct ExecutionBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct CallOpts {
|
pub struct CallOpts {
|
||||||
pub from: Option<Address>,
|
pub from: Option<Address>,
|
||||||
pub to: Address,
|
pub to: Address,
|
||||||
pub gas: Option<U256>,
|
pub gas: Option<U256>,
|
||||||
|
pub gas_price: Option<U256>,
|
||||||
pub value: Option<U256>,
|
pub value: Option<U256>,
|
||||||
#[serde(default, deserialize_with = "bytes_deserialize")]
|
#[serde(default, deserialize_with = "bytes_deserialize")]
|
||||||
pub data: Option<Vec<u8>>,
|
pub data: Option<Vec<u8>>,
|
||||||
|
|
Loading…
Reference in New Issue