Skip to content

Commit

Permalink
EVM: Clean up backend vicinity (#2641)
Browse files Browse the repository at this point in the history
* Fix vicinity when creating backend instances, better refactors

* Rename to eth debug RPC for cpp exports

* Clean up setting vicinity pipeline with into impl
  • Loading branch information
sieniven authored Oct 31, 2023
1 parent 47d2c5e commit bc79d30
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 113 deletions.
4 changes: 2 additions & 2 deletions lib/ain-cpp-imports/src/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub mod ffi {
fn getNumCores() -> i32;
fn getCORSAllowedOrigin() -> String;
fn getNumConnections() -> i32;
fn isDebugEnabled() -> bool;
fn isDebugTraceEnabled() -> bool;
fn isEthDebugRPCEnabled() -> bool;
fn isEthDebugTraceRPCEnabled() -> bool;
}
}
12 changes: 6 additions & 6 deletions lib/ain-cpp-imports/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,10 @@ mod ffi {
pub fn getNumConnections() -> i32 {
unimplemented!("{}", UNIMPL_MSG)
}
pub fn isDebugEnabled() -> bool {
pub fn isEthDebugRPCEnabled() -> bool {
unimplemented!("{}", UNIMPL_MSG)
}
pub fn isDebugTraceEnabled() -> bool {
pub fn isEthDebugTraceRPCEnabled() -> bool {
unimplemented!("{}", UNIMPL_MSG)
}
}
Expand Down Expand Up @@ -217,12 +217,12 @@ pub fn get_num_connections() -> i32 {
ffi::getNumConnections()
}

pub fn is_debug_enabled() -> bool {
ffi::isDebugEnabled()
pub fn is_eth_debug_rpc_enabled() -> bool {
ffi::isEthDebugRPCEnabled()
}

pub fn is_debug_trace_enabled() -> bool {
ffi::isDebugTraceEnabled()
pub fn is_eth_debug_trace_rpc_enabled() -> bool {
ffi::isEthDebugTraceRPCEnabled()
}

#[cfg(test)]
Expand Down
25 changes: 21 additions & 4 deletions lib/ain-evm/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{
};

use anyhow::format_err;
use ethereum::{Account, Log};
use ethereum::{Account, Header, Log};
use ethereum_types::{H160, H256, U256};
use evm::backend::{Apply, ApplyBackend, Backend, Basic};
use hash_db::Hasher as _;
Expand All @@ -30,18 +30,33 @@ fn is_empty_account(account: &Account) -> bool {

#[derive(Default, Debug, Clone)]
pub struct Vicinity {
pub gas_price: U256,
pub origin: H160,
pub gas_price: U256,
pub total_gas_used: U256,
pub beneficiary: H160,
pub block_number: U256,
pub timestamp: U256,
pub total_gas_used: U256,
pub block_difficulty: U256,
pub block_gas_limit: U256,
pub block_base_fee_per_gas: U256,
pub block_randomness: Option<H256>,
}

impl From<Header> for Vicinity {
fn from(header: Header) -> Self {
Vicinity {
beneficiary: header.beneficiary,
block_number: header.number,
timestamp: U256::from(header.timestamp),
block_difficulty: header.difficulty,
block_gas_limit: header.gas_limit,
block_base_fee_per_gas: header.base_fee,
block_randomness: None,
..Default::default()
}
}
}

#[derive(Debug, Clone)]
struct OverlayData {
account: Account,
Expand Down Expand Up @@ -269,11 +284,13 @@ impl EVMBackend {
Ok(self.state.commit().into())
}

pub fn update_vicinity_from_tx(&mut self, tx: &SignedTx) {
pub fn update_vicinity_from_tx(&mut self, tx: &SignedTx) -> Result<()> {
self.vicinity = Vicinity {
origin: tx.sender,
gas_price: tx.effective_gas_price(self.block_base_fee_per_gas())?,
..self.vicinity
};
Ok(())
}

pub fn update_vicinity_with_gas_used(&mut self, gas_used: U256) {
Expand Down
113 changes: 45 additions & 68 deletions lib/ain-evm/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,25 @@ use ethereum::{
TransactionV2,
};
use ethereum_types::{Bloom, BloomInput, H160, H256, U256};
use evm::executor::stack::{MemoryStackState, StackExecutor, StackSubstateMetadata};
use evm::gasometer::tracing::using as gas_using;
use evm::Config;
use evm::{
executor::stack::{MemoryStackState, StackExecutor, StackSubstateMetadata},
gasometer::tracing::using as gas_using,
Config,
};
use evm_runtime::tracing::using as runtime_using;
use log::{debug, trace};
use lru::LruCache;
use parking_lot::Mutex;
use vsdb_core::vsdb_set_base_dir;

use crate::precompiles::MetachainPrecompiles;
use crate::{
backend::{BackendError, EVMBackend, Vicinity},
block::INITIAL_BASE_FEE,
blocktemplate::BlockTemplate,
executor::{AinExecutor, ExecutorContext, TxResponse},
fee::calculate_max_prepay_gas_fee,
gas::check_tx_intrinsic_gas,
precompiles::MetachainPrecompiles,
receipt::ReceiptService,
storage::{traits::BlockStorage, Storage},
transaction::SignedTx,
Expand Down Expand Up @@ -250,47 +252,25 @@ impl EVMCoreService {
access_list,
block_number,
} = arguments;
debug!("[call] caller: {:?}", caller);

let (
state_root,
block_number,
beneficiary,
base_fee,
timestamp,
block_difficulty,
block_gas_limit,
) = self
let block_header = self
.storage
.get_block_by_number(&block_number)?
.map(|block| {
(
block.header.state_root,
block.header.number,
block.header.beneficiary,
block.header.base_fee,
block.header.timestamp,
block.header.difficulty,
block.header.gas_limit,
)
})
.unwrap_or_default();
.map(|block| block.header)
.ok_or(format_err!(
"[call] Block number {:x?} not found",
block_number
))?;
let state_root = block_header.state_root;
debug!(
"Calling EVM at block number : {:#x}, state_root : {:#x}",
block_number, state_root
);
debug!("[call] caller: {:?}", caller);
let vicinity = Vicinity {
gas_price,
origin: caller,
beneficiary,
block_number,
timestamp: U256::from(timestamp),
total_gas_used: U256::zero(),
block_difficulty,
block_gas_limit,
block_base_fee_per_gas: base_fee,
block_randomness: None,
};

let mut vicinity = Vicinity::from(block_header);
vicinity.gas_price = gas_price;
vicinity.origin = caller;
debug!("[call] vicinity: {:?}", vicinity);

let mut backend = EVMBackend::from_root(
Expand Down Expand Up @@ -759,38 +739,38 @@ impl EVMCoreService {
#[allow(clippy::too_many_arguments)]
pub fn trace_transaction(
&self,
caller: H160,
to: H160,
value: U256,
data: &[u8],
gas_limit: u64,
access_list: AccessList,
tx: &SignedTx,
block_number: U256,
) -> Result<(Vec<ExecutionStep>, bool, Vec<u8>, u64)> {
let (state_root, block_number) = self
let caller = tx.sender;
let to = tx.to().ok_or(format_err!(
"debug_traceTransaction does not support contract creation transactions",
))?;
let value = tx.value();
let data = tx.data();
let gas_limit = u64::try_from(tx.gas_limit())?;
let access_list = tx.access_list();

let block_header = self
.storage
.get_block_by_number(&block_number)?
.ok_or_else(|| format_err!("Cannot find block"))
.map(|block| (block.header.state_root, block.header.number))?;

.ok_or_else(|| format_err!("Block not found"))
.map(|block| block.header)?;
let state_root = block_header.state_root;
debug!(
"Calling EVM at block number : {:#x}, state_root : {:#x}",
block_number, state_root
);

let vicinity = Vicinity {
block_number,
origin: caller,
..Default::default()
};

let backend = EVMBackend::from_root(
let vicinity = Vicinity::from(block_header);
let mut backend = EVMBackend::from_root(
state_root,
Arc::clone(&self.trie_store),
Arc::clone(&self.storage),
vicinity,
)
.map_err(|e| format_err!("Could not restore backend {}", e))?;
backend.update_vicinity_from_tx(tx)?;

static CONFIG: Config = Config::shanghai();
let metadata = StackSubstateMetadata::new(gas_limit, &CONFIG);
Expand All @@ -804,7 +784,6 @@ impl EVMCoreService {
let mut gas_listener = crate::eventlistener::GasListener::new();

let al = access_list.clone();

gas_using(&mut gas_listener, move || {
let access_list = al
.into_iter()
Expand Down Expand Up @@ -921,28 +900,26 @@ impl EVMCoreService {
}

pub fn get_latest_block_backend(&self) -> Result<EVMBackend> {
let (state_root, block_number) = self
let block_header = self
.storage
.get_latest_block()?
.map(|block| (block.header.state_root, block.header.number))
.unwrap_or_default();

.map(|block| block.header)
.ok_or(format_err!(
"[get_latest_block_backend] Latest block not found",
))?;
let state_root = block_header.state_root;
trace!(
"[get_latest_block_backend] At block number : {:#x}, state_root : {:#x}",
block_number,
state_root
block_header.number,
state_root,
);

let vicinity = Vicinity::from(block_header);
EVMBackend::from_root(
state_root,
Arc::clone(&self.trie_store),
Arc::clone(&self.storage),
Vicinity {
block_gas_limit: U256::from(
self.storage.get_attributes_or_default()?.block_gas_limit,
),
..Vicinity::default()
},
vicinity,
)
}

Expand Down
11 changes: 6 additions & 5 deletions lib/ain-evm/src/eventlistener.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::core::ExecutionStep;
use crate::opcode;
use evm::gasometer::tracing::{Event as GasEvent, EventListener as GasEventListener};
use evm_runtime::tracing::{Event as RuntimeEvent, EventListener as RuntimeEventListener};
use evm_runtime::Opcode;
use std::collections::VecDeque;

use crate::{core::ExecutionStep, opcode};
use evm::gasometer::tracing::{Event as GasEvent, EventListener as GasEventListener};
use evm_runtime::{
tracing::{Event as RuntimeEvent, EventListener as RuntimeEventListener},
Opcode,
};
use log::debug;

pub struct Listener {
Expand Down
2 changes: 1 addition & 1 deletion lib/ain-evm/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ impl<'backend> AinExecutor<'backend> {
base_fee: U256,
system_tx: bool,
) -> Result<(TxResponse, ReceiptV3)> {
self.backend.update_vicinity_from_tx(signed_tx);
self.backend.update_vicinity_from_tx(signed_tx)?;
trace!(
"[Executor] Executing EVM TX with vicinity : {:?}",
self.backend.vicinity
Expand Down
33 changes: 12 additions & 21 deletions lib/ain-grpc/src/rpc/debug.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use anyhow::format_err;
use std::sync::Arc;

use ain_evm::storage::traits::{ReceiptStorage, TransactionStorage};
use ain_evm::transaction::SignedTx;
use ain_evm::{
core::EthCallArgs, evm::EVMServices, executor::TxResponse, storage::block_store::DumpArg,
core::EthCallArgs,
evm::EVMServices,
executor::TxResponse,
storage::{
block_store::DumpArg,
traits::{ReceiptStorage, TransactionStorage},
},
transaction::SignedTx,
};
use ethereum::Account;
use ethereum_types::{H256, U256};
Expand All @@ -15,10 +19,10 @@ use jsonrpsee::{
use log::debug;
use rlp::{Decodable, Rlp};

use crate::transaction::{TraceLogs, TraceTransactionResult};
use crate::{
call_request::CallRequest,
errors::{to_custom_err, RPCError},
transaction::{TraceLogs, TraceTransactionResult},
};

#[derive(Serialize, Deserialize)]
Expand Down Expand Up @@ -67,7 +71,7 @@ impl MetachainDebugRPCModule {
}

fn is_enabled(&self) -> RpcResult<()> {
if !ain_cpp_imports::is_debug_enabled() {
if !ain_cpp_imports::is_eth_debug_rpc_enabled() {
return Err(Error::Custom(
"debug_* RPCs have not been enabled".to_string(),
));
Expand All @@ -77,7 +81,7 @@ impl MetachainDebugRPCModule {
}

fn is_trace_enabled(&self) -> RpcResult<()> {
if !ain_cpp_imports::is_debug_trace_enabled() {
if !ain_cpp_imports::is_eth_debug_trace_rpc_enabled() {
return Err(Error::Custom(
"debug_trace* RPCs have not been enabled".to_string(),
));
Expand Down Expand Up @@ -114,21 +118,8 @@ impl MetachainDebugRPCServer for MetachainDebugRPCModule {
let (logs, succeeded, return_data, gas_used) = self
.handler
.core
.trace_transaction(
signed_tx.sender,
signed_tx.to().ok_or_else(|| {
format_err!(
"debug_traceTransaction does not support contract creation transactions"
)
})?,
signed_tx.value(),
signed_tx.data(),
signed_tx.gas_limit().as_u64(),
signed_tx.access_list(),
receipt.block_number,
)
.trace_transaction(&signed_tx, receipt.block_number)
.map_err(|e| Error::Custom(format!("Error calling EVM : {e:?}")))?;

let trace_logs = logs.iter().map(|x| TraceLogs::from(x.clone())).collect();

Ok(TraceTransactionResult {
Expand Down
Loading

0 comments on commit bc79d30

Please sign in to comment.