Skip to content

Commit

Permalink
more tests passing
Browse files Browse the repository at this point in the history
  • Loading branch information
max-wickham committed Oct 28, 2024
1 parent d1eb2f2 commit 93ad837
Show file tree
Hide file tree
Showing 18 changed files with 667 additions and 279 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ num256 = "0.5.1"
lazy_static = "1.4.0"
phf = {version = "0.11.2", features = ["macros"]}
quote = "1.0.35"

[profile.dev]
opt-level = 3 # Use slightly better optimizations.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ This repo contains both some local tests as well as using the official Ethereum

This project is very much a work in progress. Most of the Opcodes are now functional, however, some core functionality is still being implemented such as better transaction reverting etc. The aim is to get all of the basic official Ethereum VMTests working as quickly as possible, (of which about 60% are currently passing). Then teh code will be refactored significantly to clean up all the mess created getting things to work.

After this work will be done on optimisations of the interpreter, such as analysis to combine gas additions, as well as adding new instructions to combine blocks of code.
After this work will be done on optimisations of the interpreter, such as analysis to combine gas additions, as well as adding new instructions to combine blocks of code.
22 changes: 21 additions & 1 deletion src/configs/gas_costs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::ops::Div;

use primitive_types::{H256, U256};
use static_costs::{G_COLD_ACCOUNT_ACCESS, G_NEW_ACCOUNT, G_SELF_DESTRUCT};

use crate::evm_logic::util::{ZERO, ZERO_H256};

Expand Down Expand Up @@ -57,6 +58,7 @@ pub enum DynamicCosts {
target_is_cold: bool,
empty_account: bool,
is_delegate: bool,
is_code: bool,
},
StaticCall {
/// Call gas.
Expand Down Expand Up @@ -107,11 +109,16 @@ pub enum DynamicCosts {
ExtCodeCopy {
target_is_cold: bool,
size_bytes: usize,
},
SelfDestruct {
address_exists: bool,
is_cold: bool,
}
}

impl DynamicCosts {
// TODO add error here
#[inline]
pub fn cost(&self) -> u64 {
match self {
DynamicCosts::Balance { target_is_cold } => {
Expand Down Expand Up @@ -140,7 +147,10 @@ impl DynamicCosts {
empty_account,
target_is_cold,
is_delegate,
is_code,
} => {
println!("empty_account: {}", empty_account);
println!("target_is_cold {}", target_is_cold);

0 + if *target_is_cold {
static_costs::G_COLD_ACCOUNT_ACCESS
Expand All @@ -150,7 +160,7 @@ impl DynamicCosts {
if !value.eq(&ZERO) & !is_delegate {
static_costs::G_CALL_VALUE - static_costs::G_CALL_STIPEND
} else {0} +
if *empty_account {
if !value.eq(&ZERO) & *empty_account & !is_delegate &!is_code {
static_costs::G_NEW_ACCOUNT
} else {0}
}
Expand Down Expand Up @@ -212,6 +222,13 @@ impl DynamicCosts {
gas_cost

}
DynamicCosts::SelfDestruct { address_exists, is_cold} => {
G_SELF_DESTRUCT + if !*address_exists {
G_NEW_ACCOUNT
} else {
if *is_cold { G_COLD_ACCOUNT_ACCESS } else { 0 }
}
}
_ => 0,
}
}
Expand All @@ -224,6 +241,9 @@ impl DynamicCosts {
0
}
}
DynamicCosts::SelfDestruct { address_exists, is_cold } => {
24000
}
_ => 0,
}
}
Expand Down
40 changes: 29 additions & 11 deletions src/evm_logic/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::result::{ExecutionError, ExecutionResult, ExecutionSuccess};
use crate::runtime::Runtime;

use super::state::memory::Memory;
use super::state::program_memory::ProgramMemory;
use super::state::stack::Stack;

use primitive_types::U256;
Expand All @@ -30,7 +31,7 @@ struct Message {
pub struct EVMContext {
stack: Stack,
memory: Memory,
program: Memory,
program: ProgramMemory,
program_counter: usize,
contract_address: U256,
transaction: Transaction,
Expand Down Expand Up @@ -58,17 +59,11 @@ impl EVMContext {
EVMContext {
stack: Stack::new(),
memory: Memory::new(),
program: Memory::from(
program: ProgramMemory::from(
&code,
Some(&mut GasRecorder {
gas_input: gas as usize,
gas_usage: 0,
gas_refunds: 0,
}),
),
program_counter: 0,
contract_address: address,
// TODO remove need to clone here
transaction: transaction,
message: message,
last_return_data: Memory::new(),
Expand All @@ -88,9 +83,10 @@ impl EVMContext {
fn execute_program(&mut self, runtime: &mut impl Runtime, debug: bool) -> ExecutionResult {
runtime.add_context();
let mut result;
let jump_dests = decoder::calculate_jump_dests(self);
if self.program.len() != 0 {
loop {
result = self.execute_next_instruction(runtime, debug);
result = self.execute_next_instruction(runtime, &jump_dests, debug);
match &result {
ExecutionResult::InProgress => {}
_ => {
Expand All @@ -107,6 +103,7 @@ impl EVMContext {
} else {
self.gas_recorder.gas_usage as u64
} as usize;

if debug {
println!("Sub Gas Usage {:x}", self.gas_recorder.gas_usage);
}
Expand All @@ -121,17 +118,17 @@ impl EVMContext {
panic!("Program shouldn't have excited in progress");
}
}

result
}

#[inline]
fn execute_next_instruction(
&mut self,
runtime: &mut impl Runtime,
jump_dests: &[usize],
debug: bool,
) -> ExecutionResult {
decoder::decode_instruction(self, runtime, debug)
decoder::decode_instruction(self, runtime, jump_dests, debug)
}

#[inline]
Expand Down Expand Up @@ -168,6 +165,7 @@ pub fn execute_transaction(
origin: origin,
gas_price: gas_price,
};

let mut evm = EVMContext::create_sub_context(
contract_address,
message,
Expand All @@ -178,6 +176,7 @@ pub fn execute_transaction(
0,
false,
);

evm.gas_recorder
.record_gas_usage(static_costs::G_TRANSACTION);
evm.gas_recorder
Expand All @@ -187,5 +186,24 @@ pub fn execute_transaction(
}
let result = evm.execute_program(runtime, debug);
let gas_usage = evm.gas_recorder.usage_with_refunds();

// Increase Nonce and deposit the value
runtime.increase_nonce(origin);
match result {
ExecutionResult::Success(_) => {
runtime.deposit(contract_address, value);
// withdraw the value from the sender
runtime.withdrawal(origin, value);
}
_ => {}
}
// Withdraw the gas from the wallet
let eth_usage = (gas_usage) * gas_price.as_usize();
runtime.withdrawal(origin, U256::from(eth_usage as u64));
runtime.deposit(runtime.block_coinbase(), U256::from(eth_usage as u64));

// TODO handle not enough eth for gas and value

runtime.merge_context();
return (result, gas_usage);
}
Loading

0 comments on commit 93ad837

Please sign in to comment.