fix: correct blockhash access in calls (#88)

This commit is contained in:
Noah Citron 2022-11-04 16:37:30 -04:00 committed by GitHub
parent eaca764aac
commit 0706755ec2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 21 deletions

View File

@ -28,7 +28,7 @@ Helios will now run a local RPC server at `http://127.0.0.1:8545`.
`--rpc-port` or `-p` sets the port that the local RPC should run on. The default value is `8545`.
`--data-dir` or `d` sets the directory that Helios should use to store cached weak subjectivity checkpoints in. Each network only stores the latest checkpoint, which is just 32 bytes.
`--data-dir` or `-d` sets the directory that Helios should use to store cached weak subjectivity checkpoints in. Each network only stores the latest checkpoint, which is just 32 bytes.
### Configuration Files
All configuration options can be set on a per-network level in `~/.helios/helios.toml`. Here is an example config file:

View File

@ -102,7 +102,12 @@ impl Node {
self.check_blocktag_age(&block)?;
let payload = self.get_payload(block)?;
let mut evm = Evm::new(self.execution.clone(), payload.clone(), self.chain_id());
let mut evm = Evm::new(
self.execution.clone(),
&payload,
&self.payloads,
self.chain_id(),
);
evm.call(opts).await
}
@ -110,7 +115,12 @@ impl Node {
self.check_head_age()?;
let payload = self.get_payload(BlockTag::Latest)?;
let mut evm = Evm::new(self.execution.clone(), payload.clone(), self.chain_id());
let mut evm = Evm::new(
self.execution.clone(),
&payload,
&self.payloads,
self.chain_id(),
);
evm.estimate_gas(opts).await
}

View File

@ -1,6 +1,13 @@
use std::{cmp, collections::HashMap, str::FromStr, sync::Arc, thread};
use std::{
cmp,
collections::{BTreeMap, HashMap},
str::FromStr,
sync::Arc,
thread,
};
use bytes::Bytes;
use common::{errors::BlockNotFoundError, types::BlockTag};
use ethers::{
abi::ethereum_types::BigEndianHash,
prelude::{Address, H160, H256, U256},
@ -21,19 +28,20 @@ use crate::{
use super::ExecutionClient;
pub struct Evm<R: ExecutionRpc> {
evm: EVM<ProofDB<R>>,
pub struct Evm<'a, R: ExecutionRpc> {
evm: EVM<ProofDB<'a, R>>,
chain_id: u64,
}
impl<R: ExecutionRpc> Evm<R> {
impl<'a, R: ExecutionRpc> Evm<'a, R> {
pub fn new(
execution: Arc<ExecutionClient<R>>,
payload: ExecutionPayload,
current_payload: &'a ExecutionPayload,
payloads: &'a BTreeMap<u64, ExecutionPayload>,
chain_id: u64,
) -> Self {
let mut evm: EVM<ProofDB<R>> = EVM::new();
let db = ProofDB::new(execution, payload);
let db = ProofDB::new(execution, current_payload, payloads);
evm.database(db);
Evm { evm, chain_id }
@ -105,9 +113,9 @@ impl<R: ExecutionRpc> Evm<R> {
async fn batch_fetch_accounts(&self, opts: &CallOpts) -> Result<HashMap<Address, Account>> {
let db = self.evm.db.as_ref().unwrap();
let rpc = db.execution.rpc.clone();
let payload = db.payload.clone();
let payload = db.current_payload.clone();
let execution = db.execution.clone();
let block = db.payload.block_number;
let block = db.current_payload.block_number;
let opts_moved = CallOpts {
from: opts.from,
@ -173,7 +181,7 @@ impl<R: ExecutionRpc> Evm<R> {
fn get_env(&self, opts: &CallOpts) -> Env {
let mut env = Env::default();
let payload = &self.evm.db.as_ref().unwrap().payload;
let payload = &self.evm.db.as_ref().unwrap().current_payload;
env.tx.transact_to = TransactTo::Call(opts.to);
env.tx.caller = opts.from.unwrap_or(Address::zero());
@ -193,18 +201,24 @@ impl<R: ExecutionRpc> Evm<R> {
}
}
struct ProofDB<R: ExecutionRpc> {
struct ProofDB<'a, R: ExecutionRpc> {
execution: Arc<ExecutionClient<R>>,
payload: ExecutionPayload,
current_payload: &'a ExecutionPayload,
payloads: &'a BTreeMap<u64, ExecutionPayload>,
accounts: HashMap<Address, Account>,
error: Option<String>,
}
impl<R: ExecutionRpc> ProofDB<R> {
pub fn new(execution: Arc<ExecutionClient<R>>, payload: ExecutionPayload) -> Self {
impl<'a, R: ExecutionRpc> ProofDB<'a, R> {
pub fn new(
execution: Arc<ExecutionClient<R>>,
current_payload: &'a ExecutionPayload,
payloads: &'a BTreeMap<u64, ExecutionPayload>,
) -> Self {
ProofDB {
execution,
payload,
current_payload,
payloads,
accounts: HashMap::new(),
error: None,
}
@ -217,7 +231,7 @@ impl<R: ExecutionRpc> ProofDB<R> {
fn get_account(&mut self, address: Address, slots: &[H256]) -> Result<Account> {
let execution = self.execution.clone();
let addr = address.clone();
let payload = self.payload.clone();
let payload = self.current_payload.clone();
let slots = slots.to_owned();
let handle = thread::spawn(move || {
@ -230,7 +244,7 @@ impl<R: ExecutionRpc> ProofDB<R> {
}
}
impl<R: ExecutionRpc> Database for ProofDB<R> {
impl<'a, R: ExecutionRpc> Database for ProofDB<'a, R> {
type Error = Report;
fn basic(&mut self, address: H160) -> Result<Option<AccountInfo>, Report> {
@ -256,8 +270,13 @@ impl<R: ExecutionRpc> Database for ProofDB<R> {
)))
}
fn block_hash(&mut self, _number: U256) -> Result<H256, Report> {
Ok(H256::default())
fn block_hash(&mut self, number: U256) -> Result<H256, Report> {
let number = number.as_u64();
let payload = self
.payloads
.get(&number)
.ok_or(BlockNotFoundError::new(BlockTag::Number(number)))?;
Ok(H256::from_slice(&payload.block_hash))
}
fn storage(&mut self, address: H160, slot: U256) -> Result<U256, Report> {