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

fix(levm): fixes several bugs found when running the EF tests #1085

Merged
merged 126 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from 120 commits
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
3492657
db, warm addresses and cache scaffold
JereSalo Oct 26, 2024
13d7d47
ongoing changes on db
JereSalo Oct 28, 2024
5fd1345
Add `Database` api
juanimedone Oct 28, 2024
c0f8cf8
some changes in Database and Db
JereSalo Oct 28, 2024
2e9cf34
add method get_from_db_then_cache()
JereSalo Oct 28, 2024
1ddefdf
fix some tests
JereSalo Oct 28, 2024
b5eebd4
Fix environment opcodes
juanimedone Oct 28, 2024
99b4fc3
make changes to vm testing function
JereSalo Oct 28, 2024
6b381a8
Merge branch 'levm/refactor/db' of github.com:lambdaclass/lambda_ethe…
JereSalo Oct 28, 2024
594ef74
fix more tests
JereSalo Oct 28, 2024
cdd786d
fix some issues in vm
JereSalo Oct 28, 2024
0b8614b
Add `get_block_hash`
juanimedone Oct 28, 2024
5c380f1
fix more tests i guess..
JereSalo Oct 28, 2024
db12190
Merge branch 'levm/refactor/db' of github.com:lambdaclass/lambda_ethe…
JereSalo Oct 28, 2024
ffad514
'fix' errors in call opcode
JereSalo Oct 28, 2024
61d36c8
change to create
JereSalo Oct 28, 2024
eaf4616
Fix `SLOAD` and `SSTORE`
juanimedone Oct 28, 2024
f34b493
changes in caching from db
JereSalo Oct 28, 2024
1fa59e0
Merge branch 'levm/refactor/db' of github.com:lambdaclass/lambda_ethe…
JereSalo Oct 28, 2024
c3b21ff
Fix lint
juanimedone Oct 28, 2024
b2fe679
fix errors in tests
JereSalo Oct 28, 2024
b1c9be0
Merge branch 'levm/refactor/db' of github.com:lambdaclass/lambda_ethe…
JereSalo Oct 28, 2024
96e66cc
cache all data added to db in tests
JereSalo Oct 28, 2024
e66aa3e
fix one test...
JereSalo Oct 28, 2024
741a543
fix call tests
JereSalo Oct 28, 2024
91ab731
fix sstore
JereSalo Oct 28, 2024
7c7ada9
fix create tests
JereSalo Oct 28, 2024
842a530
Fix `extcodehash_account_with_empty_code`
juanimedone Oct 28, 2024
965bc4c
Fix compiling warning
juanimedone Oct 28, 2024
439c2ac
change variables names for clarity
JereSalo Oct 29, 2024
abd5789
fix call opcodes, remove delegate and change opcodes that used it
JereSalo Oct 29, 2024
96a83c9
comment delegatecall tests for being messy :)
JereSalo Oct 29, 2024
63d67bc
add comments to callframe attributes
JereSalo Oct 29, 2024
08cc426
run cargo fmt
JereSalo Oct 29, 2024
dd64d70
remove unused object
JereSalo Oct 29, 2024
b463d30
remove commented methods from Db implementation of Database trait
JereSalo Oct 29, 2024
5233c57
delete debug trait for database and vm, for integration to work
JereSalo Oct 29, 2024
e37a47e
change storage key from U256 to H256
JereSalo Oct 29, 2024
9d7e700
change block_number from U256 to u64
JereSalo Oct 29, 2024
c42f9f0
run cargo fmt
JereSalo Oct 29, 2024
18868f6
Merge branch 'main' into levm/refactor/db
juanimedone Oct 29, 2024
84330a6
Merge fixes
juanimedone Oct 30, 2024
97a6e11
Improve call/create transactions handling
maximopalopoli Oct 30, 2024
8a49f1f
Move validations in new to transact
maximopalopoli Oct 30, 2024
f0440fc
Delete commented code
maximopalopoli Oct 30, 2024
55ab9eb
starting changes, doesnt work
maximopalopoli Oct 30, 2024
3cee7e5
environment changes
JereSalo Oct 30, 2024
c04a00f
Fix tests
jrchatruc Oct 30, 2024
fedefff
Fix mutable variable
jrchatruc Oct 30, 2024
4b5f0fc
[WIP] Levm ethereum Rust integration
jrchatruc Oct 30, 2024
167a04e
fix tests and lints
JereSalo Oct 30, 2024
b85bff9
change name of package ethereum_rust_levm
JereSalo Oct 31, 2024
b5dae80
change storewrapper implementation of database methods
JereSalo Oct 31, 2024
5cc1adc
[WIP] More progress
jrchatruc Oct 31, 2024
a979da3
add gas consumed by sstore (without gas refunds)
JereSalo Oct 31, 2024
376248f
fix gas cost issue, now call to a contract works properly
JereSalo Oct 31, 2024
63550e1
fix sstore test
JereSalo Nov 1, 2024
bce322a
Fix clippy alerts and fmt
maximopalopoli Nov 1, 2024
557e57a
Change address obtaining to prevent overflow + fmt
maximopalopoli Nov 1, 2024
d73f18f
add some gas comnsumption comments
JereSalo Nov 4, 2024
5bd6be8
feat(levm): merge `main` into `levm-ethereum-rust-integration` (#1062)
ilitteri Nov 4, 2024
7993506
Merge branch 'main' of github.com:lambdaclass/lambda_ethereum_rust in…
ilitteri Nov 4, 2024
30d447d
fix(levm): fix generic_call (#1063)
JereSalo Nov 4, 2024
b065162
feat(levm): prepare levm-ethereum-rust-integration for merge (#1064)
ilitteri Nov 5, 2024
d2987a8
Fix default execute_block
ilitteri Nov 5, 2024
28f45f9
Add conditional compilation on levm's db
ilitteri Nov 5, 2024
29d56b8
Make ethereum_rust_levm optional
ilitteri Nov 5, 2024
b85cbde
Merge branch 'main' of github.com:lambdaclass/lambda_ethereum_rust in…
ilitteri Nov 5, 2024
9f21a33
Add Ethereum Foundation Tests Setup
ilitteri Nov 5, 2024
fb27487
Handle empty contract code when is CREATE
ilitteri Nov 5, 2024
3a278c8
Fix CALLDATACOPY
ilitteri Nov 5, 2024
2211ce4
Handle SWAP stack underflow
ilitteri Nov 5, 2024
68dbd2b
Fix CALLDATACOPY
ilitteri Nov 5, 2024
3f6ca94
Fix CREATE
ilitteri Nov 6, 2024
648b18e
Fix CREATE2
ilitteri Nov 6, 2024
f94b464
Fix CALLCODE
ilitteri Nov 6, 2024
420158f
Handle invalid opcodes
ilitteri Nov 6, 2024
8c55ccc
Fix SDIV & DIV
ilitteri Nov 6, 2024
597dd31
Fix negation
ilitteri Nov 6, 2024
589917b
Fix MSTORE
ilitteri Nov 6, 2024
b78c5e7
Fix CODECOPY
ilitteri Nov 6, 2024
8c16739
Fix CODECOPY v2
ilitteri Nov 6, 2024
1ab8cb0
Fix local stack overflow
ilitteri Nov 6, 2024
97e7fed
Fix RETURNDATACOPY
ilitteri Nov 6, 2024
26c62b6
Fix tx validation
ilitteri Nov 6, 2024
1d49dd2
Fix CODECOPY v3
ilitteri Nov 6, 2024
f1bd149
Fix DELEGATECALL
ilitteri Nov 6, 2024
0f97145
Fix STATICCALL
ilitteri Nov 6, 2024
fb2b184
Fix unbounded memory access
ilitteri Nov 6, 2024
12b2d94
Fix MSTORE out of bounds
ilitteri Nov 6, 2024
b1976bd
Improve EFTestsReport Display impl
ilitteri Nov 6, 2024
b660a82
Execute VM
ilitteri Nov 6, 2024
71963e9
Handle gas_used overflow
ilitteri Nov 6, 2024
f35a006
Improve EFTestsReport printing
ilitteri Nov 6, 2024
8c21a37
Comment out or remove dbg! macros
ilitteri Nov 6, 2024
1ff2d77
Create issues for TODOs and link them
ilitteri Nov 6, 2024
6a6edd1
Merge branch 'levm-ethereum-rust-integration' of github.com:lambdacla…
ilitteri Nov 6, 2024
d233634
Merge branch 'levm_ef_tests' of github.com:lambdaclass/lambda_ethereu…
ilitteri Nov 6, 2024
7ed25ca
Start ensure_post_state implementation
ilitteri Nov 6, 2024
a0d4e0c
Download ef tests
ilitteri Nov 6, 2024
cf0370b
Merge branch 'main' of github.com:lambdaclass/lambda_ethereum_rust in…
ilitteri Nov 6, 2024
869393a
Merge branch 'levm_ef_tests' of github.com:lambdaclass/lambda_ethereu…
ilitteri Nov 6, 2024
3bed82a
Revert "Download ef tests"
ilitteri Nov 6, 2024
5a2edbd
Update main CI
ilitteri Nov 6, 2024
4c2beef
Add CI for running LEVM EF tests on LEVM changes
ilitteri Nov 6, 2024
a2d6d75
Update .gitignore
ilitteri Nov 6, 2024
eaac8c5
Add commands for running EF Tests
ilitteri Nov 6, 2024
a00b599
Run only ef tests
ilitteri Nov 6, 2024
b864799
Force test running in release
ilitteri Nov 6, 2024
0b6f696
Ignore levm ef tests by default
ilitteri Nov 8, 2024
02860db
Merge branch 'levm_ef_tests' of github.com:lambdaclass/lambda_ethereu…
ilitteri Nov 8, 2024
68daa73
Revert "Fix MSTORE out of bounds"
ilitteri Nov 8, 2024
a88e65b
Fix `op_swap`
ilitteri Nov 8, 2024
02b9c29
Derive Debug & Clone for OpcodeSuccess
ilitteri Nov 8, 2024
9dcc04e
Handle very large numbers in op_log
ilitteri Nov 8, 2024
d249c65
Reduce call frame depth
ilitteri Nov 8, 2024
ce3ad3b
Pop the success value of generic_call in create op
maximopalopoli Nov 8, 2024
00a51eb
fix(levm): avoid panicking in ef tests (#1130)
JereSalo Nov 11, 2024
f7aecc4
fix(levm): fix create2 address generation (#1122)
maximopalopoli Nov 11, 2024
c856f5f
Merge branch 'main' of github.com:lambdaclass/lambda_ethereum_rust in…
ilitteri Nov 11, 2024
e81211c
Test fix CI
jrchatruc Nov 12, 2024
a38d0d5
Fix lint
ilitteri Nov 12, 2024
b277379
Fix lint
ilitteri Nov 12, 2024
dca41b5
Fix lint
ilitteri Nov 12, 2024
01d1de7
cargo fmt
ilitteri Nov 12, 2024
59afa1f
Revert "fix(levm): fix create2 address generation (#1122)"
ilitteri Nov 12, 2024
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
14 changes: 11 additions & 3 deletions crates/vm/levm/src/call_frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@ impl Stack {
self.stack.get(index).ok_or(VMError::StackUnderflow)
}

pub fn swap(&mut self, a: usize, b: usize) {
self.stack.swap(a, b)
pub fn swap(&mut self, a: usize, b: usize) -> Result<(), VMError> {
if a >= self.stack.len() || b >= self.stack.len() {
return Err(VMError::StackUnderflow);
}
self.stack.swap(a, b);
Ok(())
}
}

Expand Down Expand Up @@ -144,6 +148,10 @@ impl CallFrame {
}

fn opcode_at(&self, offset: usize) -> Option<Opcode> {
self.bytecode.get(offset).copied().map(Opcode::from)
self.bytecode
.get(offset)
.copied()
.map(Opcode::try_from)?
.ok()
}
}
9 changes: 9 additions & 0 deletions crates/vm/levm/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ pub fn init_code_cost(init_code_length: usize) -> u64 {
INIT_WORD_COST as u64 * (init_code_length as u64 + 31) / 32
}

pub mod create_opcode {
use ethereum_rust_core::U256;

pub const INIT_CODE_WORD_COST: U256 = U256([2, 0, 0, 0]);
pub const CODE_DEPOSIT_COST: U256 = U256([200, 0, 0, 0]);
pub const CREATE_BASE_COST: U256 = U256([32000, 0, 0, 0]);
}

pub const VERSIONED_HASH_VERSION_KZG: u8 = 0x01;
pub const MAX_BLOB_NUMBER_PER_BLOCK: usize = 6;

Expand All @@ -139,3 +147,4 @@ pub const COLD_STORAGE_ACCESS_COST: U256 = U256([2100, 0, 0, 0]);

// Block constants
pub const LAST_AVAILABLE_BLOCK_LIMIT: U256 = U256([256, 0, 0, 0]);
pub const MAX_BLOCK_GAS_LIMIT: U256 = U256([30_000_000, 0, 0, 0]);
9 changes: 9 additions & 0 deletions crates/vm/levm/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,17 @@ pub enum VMError {
InvalidInitialByte,
NonceOverflow,
InternalError,
MemoryLoadOutOfBounds,
GasLimitPriceProductOverflow,
DataSizeOverflow,
Internal,
GasCostOverflow,
OffsetOverflow,
CreationCostIsTooHigh,
MaxGasLimitExceeded,
}

#[derive(Debug, Clone)]
pub enum OpcodeSuccess {
Continue,
Result(ResultReason),
Expand Down
109 changes: 89 additions & 20 deletions crates/vm/levm/src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,47 +30,116 @@ impl Memory {
}
}

pub fn load(&mut self, offset: usize) -> U256 {
self.resize(offset + 32);
pub fn load(&mut self, offset: usize) -> Result<U256, VMError> {
self.resize(
offset
.checked_add(32)
.ok_or(VMError::MemoryLoadOutOfBounds)?,
);
let value_bytes: [u8; 32] = self
.data
.get(offset..offset + 32)
.unwrap()
.get(
offset
..offset
.checked_add(32)
.ok_or(VMError::MemoryLoadOutOfBounds)?,
)
.ok_or(VMError::MemoryLoadOutOfBounds)?
.try_into()
.unwrap();
U256::from(value_bytes)
Ok(U256::from(value_bytes))
}

pub fn load_range(&mut self, offset: usize, size: usize) -> Vec<u8> {
self.resize(offset + size);
self.data.get(offset..offset + size).unwrap().into()
pub fn load_range(&mut self, offset: usize, size: usize) -> Result<Vec<u8>, VMError> {
self.resize(
offset
.checked_add(size)
.ok_or(VMError::MemoryLoadOutOfBounds)?,
);
self.data
.get(
offset
..offset
.checked_add(size)
.ok_or(VMError::MemoryLoadOutOfBounds)?,
)
.ok_or(VMError::MemoryLoadOutOfBounds)
.map(|slice| slice.to_vec())
}

pub fn store_bytes(&mut self, offset: usize, value: &[u8]) {
pub fn store_bytes(&mut self, offset: usize, value: &[u8]) -> Result<(), VMError> {
let len = value.len();
self.resize(offset + len);
self.data
.splice(offset..offset + len, value.iter().copied());
self.resize(
offset
.checked_add(len)
.ok_or(VMError::MemoryLoadOutOfBounds)?,
);
self.data.splice(
offset
..offset
.checked_add(len)
.ok_or(VMError::MemoryLoadOutOfBounds)?,
value.iter().copied(),
);
Ok(())
}

pub fn store_n_bytes(&mut self, offset: usize, value: &[u8], size: usize) {
self.resize(offset + size);
self.data
.splice(offset..offset + size, value.iter().copied());
pub fn store_n_bytes(
&mut self,
offset: usize,
value: &[u8],
size: usize,
) -> Result<(), VMError> {
self.resize(
offset
.checked_add(size)
.ok_or(VMError::MemoryLoadOutOfBounds)?,
);
self.data.splice(
offset
..offset
.checked_add(size)
.ok_or(VMError::MemoryLoadOutOfBounds)?,
value.iter().copied(),
);
Ok(())
}

pub fn size(&self) -> U256 {
U256::from(self.data.len())
}

pub fn copy(&mut self, src_offset: usize, dest_offset: usize, size: usize) {
let max_size = std::cmp::max(src_offset + size, dest_offset + size);
pub fn copy(
&mut self,
src_offset: usize,
dest_offset: usize,
size: usize,
) -> Result<(), VMError> {
let max_size = std::cmp::max(
src_offset
.checked_add(size)
.ok_or(VMError::MemoryLoadOutOfBounds)?,
dest_offset
.checked_add(size)
.ok_or(VMError::MemoryLoadOutOfBounds)?,
);
self.resize(max_size);
let mut temp = vec![0u8; size];

temp.copy_from_slice(&self.data[src_offset..src_offset + size]);
temp.copy_from_slice(
&self.data[src_offset
..src_offset
.checked_add(size)
.ok_or(VMError::MemoryLoadOutOfBounds)?],
);

self.data[dest_offset
..dest_offset
.checked_add(size)
.ok_or(VMError::MemoryLoadOutOfBounds)?]
.copy_from_slice(&temp);

self.data[dest_offset..dest_offset + size].copy_from_slice(&temp);
Ok(())
}

pub fn expansion_cost(&self, memory_byte_size: usize) -> Result<U256, VMError> {
Expand Down
13 changes: 10 additions & 3 deletions crates/vm/levm/src/opcode_handlers/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ impl VM {
current_call_frame.stack.push(U256::zero())?;
return Ok(OpcodeSuccess::Continue);
}
let quotient = dividend / divisor;
let Some(quotient) = dividend.checked_div(divisor) else {
current_call_frame.stack.push(U256::zero())?;
return Ok(OpcodeSuccess::Continue);
};
current_call_frame.stack.push(quotient)?;

Ok(OpcodeSuccess::Continue)
Expand Down Expand Up @@ -88,7 +91,10 @@ impl VM {
} else {
divisor
};
let quotient = dividend / divisor;
let Some(quotient) = dividend.checked_div(divisor) else {
current_call_frame.stack.push(U256::zero())?;
return Ok(OpcodeSuccess::Continue);
};
let quotient_is_negative = dividend_is_negative ^ divisor_is_negative;
let quotient = if quotient_is_negative {
negate(quotient)
Expand Down Expand Up @@ -264,5 +270,6 @@ fn abs(value: U256) -> U256 {

/// Negates a number in two's complement
fn negate(value: U256) -> U256 {
!value + U256::one()
let inverted = !value;
inverted.saturating_add(U256::one())
}
Loading
Loading