Skip to content

Commit

Permalink
Add vinicity to EVM execution and update on each TX (#1987)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jouzo authored May 15, 2023
1 parent 90cd6de commit ffd3d7c
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 50 deletions.
73 changes: 49 additions & 24 deletions lib/ain-evm/src/backend.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,42 @@
use ethereum::{Account, Log};
use evm::backend::{Apply, ApplyBackend, Backend, Basic};
use hash_db::Hasher as _;
use log::debug;
use log::{debug, trace};
use primitive_types::{H160, H256, U256};
use rlp::{Decodable, Encodable, Rlp};
use sp_core::hexdisplay::AsBytesRef;
use sp_core::Blake2Hasher;
use vsdb_trie_db::MptOnce;

use crate::{evm::TrieDBStore, storage::Storage, traits::BridgeBackend};
use crate::{
evm::TrieDBStore,
storage::{traits::BlockStorage, Storage},
traits::BridgeBackend,
transaction::SignedTx,
};

type Hasher = Blake2Hasher;

fn is_empty_account(account: &Account) -> bool {
account.balance.is_zero() && account.nonce.is_zero() && account.code_hash.is_zero()
}

// TBD
pub struct Vicinity;
#[derive(Default, Debug)]
pub struct Vicinity {
pub gas_price: U256,
pub origin: H160,
pub beneficiary: H160,
pub block_number: U256,
pub timestamp: U256,
pub gas_limit: U256,
pub block_base_fee_per_gas: U256,
}

pub struct EVMBackend {
state: MptOnce,
trie_store: Arc<TrieDBStore>,
storage: Arc<Storage>,
_vicinity: Vicinity,
pub vicinity: Vicinity,
}

type Result<T> = std::result::Result<T, EVMBackendError>;
Expand All @@ -33,7 +46,7 @@ impl EVMBackend {
state_root: H256,
trie_store: Arc<TrieDBStore>,
storage: Arc<Storage>,
_vicinity: Vicinity,
vicinity: Vicinity,
) -> Result<Self> {
let state = trie_store
.trie_db
Expand All @@ -44,7 +57,7 @@ impl EVMBackend {
state,
trie_store,
storage,
_vicinity,
vicinity,
})
}

Expand Down Expand Up @@ -104,6 +117,15 @@ impl EVMBackend {
pub fn commit(&mut self) -> H256 {
self.state.commit().into()
}

pub fn update_vicinity_from_tx(&mut self, tx: &SignedTx) {
self.vicinity = Vicinity {
origin: tx.sender,
gas_price: tx.gas_price(),
gas_limit: tx.gas_limit(),
..self.vicinity
};
}
}

impl EVMBackend {
Expand All @@ -117,43 +139,46 @@ impl EVMBackend {

impl Backend for EVMBackend {
fn gas_price(&self) -> U256 {
debug!(target: "backend", "[EVMBackend] Getting gas");
unimplemented!()
trace!(target: "backend", "[EVMBackend] Getting gas");
self.vicinity.gas_price
}

fn origin(&self) -> H160 {
debug!(target: "backend", "[EVMBackend] Getting origin");
unimplemented!()
trace!(target: "backend", "[EVMBackend] Getting origin");
self.vicinity.origin
}

fn block_hash(&self, _number: U256) -> H256 {
unimplemented!("Implement block_hash function")
fn block_hash(&self, number: U256) -> H256 {
trace!(target: "backend", "[EVMBackend] Getting block hash for block {:x?}", number);
self.storage
.get_block_by_number(&number)
.map_or(H256::zero(), |block| block.header.hash())
}

fn block_number(&self) -> U256 {
unimplemented!()
trace!(target: "backend", "[EVMBackend] Getting current block number");
self.vicinity.block_number
}

fn block_coinbase(&self) -> H160 {
unimplemented!("Implement block_coinbase function")
self.vicinity.beneficiary
}

fn block_timestamp(&self) -> U256 {
unimplemented!("Implement block_timestamp function")
self.vicinity.timestamp
}

fn block_difficulty(&self) -> U256 {
U256::zero()
}

fn block_gas_limit(&self) -> U256 {
unimplemented!("Implement block_gas_limit function")
self.vicinity.gas_limit
}

fn block_base_fee_per_gas(&self) -> U256 {
debug!(target: "backend", "[EVMBackend] Getting block_base_fee_per_gas");
U256::default()
// unimplemented!("Implement block_base_fee_per_gas function")
trace!(target: "backend", "[EVMBackend] Getting block_base_fee_per_gas");
self.vicinity.block_base_fee_per_gas
}

fn chain_id(&self) -> U256 {
Expand All @@ -165,7 +190,7 @@ impl Backend for EVMBackend {
}

fn basic(&self, address: H160) -> Basic {
debug!(target: "backend", "[EVMBackend] basic for address {:x?}", address);
trace!(target: "backend", "[EVMBackend] basic for address {:x?}", address);
self.get_account(address)
.map(|account| Basic {
balance: account.balance,
Expand All @@ -175,14 +200,14 @@ impl Backend for EVMBackend {
}

fn code(&self, address: H160) -> Vec<u8> {
debug!(target: "backend", "[EVMBackend] code for address {:x?}", address);
trace!(target: "backend", "[EVMBackend] code for address {:x?}", address);
self.get_account(address)
.and_then(|account| self.storage.get_code_by_hash(account.code_hash))
.unwrap_or_default()
}

fn storage(&self, address: H160, index: H256) -> H256 {
debug!(target: "backend", "[EVMBackend] Getting storage for address {:x?} at index {:x?}", address, index);
trace!(target: "backend", "[EVMBackend] Getting storage for address {:x?} at index {:x?}", address, index);
self.get_account(address)
.and_then(|account| {
self.trie_store
Expand All @@ -196,7 +221,7 @@ impl Backend for EVMBackend {
}

fn original_storage(&self, address: H160, index: H256) -> Option<H256> {
debug!(target: "backend", "[EVMBackend] Getting original storage for address {:x?} at index {:x?}", address, index);
trace!(target: "backend", "[EVMBackend] Getting original storage for address {:x?} at index {:x?}", address, index);
Some(self.storage(address, index))
}
}
Expand Down
16 changes: 11 additions & 5 deletions lib/ain-evm/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,20 @@ impl EVMHandler {
gas_limit: u64,
access_list: AccessList,
) -> Result<TxResponse, Box<dyn Error>> {
let state_root = self
let (state_root, block_number) = self
.storage
.get_latest_block()
.map(|block| block.header.state_root)
.map(|block| (block.header.state_root, block.header.number))
.unwrap_or_default();
println!("state_root : {:#?}", state_root);
let vicinity = Vicinity {};

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

let mut backend = EVMBackend::from_root(
state_root,
Arc::clone(&self.trie_store),
Expand Down Expand Up @@ -251,13 +258,12 @@ impl EVMHandler {
.or_else(|| self.storage.get_latest_block())
.map(|block| block.header.state_root)
.unwrap_or_default();
let vicinity = Vicinity {};

let backend = EVMBackend::from_root(
state_root,
Arc::clone(&self.trie_store),
Arc::clone(&self.storage),
vicinity,
Vicinity::default(),
)?;
Ok(backend.get_account(address))
}
Expand Down
37 changes: 21 additions & 16 deletions lib/ain-evm/src/executor.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
use crate::{
backend::EVMBackendError,
backend::{EVMBackend, EVMBackendError},
evm::EVMHandler,
traits::{BridgeBackend, Executor, ExecutorContext},
transaction::SignedTx,
};
use ethereum::{EIP658ReceiptData, Log, ReceiptV3};
use ethereum_types::{Bloom, U256};
use evm::{
backend::{ApplyBackend, Backend},
backend::ApplyBackend,
executor::stack::{MemoryStackState, StackExecutor, StackSubstateMetadata},
Config, ExitReason,
};
use primitive_types::H160;
use log::trace;
use primitive_types::{H160, H256};
use std::collections::BTreeMap;

#[derive(Debug)]
pub struct AinExecutor<'backend, B: Backend> {
pub backend: &'backend mut B,
pub struct AinExecutor<'backend> {
backend: &'backend mut EVMBackend,
}

impl<'backend, B> AinExecutor<'backend, B>
where
B: Backend + ApplyBackend + BridgeBackend,
{
pub fn new(backend: &'backend mut B) -> Self {
impl<'backend> AinExecutor<'backend> {}

impl<'backend> AinExecutor<'backend> {
pub fn new(backend: &'backend mut EVMBackend) -> Self {
Self { backend }
}

Expand All @@ -34,12 +33,13 @@ where
pub fn sub_balance(&mut self, address: H160, amount: U256) -> Result<(), EVMBackendError> {
self.backend.sub_balance(address, amount)
}

pub fn commit(&mut self) -> H256 {
self.backend.commit()
}
}

impl<'backend, B> Executor for AinExecutor<'backend, B>
where
B: Backend + ApplyBackend,
{
impl<'backend> Executor for AinExecutor<'backend> {
const CONFIG: Config = Config::london();

fn call(&mut self, ctx: ExecutorContext, apply: bool) -> TxResponse {
Expand Down Expand Up @@ -74,7 +74,7 @@ where
let (values, logs) = executor.into_state().deconstruct();
let logs = logs.into_iter().collect::<Vec<_>>();
if apply && exit_reason.is_succeed() {
self.backend.apply(values, logs.clone(), true);
ApplyBackend::apply(self.backend, values, logs.clone(), true);
}

let receipt = ReceiptV3::EIP1559(EIP658ReceiptData {
Expand All @@ -99,6 +99,11 @@ where

fn exec(&mut self, signed_tx: &SignedTx) -> TxResponse {
let apply = true;
self.backend.update_vicinity_from_tx(signed_tx);
trace!(
"[Executor] Executing EVM TX with vicinity : {:?}",
self.backend.vicinity
);
self.call(
ExecutorContext {
caller: Some(signed_tx.sender),
Expand Down
17 changes: 12 additions & 5 deletions lib/ain-evm/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,20 @@ impl Handlers {
let mut gas_used = 0u64;
let mut logs_bloom: Bloom = Bloom::default();

let (parent_hash, parent_number) = self.block.get_latest_block_hash_and_number();
let state_root = self
.storage
.get_latest_block()
.map_or(GENESIS_STATE_ROOT.parse().unwrap(), |block| {
block.header.state_root
});

let vicinity = Vicinity {};
let vicinity = Vicinity {
beneficiary,
timestamp: U256::from(timestamp),
block_number: parent_number + 1,
..Default::default()
};

let mut backend = EVMBackend::from_root(
state_root,
Expand Down Expand Up @@ -101,7 +107,7 @@ impl Handlers {
EVMHandler::logs_bloom(logs, &mut logs_bloom);
receipts_v3.push(receipt);

executor.backend.commit();
executor.commit();
}
QueueTx::BridgeTx(BridgeTx::EvmIn(BalanceUpdate { address, amount })) => {
debug!(
Expand Down Expand Up @@ -129,8 +135,6 @@ impl Handlers {

self.evm.tx_queues.remove(context);

let (parent_hash, parent_number) = self.block.get_latest_block_hash_and_number();

let block = Block::new(
PartialHeader {
parent_hash,
Expand Down Expand Up @@ -166,7 +170,10 @@ impl Handlers {
);

if update_state {
debug!("new_state_root : {:#x}", block.header.state_root);
debug!(
"[finalize_block] Updating state with new state_root : {:#x}",
block.header.state_root
);
self.block.connect_block(block.clone());
self.receipt.put_receipts(receipts);
}
Expand Down

0 comments on commit ffd3d7c

Please sign in to comment.