fix: implement pending evm env (#2968)

This commit is contained in:
Matthias Seitz
2023-06-05 04:51:26 +02:00
committed by GitHub
parent ef6fa6dca2
commit 25dd544468
8 changed files with 41 additions and 16 deletions

View File

@ -157,7 +157,7 @@ where
TraceApiClient::trace_raw_transaction(client, Bytes::default(), HashSet::default(), None)
.await
.unwrap_err();
TraceApiClient::trace_call_many(client, vec![], None).await.err().unwrap();
TraceApiClient::trace_call_many(client, vec![], None).await.unwrap();
TraceApiClient::replay_transaction(client, H256::default(), HashSet::default())
.await
.err()

View File

@ -196,23 +196,22 @@ where
f(state)
}
async fn evm_env_at(&self, at: BlockId) -> EthResult<(CfgEnv, BlockEnv, BlockId)> {
// TODO handle Pending state's env
match at {
BlockId::Number(BlockNumberOrTag::Pending) => {
// This should perhaps use the latest env settings and update block specific
// settings like basefee/number
Err(EthApiError::Unsupported("pending state not implemented yet"))
}
hash_or_num => {
let block_hash = self
.client()
.block_hash_for_id(hash_or_num)?
.ok_or_else(|| EthApiError::UnknownBlockNumber)?;
let (cfg, env) = self.cache().get_evm_env(block_hash).await?;
Ok((cfg, env, block_hash.into()))
async fn evm_env_at(&self, mut at: BlockId) -> EthResult<(CfgEnv, BlockEnv, BlockId)> {
if at.is_pending() {
if let Some(pending) = self.client().pending_header()? {
let mut cfg = CfgEnv::default();
let mut block_env = BlockEnv::default();
self.client().fill_block_env_with_header(&mut block_env, &pending.header)?;
self.client().fill_cfg_env_with_header(&mut cfg, &pending.header)?;
return Ok((cfg, block_env, pending.hash.into()))
}
// No pending block, use latest
at = BlockId::Number(BlockNumberOrTag::Latest);
}
let block_hash =
self.client().block_hash_for_id(at)?.ok_or_else(|| EthApiError::UnknownBlockNumber)?;
let (cfg, env) = self.cache().get_evm_env(block_hash).await?;
Ok((cfg, env, block_hash.into()))
}
async fn evm_env_for_raw_block(&self, header: &Header) -> EthResult<(CfgEnv, BlockEnv)> {

View File

@ -184,6 +184,10 @@ impl<DB: Database> BlockProvider for ShareableDatabase<DB> {
self.provider()?.pending_block()
}
fn pending_header(&self) -> Result<Option<SealedHeader>> {
self.provider()?.pending_header()
}
fn ommers(&self, id: BlockHashOrNumber) -> Result<Option<Vec<Header>>> {
self.provider()?.ommers(id)
}

View File

@ -206,6 +206,10 @@ impl<'this, TX: DbTx<'this>> BlockProvider for DatabaseProvider<'this, TX> {
Ok(None)
}
fn pending_header(&self) -> Result<Option<SealedHeader>> {
Ok(None)
}
fn ommers(&self, id: BlockHashOrNumber) -> Result<Option<Vec<Header>>> {
if let Some(number) = self.convert_hash_or_number(id)? {
// TODO: this can be optimized to return empty Vec post-merge

View File

@ -230,6 +230,10 @@ where
Ok(self.tree.pending_block())
}
fn pending_header(&self) -> Result<Option<SealedHeader>> {
Ok(self.tree.pending_header())
}
fn ommers(&self, id: BlockHashOrNumber) -> Result<Option<Vec<Header>>> {
self.database.provider()?.ommers(id)
}

View File

@ -306,6 +306,10 @@ impl BlockProvider for MockEthProvider {
Ok(None)
}
fn pending_header(&self) -> Result<Option<SealedHeader>> {
Ok(None)
}
fn ommers(&self, _id: BlockHashOrNumber) -> Result<Option<Vec<Header>>> {
Ok(None)
}

View File

@ -62,6 +62,10 @@ impl BlockProvider for NoopProvider {
Ok(None)
}
fn pending_header(&self) -> Result<Option<SealedHeader>> {
Ok(None)
}
fn ommers(&self, _id: BlockHashOrNumber) -> Result<Option<Vec<Header>>> {
Ok(None)
}

View File

@ -64,6 +64,12 @@ pub trait BlockProvider:
/// and the caller does not know the hash.
fn pending_block(&self) -> Result<Option<SealedBlock>>;
/// Returns the pending block header if available
///
/// Note: This returns a [SealedHeader] because it's expected that this is sealed by the
/// provider and the caller does not know the hash.
fn pending_header(&self) -> Result<Option<SealedHeader>>;
/// Returns the ommers/uncle headers of the given block from the database.
///
/// Returns `None` if block is not found.