Skip to content

Commit

Permalink
feat(levm): track initial account states to compare with the updated …
Browse files Browse the repository at this point in the history
…ones (#1280)

**Motivation**

<!-- Why does this pull request exist? What are its goals? -->

If an account is updated in LEVM but not in the compared VM we only
print a message saying so. It'd be useful to know what has changed in
the account state in those cases.
  • Loading branch information
ilitteri authored Nov 27, 2024
1 parent 74351b1 commit de07d1b
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 6 deletions.
89 changes: 88 additions & 1 deletion cmd/ef_tests/levm/report.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use crate::runner::{EFTestRunnerError, InternalError};
use colored::Colorize;
use ethrex_core::{Address, H256};
use ethrex_levm::errors::{TransactionReport, TxResult, VMError};
use ethrex_levm::{
errors::{TransactionReport, TxResult, VMError},
Account, StorageSlot,
};
use ethrex_storage::{error::StoreError, AccountUpdate};
use ethrex_vm::SpecId;
use revm::primitives::{EVMError, ExecutionResult as RevmExecutionResult};
Expand Down Expand Up @@ -340,6 +343,7 @@ impl EFTestReport {

#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct AccountUpdatesReport {
pub initial_accounts: HashMap<Address, Account>,
pub levm_account_updates: Vec<AccountUpdate>,
pub revm_account_updates: Vec<AccountUpdate>,
pub levm_updated_accounts_only: HashSet<Address>,
Expand All @@ -353,6 +357,89 @@ impl fmt::Display for AccountUpdatesReport {
for levm_updated_account_only in self.levm_updated_accounts_only.iter() {
writeln!(f, " {levm_updated_account_only:#x}:")?;
writeln!(f, "{}", " Was updated in LEVM but not in REVM".red())?;
let initial_account = self
.initial_accounts
.get(levm_updated_account_only)
.cloned()
.unwrap_or_default();
let updated_account_update = self
.levm_account_updates
.iter()
.find(|account_update| &account_update.address == levm_updated_account_only)
.unwrap();
let updated_account_storage = updated_account_update
.added_storage
.iter()
.map(|(key, value)| {
let storage_slot = StorageSlot {
original_value: *value,
current_value: *value,
};
(*key, storage_slot)
})
.collect();
let updated_account_info = updated_account_update.info.clone().unwrap();
let updated_account = Account::new(
updated_account_info.balance,
updated_account_update.code.clone().unwrap_or_default(),
updated_account_info.nonce,
updated_account_storage,
);
let mut updates = 0;
if initial_account.info.balance != updated_account.info.balance {
writeln!(
f,
"{}",
format!(
" Balance updated: {initial_balance} -> {updated_balance}",
initial_balance = initial_account.info.balance,
updated_balance = updated_account.info.balance
)
.red()
)?;
updates += 1;
}
if initial_account.info.nonce != updated_account.info.nonce {
writeln!(
f,
"{}",
format!(
" Nonce updated: {initial_nonce} -> {updated_nonce}",
initial_nonce = initial_account.info.nonce,
updated_nonce = updated_account.info.nonce
)
.red()
)?;
updates += 1;
}
if initial_account.info.bytecode != updated_account.info.bytecode {
writeln!(
f,
"{}",
format!(
" Code updated: {initial_code}, {updated_code}",
initial_code = hex::encode(&initial_account.info.bytecode),
updated_code = hex::encode(&updated_account.info.bytecode)
)
.red()
)?;
updates += 1;
}
for (added_storage_address, added_storage_slot) in updated_account.storage.iter() {
writeln!(
f,
"{}",
format!(
" Storage slot added: {added_storage_address}: {} -> {}",
added_storage_slot.original_value, added_storage_slot.current_value
)
.red()
)?;
updates += 1;
}
if updates == 0 {
writeln!(f, "{}", " No changes".green())?;
}
}
for revm_updated_account_only in self.revm_updated_accounts_only.iter() {
writeln!(f, " {revm_updated_account_only:#x}:")?;
Expand Down
48 changes: 43 additions & 5 deletions cmd/ef_tests/levm/runner/revm_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ use crate::{
types::EFTest,
utils::load_initial_state,
};
use ethrex_core::{types::TxKind, Address};
use ethrex_levm::errors::{TransactionReport, TxResult};
use ethrex_core::{types::TxKind, Address, H256};
use ethrex_levm::{
errors::{TransactionReport, TxResult},
Account, StorageSlot,
};
use ethrex_storage::{error::StoreError, AccountUpdate};
use ethrex_vm::{db::StoreWrapper, EvmState, RevmAddress, RevmU256, SpecId};
use revm::{
Expand All @@ -17,7 +20,7 @@ use revm::{
},
Evm as Revm,
};
use std::collections::HashSet;
use std::collections::{HashMap, HashSet};

pub fn re_run_failed_ef_test(
test: &EFTest,
Expand Down Expand Up @@ -245,8 +248,11 @@ pub fn ensure_post_state(
None => {
let levm_account_updates = levm_runner::get_state_transitions(levm_execution_report);
let revm_account_updates = ethrex_vm::get_state_transitions(revm_state);
let account_updates_report =
compare_levm_revm_account_updates(&levm_account_updates, &revm_account_updates);
let account_updates_report = compare_levm_revm_account_updates(
test,
&levm_account_updates,
&revm_account_updates,
);
re_run_report.register_account_updates_report(*vector, account_updates_report);
}
}
Expand All @@ -255,9 +261,40 @@ pub fn ensure_post_state(
}

pub fn compare_levm_revm_account_updates(
test: &EFTest,
levm_account_updates: &[AccountUpdate],
revm_account_updates: &[AccountUpdate],
) -> AccountUpdatesReport {
let mut initial_accounts: HashMap<Address, Account> = test
.pre
.0
.iter()
.map(|(account_address, pre_state_value)| {
let account_storage = pre_state_value
.storage
.iter()
.map(|(key, value)| {
let mut temp = [0u8; 32];
key.to_big_endian(&mut temp);
let storage_slot = StorageSlot {
original_value: *value,
current_value: *value,
};
(H256::from_slice(&temp), storage_slot)
})
.collect();
let account = Account::new(
pre_state_value.balance,
pre_state_value.code.clone(),
pre_state_value.nonce.as_u64(),
account_storage,
);
(*account_address, account)
})
.collect();
initial_accounts
.entry(test.env.current_coinbase)
.or_default();
let levm_updated_accounts = levm_account_updates
.iter()
.map(|account_update| account_update.address)
Expand All @@ -268,6 +305,7 @@ pub fn compare_levm_revm_account_updates(
.collect::<HashSet<Address>>();

AccountUpdatesReport {
initial_accounts,
levm_account_updates: levm_account_updates.to_vec(),
revm_account_updates: revm_account_updates.to_vec(),
levm_updated_accounts_only: levm_updated_accounts
Expand Down

0 comments on commit de07d1b

Please sign in to comment.