Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EVM: Clean up backend vicinity #2641

Merged
merged 3 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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