From 223f6cd0b7bbb5b65df3f84021e101f2883af30a Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 2 Apr 2024 22:08:49 +0200 Subject: [PATCH 001/105] chore: fix publish revm-precompile (#1258) --- publish.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/publish.sh b/publish.sh index ce3c389c..b6944ae0 100755 --- a/publish.sh +++ b/publish.sh @@ -1,7 +1,10 @@ #!/bin/bash +# stop on error +set -e + cargo publish --package revm-primitives -cargo publish --package revm-precompiles +cargo publish --package revm-precompile cargo publish --package revm-interpreter cargo publish --package revm cargo publish --package revme From 8af9531c1e103ecd5d2b6a8aa820b366bb480f32 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Wed, 3 Apr 2024 10:07:03 +0200 Subject: [PATCH 002/105] feat(interpreter): test Host object-safety, allow `dyn Host` in instructions (#1245) --- crates/interpreter/src/host.rs | 13 +++++++ .../src/instructions/arithmetic.rs | 22 ++++++------ .../interpreter/src/instructions/bitwise.rs | 28 +++++++-------- .../interpreter/src/instructions/control.rs | 18 +++++----- crates/interpreter/src/instructions/host.rs | 34 +++++++++---------- .../src/instructions/host/call_helpers.rs | 2 +- .../interpreter/src/instructions/host_env.rs | 22 ++++++------ crates/interpreter/src/instructions/memory.rs | 10 +++--- crates/interpreter/src/instructions/opcode.rs | 19 ++++++----- crates/interpreter/src/instructions/stack.rs | 10 +++--- crates/interpreter/src/instructions/system.rs | 24 ++++++------- crates/interpreter/src/interpreter.rs | 26 ++++++++++++-- crates/revm/src/inspector/handler_register.rs | 19 +++++------ 13 files changed, 140 insertions(+), 107 deletions(-) diff --git a/crates/interpreter/src/host.rs b/crates/interpreter/src/host.rs index fff18bb8..6caecee4 100644 --- a/crates/interpreter/src/host.rs +++ b/crates/interpreter/src/host.rs @@ -65,3 +65,16 @@ pub struct SStoreResult { /// Is storage slot loaded from database pub is_cold: bool, } + +#[cfg(test)] +mod tests { + use super::*; + + fn assert_host() {} + + #[test] + fn object_safety() { + assert_host::(); + assert_host::(); + } +} diff --git a/crates/interpreter/src/instructions/arithmetic.rs b/crates/interpreter/src/instructions/arithmetic.rs index 583299d5..2d767279 100644 --- a/crates/interpreter/src/instructions/arithmetic.rs +++ b/crates/interpreter/src/instructions/arithmetic.rs @@ -5,25 +5,25 @@ use crate::{ Host, Interpreter, }; -pub fn wrapping_add(interpreter: &mut Interpreter, _host: &mut H) { +pub fn wrapping_add(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = op1.wrapping_add(*op2); } -pub fn wrapping_mul(interpreter: &mut Interpreter, _host: &mut H) { +pub fn wrapping_mul(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); *op2 = op1.wrapping_mul(*op2); } -pub fn wrapping_sub(interpreter: &mut Interpreter, _host: &mut H) { +pub fn wrapping_sub(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = op1.wrapping_sub(*op2); } -pub fn div(interpreter: &mut Interpreter, _host: &mut H) { +pub fn div(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); if *op2 != U256::ZERO { @@ -31,13 +31,13 @@ pub fn div(interpreter: &mut Interpreter, _host: &mut H) { } } -pub fn sdiv(interpreter: &mut Interpreter, _host: &mut H) { +pub fn sdiv(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); *op2 = i256_div(op1, *op2); } -pub fn rem(interpreter: &mut Interpreter, _host: &mut H) { +pub fn rem(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); if *op2 != U256::ZERO { @@ -45,25 +45,25 @@ pub fn rem(interpreter: &mut Interpreter, _host: &mut H) { } } -pub fn smod(interpreter: &mut Interpreter, _host: &mut H) { +pub fn smod(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); *op2 = i256_mod(op1, *op2) } -pub fn addmod(interpreter: &mut Interpreter, _host: &mut H) { +pub fn addmod(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::MID); pop_top!(interpreter, op1, op2, op3); *op3 = op1.add_mod(op2, *op3) } -pub fn mulmod(interpreter: &mut Interpreter, _host: &mut H) { +pub fn mulmod(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::MID); pop_top!(interpreter, op1, op2, op3); *op3 = op1.mul_mod(op2, *op3) } -pub fn exp(interpreter: &mut Interpreter, _host: &mut H) { +pub fn exp(interpreter: &mut Interpreter, _host: &mut H) { pop_top!(interpreter, op1, op2); gas_or_fail!(interpreter, gas::exp_cost::(*op2)); *op2 = op1.pow(*op2); @@ -84,7 +84,7 @@ pub fn exp(interpreter: &mut Interpreter, _host: &mut H) { /// `y | !mask` where `|` is the bitwise `OR` and `!` is bitwise negation. Similarly, if /// `b == 0` then the yellow paper says the output should start with all zeros, then end with /// bits from `b`; this is equal to `y & mask` where `&` is bitwise `AND`. -pub fn signextend(interpreter: &mut Interpreter, _host: &mut H) { +pub fn signextend(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::LOW); pop_top!(interpreter, ext, x); // For 31 we also don't need to do anything. diff --git a/crates/interpreter/src/instructions/bitwise.rs b/crates/interpreter/src/instructions/bitwise.rs index d8329642..586af76c 100644 --- a/crates/interpreter/src/instructions/bitwise.rs +++ b/crates/interpreter/src/instructions/bitwise.rs @@ -7,67 +7,67 @@ use crate::{ use core::cmp::Ordering; use revm_primitives::uint; -pub fn lt(interpreter: &mut Interpreter, _host: &mut H) { +pub fn lt(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = U256::from(op1 < *op2); } -pub fn gt(interpreter: &mut Interpreter, _host: &mut H) { +pub fn gt(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = U256::from(op1 > *op2); } -pub fn slt(interpreter: &mut Interpreter, _host: &mut H) { +pub fn slt(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = U256::from(i256_cmp(&op1, op2) == Ordering::Less); } -pub fn sgt(interpreter: &mut Interpreter, _host: &mut H) { +pub fn sgt(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = U256::from(i256_cmp(&op1, op2) == Ordering::Greater); } -pub fn eq(interpreter: &mut Interpreter, _host: &mut H) { +pub fn eq(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = U256::from(op1 == *op2); } -pub fn iszero(interpreter: &mut Interpreter, _host: &mut H) { +pub fn iszero(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1); *op1 = U256::from(*op1 == U256::ZERO); } -pub fn bitand(interpreter: &mut Interpreter, _host: &mut H) { +pub fn bitand(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = op1 & *op2; } -pub fn bitor(interpreter: &mut Interpreter, _host: &mut H) { +pub fn bitor(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = op1 | *op2; } -pub fn bitxor(interpreter: &mut Interpreter, _host: &mut H) { +pub fn bitxor(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = op1 ^ *op2; } -pub fn not(interpreter: &mut Interpreter, _host: &mut H) { +pub fn not(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1); *op1 = !*op1; } -pub fn byte(interpreter: &mut Interpreter, _host: &mut H) { +pub fn byte(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); @@ -81,7 +81,7 @@ pub fn byte(interpreter: &mut Interpreter, _host: &mut H) { } /// EIP-145: Bitwise shifting instructions in EVM -pub fn shl(interpreter: &mut Interpreter, _host: &mut H) { +pub fn shl(interpreter: &mut Interpreter, _host: &mut H) { check!(interpreter, CONSTANTINOPLE); gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); @@ -89,7 +89,7 @@ pub fn shl(interpreter: &mut Interpreter, _host: &mut H) { } /// EIP-145: Bitwise shifting instructions in EVM -pub fn shr(interpreter: &mut Interpreter, _host: &mut H) { +pub fn shr(interpreter: &mut Interpreter, _host: &mut H) { check!(interpreter, CONSTANTINOPLE); gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); @@ -97,7 +97,7 @@ pub fn shr(interpreter: &mut Interpreter, _host: &mut H) { } /// EIP-145: Bitwise shifting instructions in EVM -pub fn sar(interpreter: &mut Interpreter, _host: &mut H) { +pub fn sar(interpreter: &mut Interpreter, _host: &mut H) { check!(interpreter, CONSTANTINOPLE); gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index 61a132e9..26333b77 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -4,13 +4,13 @@ use crate::{ Host, InstructionResult, Interpreter, InterpreterResult, }; -pub fn jump(interpreter: &mut Interpreter, _host: &mut H) { +pub fn jump(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::MID); pop!(interpreter, dest); jump_inner(interpreter, dest); } -pub fn jumpi(interpreter: &mut Interpreter, _host: &mut H) { +pub fn jumpi(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::HIGH); pop!(interpreter, dest, value); if value != U256::ZERO { @@ -29,11 +29,11 @@ fn jump_inner(interpreter: &mut Interpreter, dest: U256) { interpreter.instruction_pointer = unsafe { interpreter.contract.bytecode.as_ptr().add(dest) }; } -pub fn jumpdest(interpreter: &mut Interpreter, _host: &mut H) { +pub fn jumpdest(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::JUMPDEST); } -pub fn pc(interpreter: &mut Interpreter, _host: &mut H) { +pub fn pc(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); // - 1 because we have already advanced the instruction pointer in `Interpreter::step` push!(interpreter, U256::from(interpreter.program_counter() - 1)); @@ -63,27 +63,27 @@ fn return_inner(interpreter: &mut Interpreter, instruction_result: InstructionRe }; } -pub fn ret(interpreter: &mut Interpreter, _host: &mut H) { +pub fn ret(interpreter: &mut Interpreter, _host: &mut H) { return_inner(interpreter, InstructionResult::Return); } /// EIP-140: REVERT instruction -pub fn revert(interpreter: &mut Interpreter, _host: &mut H) { +pub fn revert(interpreter: &mut Interpreter, _host: &mut H) { check!(interpreter, BYZANTIUM); return_inner(interpreter, InstructionResult::Revert); } /// Stop opcode. This opcode halts the execution. -pub fn stop(interpreter: &mut Interpreter, _host: &mut H) { +pub fn stop(interpreter: &mut Interpreter, _host: &mut H) { interpreter.instruction_result = InstructionResult::Stop; } /// Invalid opcode. This opcode halts the execution. -pub fn invalid(interpreter: &mut Interpreter, _host: &mut H) { +pub fn invalid(interpreter: &mut Interpreter, _host: &mut H) { interpreter.instruction_result = InstructionResult::InvalidFEOpcode; } /// Unknown opcode. This opcode halts the execution. -pub fn unknown(interpreter: &mut Interpreter, _host: &mut H) { +pub fn unknown(interpreter: &mut Interpreter, _host: &mut H) { interpreter.instruction_result = InstructionResult::OpcodeNotFound; } diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index 7357adf4..b19d0dfc 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -13,7 +13,7 @@ use core::cmp::min; use revm_primitives::BLOCK_HASH_HISTORY; use std::{boxed::Box, vec::Vec}; -pub fn balance(interpreter: &mut Interpreter, host: &mut H) { +pub fn balance(interpreter: &mut Interpreter, host: &mut H) { pop_address!(interpreter, address); let Some((balance, is_cold)) = host.balance(address) else { interpreter.instruction_result = InstructionResult::FatalExternalError; @@ -34,7 +34,7 @@ pub fn balance(interpreter: &mut Interpreter, host: &mut H) } /// EIP-1884: Repricing for trie-size-dependent opcodes -pub fn selfbalance(interpreter: &mut Interpreter, host: &mut H) { +pub fn selfbalance(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, ISTANBUL); gas!(interpreter, gas::LOW); let Some((balance, _)) = host.balance(interpreter.contract.address) else { @@ -44,7 +44,7 @@ pub fn selfbalance(interpreter: &mut Interpreter, host: &mu push!(interpreter, balance); } -pub fn extcodesize(interpreter: &mut Interpreter, host: &mut H) { +pub fn extcodesize(interpreter: &mut Interpreter, host: &mut H) { pop_address!(interpreter, address); let Some((code, is_cold)) = host.code(address) else { interpreter.instruction_result = InstructionResult::FatalExternalError; @@ -69,7 +69,7 @@ pub fn extcodesize(interpreter: &mut Interpreter, host: &mu } /// EIP-1052: EXTCODEHASH opcode -pub fn extcodehash(interpreter: &mut Interpreter, host: &mut H) { +pub fn extcodehash(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, CONSTANTINOPLE); pop_address!(interpreter, address); let Some((code_hash, is_cold)) = host.code_hash(address) else { @@ -93,7 +93,7 @@ pub fn extcodehash(interpreter: &mut Interpreter, host: &mu push_b256!(interpreter, code_hash); } -pub fn extcodecopy(interpreter: &mut Interpreter, host: &mut H) { +pub fn extcodecopy(interpreter: &mut Interpreter, host: &mut H) { pop_address!(interpreter, address); pop!(interpreter, memory_offset, code_offset, len_u256); @@ -120,7 +120,7 @@ pub fn extcodecopy(interpreter: &mut Interpreter, host: &mu .set_data(memory_offset, code_offset, len, code.bytes()); } -pub fn blockhash(interpreter: &mut Interpreter, host: &mut H) { +pub fn blockhash(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BLOCKHASH); pop_top!(interpreter, number); @@ -139,7 +139,7 @@ pub fn blockhash(interpreter: &mut Interpreter, host: &mut H) { *number = U256::ZERO; } -pub fn sload(interpreter: &mut Interpreter, host: &mut H) { +pub fn sload(interpreter: &mut Interpreter, host: &mut H) { pop!(interpreter, index); let Some((value, is_cold)) = host.sload(interpreter.contract.address, index) else { @@ -150,7 +150,7 @@ pub fn sload(interpreter: &mut Interpreter, host: &mut H) { push!(interpreter, value); } -pub fn sstore(interpreter: &mut Interpreter, host: &mut H) { +pub fn sstore(interpreter: &mut Interpreter, host: &mut H) { check_staticcall!(interpreter); pop!(interpreter, index, value); @@ -173,7 +173,7 @@ pub fn sstore(interpreter: &mut Interpreter, host: &mut H) /// EIP-1153: Transient storage opcodes /// Store value to transient storage -pub fn tstore(interpreter: &mut Interpreter, host: &mut H) { +pub fn tstore(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, CANCUN); check_staticcall!(interpreter); gas!(interpreter, gas::WARM_STORAGE_READ_COST); @@ -185,7 +185,7 @@ pub fn tstore(interpreter: &mut Interpreter, host: &mut H) /// EIP-1153: Transient storage opcodes /// Load value from transient storage -pub fn tload(interpreter: &mut Interpreter, host: &mut H) { +pub fn tload(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, CANCUN); gas!(interpreter, gas::WARM_STORAGE_READ_COST); @@ -194,7 +194,7 @@ pub fn tload(interpreter: &mut Interpreter, host: &mut H) { *index = host.tload(interpreter.contract.address, *index); } -pub fn log(interpreter: &mut Interpreter, host: &mut H) { +pub fn log(interpreter: &mut Interpreter, host: &mut H) { check_staticcall!(interpreter); pop!(interpreter, offset, len); @@ -227,7 +227,7 @@ pub fn log(interpreter: &mut Interpreter, host: &mut H) host.log(log); } -pub fn selfdestruct(interpreter: &mut Interpreter, host: &mut H) { +pub fn selfdestruct(interpreter: &mut Interpreter, host: &mut H) { check_staticcall!(interpreter); pop_address!(interpreter, target); @@ -245,7 +245,7 @@ pub fn selfdestruct(interpreter: &mut Interpreter, host: &m interpreter.instruction_result = InstructionResult::SelfDestruct; } -pub fn create( +pub fn create( interpreter: &mut Interpreter, host: &mut H, ) { @@ -314,7 +314,7 @@ pub fn create( interpreter.instruction_result = InstructionResult::CallOrCreate; } -pub fn call(interpreter: &mut Interpreter, host: &mut H) { +pub fn call(interpreter: &mut Interpreter, host: &mut H) { pop!(interpreter, local_gas_limit); pop_address!(interpreter, to); // max gas limit is not possible in real ethereum situation. @@ -374,7 +374,7 @@ pub fn call(interpreter: &mut Interpreter, host: &mut H) { interpreter.instruction_result = InstructionResult::CallOrCreate; } -pub fn call_code(interpreter: &mut Interpreter, host: &mut H) { +pub fn call_code(interpreter: &mut Interpreter, host: &mut H) { pop!(interpreter, local_gas_limit); pop_address!(interpreter, to); // max gas limit is not possible in real ethereum situation. @@ -429,7 +429,7 @@ pub fn call_code(interpreter: &mut Interpreter, host: &mut interpreter.instruction_result = InstructionResult::CallOrCreate; } -pub fn delegate_call(interpreter: &mut Interpreter, host: &mut H) { +pub fn delegate_call(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, HOMESTEAD); pop!(interpreter, local_gas_limit); pop_address!(interpreter, to); @@ -475,7 +475,7 @@ pub fn delegate_call(interpreter: &mut Interpreter, host: & interpreter.instruction_result = InstructionResult::CallOrCreate; } -pub fn static_call(interpreter: &mut Interpreter, host: &mut H) { +pub fn static_call(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, BYZANTIUM); pop!(interpreter, local_gas_limit); pop_address!(interpreter, to); diff --git a/crates/interpreter/src/instructions/host/call_helpers.rs b/crates/interpreter/src/instructions/host/call_helpers.rs index 3156c9a7..05a7a203 100644 --- a/crates/interpreter/src/instructions/host/call_helpers.rs +++ b/crates/interpreter/src/instructions/host/call_helpers.rs @@ -34,7 +34,7 @@ pub fn get_memory_input_and_out_ranges( } #[inline] -pub fn calc_call_gas( +pub fn calc_call_gas( interpreter: &mut Interpreter, host: &mut H, to: Address, diff --git a/crates/interpreter/src/instructions/host_env.rs b/crates/interpreter/src/instructions/host_env.rs index 230bb39b..1b0c3995 100644 --- a/crates/interpreter/src/instructions/host_env.rs +++ b/crates/interpreter/src/instructions/host_env.rs @@ -5,28 +5,28 @@ use crate::{ }; /// EIP-1344: ChainID opcode -pub fn chainid(interpreter: &mut Interpreter, host: &mut H) { +pub fn chainid(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, ISTANBUL); gas!(interpreter, gas::BASE); push!(interpreter, U256::from(host.env().cfg.chain_id)); } -pub fn coinbase(interpreter: &mut Interpreter, host: &mut H) { +pub fn coinbase(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BASE); push_b256!(interpreter, host.env().block.coinbase.into_word()); } -pub fn timestamp(interpreter: &mut Interpreter, host: &mut H) { +pub fn timestamp(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, host.env().block.timestamp); } -pub fn number(interpreter: &mut Interpreter, host: &mut H) { +pub fn number(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, host.env().block.number); } -pub fn difficulty(interpreter: &mut Interpreter, host: &mut H) { +pub fn difficulty(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BASE); if SPEC::enabled(MERGE) { push_b256!(interpreter, host.env().block.prevrandao.unwrap()); @@ -35,30 +35,30 @@ pub fn difficulty(interpreter: &mut Interpreter, host: &mut } } -pub fn gaslimit(interpreter: &mut Interpreter, host: &mut H) { +pub fn gaslimit(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, host.env().block.gas_limit); } -pub fn gasprice(interpreter: &mut Interpreter, host: &mut H) { +pub fn gasprice(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, host.env().effective_gas_price()); } /// EIP-3198: BASEFEE opcode -pub fn basefee(interpreter: &mut Interpreter, host: &mut H) { +pub fn basefee(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, LONDON); gas!(interpreter, gas::BASE); push!(interpreter, host.env().block.basefee); } -pub fn origin(interpreter: &mut Interpreter, host: &mut H) { +pub fn origin(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BASE); push_b256!(interpreter, host.env().tx.caller.into_word()); } // EIP-4844: Shard Blob Transactions -pub fn blob_hash(interpreter: &mut Interpreter, host: &mut H) { +pub fn blob_hash(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, CANCUN); gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, index); @@ -70,7 +70,7 @@ pub fn blob_hash(interpreter: &mut Interpreter, host: &mut } /// EIP-7516: BLOBBASEFEE opcode -pub fn blob_basefee(interpreter: &mut Interpreter, host: &mut H) { +pub fn blob_basefee(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, CANCUN); gas!(interpreter, gas::BASE); push!( diff --git a/crates/interpreter/src/instructions/memory.rs b/crates/interpreter/src/instructions/memory.rs index 264c4c61..6ee2d88f 100644 --- a/crates/interpreter/src/instructions/memory.rs +++ b/crates/interpreter/src/instructions/memory.rs @@ -5,7 +5,7 @@ use crate::{ }; use core::cmp::max; -pub fn mload(interpreter: &mut Interpreter, _host: &mut H) { +pub fn mload(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop!(interpreter, index); let index = as_usize_or_fail!(interpreter, index); @@ -13,7 +13,7 @@ pub fn mload(interpreter: &mut Interpreter, _host: &mut H) { push!(interpreter, interpreter.shared_memory.get_u256(index)); } -pub fn mstore(interpreter: &mut Interpreter, _host: &mut H) { +pub fn mstore(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop!(interpreter, index, value); let index = as_usize_or_fail!(interpreter, index); @@ -21,7 +21,7 @@ pub fn mstore(interpreter: &mut Interpreter, _host: &mut H) { interpreter.shared_memory.set_u256(index, value); } -pub fn mstore8(interpreter: &mut Interpreter, _host: &mut H) { +pub fn mstore8(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop!(interpreter, index, value); let index = as_usize_or_fail!(interpreter, index); @@ -29,13 +29,13 @@ pub fn mstore8(interpreter: &mut Interpreter, _host: &mut H) { interpreter.shared_memory.set_byte(index, value.byte(0)) } -pub fn msize(interpreter: &mut Interpreter, _host: &mut H) { +pub fn msize(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, U256::from(interpreter.shared_memory.len())); } // EIP-5656: MCOPY - Memory copying instruction -pub fn mcopy(interpreter: &mut Interpreter, _host: &mut H) { +pub fn mcopy(interpreter: &mut Interpreter, _host: &mut H) { check!(interpreter, CANCUN); pop!(interpreter, dst, src, len); diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index c935775a..8896c9da 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -28,12 +28,12 @@ pub type BoxedInstructionTable<'a, H> = [BoxedInstruction<'a, H>; 256]; /// Note that `Plain` variant gives us 10-20% faster Interpreter execution. /// /// Boxed variant can be used to wrap plain function pointer with closure. -pub enum InstructionTables<'a, H> { +pub enum InstructionTables<'a, H: ?Sized> { Plain(InstructionTable), Boxed(BoxedInstructionTable<'a, H>), } -impl InstructionTables<'_, H> { +impl InstructionTables<'_, H> { /// Creates a plain instruction table for the given spec. #[inline] pub const fn new_plain() -> Self { @@ -41,7 +41,7 @@ impl InstructionTables<'_, H> { } } -impl<'a, H: Host + 'a> InstructionTables<'a, H> { +impl<'a, H: Host + ?Sized + 'a> InstructionTables<'a, H> { /// Inserts a boxed instruction into the table with the specified index. /// /// This will convert the table into the [BoxedInstructionTable] variant if it is currently a @@ -93,13 +93,14 @@ impl<'a, H: Host + 'a> InstructionTables<'a, H> { /// Make instruction table. #[inline] -pub const fn make_instruction_table() -> InstructionTable { +pub const fn make_instruction_table() -> InstructionTable { // Force const-eval of the table creation, making this function trivial. // TODO: Replace this with a `const {}` block once it is stable. - struct ConstTable { - _phantom: core::marker::PhantomData<(H, SPEC)>, + struct ConstTable { + _host: core::marker::PhantomData, + _spec: core::marker::PhantomData, } - impl ConstTable { + impl ConstTable { const NEW: InstructionTable = { let mut tables: InstructionTable = [control::unknown; 256]; let mut i = 0; @@ -120,7 +121,7 @@ pub fn make_boxed_instruction_table<'a, H, SPEC, FN>( mut outer: FN, ) -> BoxedInstructionTable<'a, H> where - H: Host, + H: Host + ?Sized, SPEC: Spec + 'a, FN: FnMut(Instruction) -> BoxedInstruction<'a, H>, { @@ -154,7 +155,7 @@ macro_rules! opcodes { }; /// Returns the instruction function for the given opcode and spec. - pub const fn instruction(opcode: u8) -> Instruction { + pub const fn instruction(opcode: u8) -> Instruction { match opcode { $($name => $f,)* _ => control::unknown, diff --git a/crates/interpreter/src/instructions/stack.rs b/crates/interpreter/src/instructions/stack.rs index 14d9e352..52676875 100644 --- a/crates/interpreter/src/instructions/stack.rs +++ b/crates/interpreter/src/instructions/stack.rs @@ -4,7 +4,7 @@ use crate::{ Host, Interpreter, }; -pub fn pop(interpreter: &mut Interpreter, _host: &mut H) { +pub fn pop(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); if let Err(result) = interpreter.stack.pop() { interpreter.instruction_result = result; @@ -14,7 +14,7 @@ pub fn pop(interpreter: &mut Interpreter, _host: &mut H) { /// EIP-3855: PUSH0 instruction /// /// Introduce a new instruction which pushes the constant value 0 onto the stack. -pub fn push0(interpreter: &mut Interpreter, _host: &mut H) { +pub fn push0(interpreter: &mut Interpreter, _host: &mut H) { check!(interpreter, SHANGHAI); gas!(interpreter, gas::BASE); if let Err(result) = interpreter.stack.push(U256::ZERO) { @@ -22,7 +22,7 @@ pub fn push0(interpreter: &mut Interpreter, _host: &mut H) } } -pub fn push(interpreter: &mut Interpreter, _host: &mut H) { +pub fn push(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); // SAFETY: In analysis we append trailing bytes to the bytecode so that this is safe to do // without bounds checking. @@ -37,14 +37,14 @@ pub fn push(interpreter: &mut Interpreter, _host: &mut interpreter.instruction_pointer = unsafe { ip.add(N) }; } -pub fn dup(interpreter: &mut Interpreter, _host: &mut H) { +pub fn dup(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); if let Err(result) = interpreter.stack.dup::() { interpreter.instruction_result = result; } } -pub fn swap(interpreter: &mut Interpreter, _host: &mut H) { +pub fn swap(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); if let Err(result) = interpreter.stack.swap::() { interpreter.instruction_result = result; diff --git a/crates/interpreter/src/instructions/system.rs b/crates/interpreter/src/instructions/system.rs index 55109d80..be81fb31 100644 --- a/crates/interpreter/src/instructions/system.rs +++ b/crates/interpreter/src/instructions/system.rs @@ -4,7 +4,7 @@ use crate::{ Host, InstructionResult, Interpreter, }; -pub fn keccak256(interpreter: &mut Interpreter, _host: &mut H) { +pub fn keccak256(interpreter: &mut Interpreter, _host: &mut H) { pop!(interpreter, from, len); let len = as_usize_or_fail!(interpreter, len); gas_or_fail!(interpreter, gas::keccak256_cost(len as u64)); @@ -19,22 +19,22 @@ pub fn keccak256(interpreter: &mut Interpreter, _host: &mut H) { push_b256!(interpreter, hash); } -pub fn address(interpreter: &mut Interpreter, _host: &mut H) { +pub fn address(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); push_b256!(interpreter, interpreter.contract.address.into_word()); } -pub fn caller(interpreter: &mut Interpreter, _host: &mut H) { +pub fn caller(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); push_b256!(interpreter, interpreter.contract.caller.into_word()); } -pub fn codesize(interpreter: &mut Interpreter, _host: &mut H) { +pub fn codesize(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, U256::from(interpreter.contract.bytecode.len())); } -pub fn codecopy(interpreter: &mut Interpreter, _host: &mut H) { +pub fn codecopy(interpreter: &mut Interpreter, _host: &mut H) { pop!(interpreter, memory_offset, code_offset, len); let len = as_usize_or_fail!(interpreter, len); gas_or_fail!(interpreter, gas::verylowcopy_cost(len as u64)); @@ -54,7 +54,7 @@ pub fn codecopy(interpreter: &mut Interpreter, _host: &mut H) { ); } -pub fn calldataload(interpreter: &mut Interpreter, _host: &mut H) { +pub fn calldataload(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop!(interpreter, index); let index = as_usize_saturated!(index); @@ -70,17 +70,17 @@ pub fn calldataload(interpreter: &mut Interpreter, _host: &mut H) { push_b256!(interpreter, load); } -pub fn calldatasize(interpreter: &mut Interpreter, _host: &mut H) { +pub fn calldatasize(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, U256::from(interpreter.contract.input.len())); } -pub fn callvalue(interpreter: &mut Interpreter, _host: &mut H) { +pub fn callvalue(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, interpreter.contract.value); } -pub fn calldatacopy(interpreter: &mut Interpreter, _host: &mut H) { +pub fn calldatacopy(interpreter: &mut Interpreter, _host: &mut H) { pop!(interpreter, memory_offset, data_offset, len); let len = as_usize_or_fail!(interpreter, len); gas_or_fail!(interpreter, gas::verylowcopy_cost(len as u64)); @@ -101,7 +101,7 @@ pub fn calldatacopy(interpreter: &mut Interpreter, _host: &mut H) { } /// EIP-211: New opcodes: RETURNDATASIZE and RETURNDATACOPY -pub fn returndatasize(interpreter: &mut Interpreter, _host: &mut H) { +pub fn returndatasize(interpreter: &mut Interpreter, _host: &mut H) { check!(interpreter, BYZANTIUM); gas!(interpreter, gas::BASE); push!( @@ -111,7 +111,7 @@ pub fn returndatasize(interpreter: &mut Interpreter, _host: } /// EIP-211: New opcodes: RETURNDATASIZE and RETURNDATACOPY -pub fn returndatacopy(interpreter: &mut Interpreter, _host: &mut H) { +pub fn returndatacopy(interpreter: &mut Interpreter, _host: &mut H) { check!(interpreter, BYZANTIUM); pop!(interpreter, memory_offset, offset, len); let len = as_usize_or_fail!(interpreter, len); @@ -132,7 +132,7 @@ pub fn returndatacopy(interpreter: &mut Interpreter, _host: } } -pub fn gas(interpreter: &mut Interpreter, _host: &mut H) { +pub fn gas(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, U256::from(interpreter.gas.remaining())); } diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index 2a1e99a3..4ee51db7 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -283,7 +283,7 @@ impl Interpreter { /// /// Internally it will increment instruction pointer by one. #[inline(always)] - fn step(&mut self, instruction_table: &[FN; 256], host: &mut H) + fn step(&mut self, instruction_table: &[FN; 256], host: &mut H) where FN: Fn(&mut Interpreter, &mut H), { @@ -305,7 +305,7 @@ impl Interpreter { } /// Executes the interpreter until it returns or stops. - pub fn run( + pub fn run( &mut self, shared_memory: SharedMemory, instruction_table: &[FN; 256], @@ -356,3 +356,25 @@ impl InterpreterResult { self.result.is_error() } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::{opcode::InstructionTable, DummyHost}; + use revm_primitives::CancunSpec; + + #[test] + fn object_safety() { + let mut interp = Interpreter::new(Contract::default(), u64::MAX, false); + + let mut host = crate::DummyHost::default(); + let table: InstructionTable = + crate::opcode::make_instruction_table::(); + let _ = interp.run(EMPTY_SHARED_MEMORY, &table, &mut host); + + let host: &mut dyn Host = &mut host as &mut dyn Host; + let table: InstructionTable = + crate::opcode::make_instruction_table::(); + let _ = interp.run(EMPTY_SHARED_MEMORY, &table, host); + } +} diff --git a/crates/revm/src/inspector/handler_register.rs b/crates/revm/src/inspector/handler_register.rs index ba5fb8e1..0cf496a4 100644 --- a/crates/revm/src/inspector/handler_register.rs +++ b/crates/revm/src/inspector/handler_register.rs @@ -260,26 +260,23 @@ pub fn inspector_instruction< #[cfg(test)] mod tests { - use super::*; use crate::{ db::EmptyDB, inspectors::NoOpInspector, - interpreter::{opcode::*, CallInputs, CreateInputs, Interpreter}, + interpreter::{opcode::*, CallInputs, CallOutcome, CreateInputs, CreateOutcome}, primitives::BerlinSpec, - Database, Evm, EvmContext, Inspector, + EvmContext, }; - use revm_interpreter::{CallOutcome, CreateOutcome}; - + // Test that this pattern builds. #[test] fn test_make_boxed_instruction_table() { - // test that this pattern builds. - let inst: InstructionTable> = - make_instruction_table::, BerlinSpec>(); - let _test: BoxedInstructionTable<'_, Evm<'_, _, _>> = - make_boxed_instruction_table::<'_, Evm<'_, NoOpInspector, EmptyDB>, BerlinSpec, _>( - inst, + type MyEvm<'a> = Evm<'a, NoOpInspector, EmptyDB>; + let table: InstructionTable> = make_instruction_table::, BerlinSpec>(); + let _boxed_table: BoxedInstructionTable<'_, MyEvm<'_>> = + make_boxed_instruction_table::<'_, MyEvm<'_>, BerlinSpec, _>( + table, inspector_instruction, ); } From 5d5c5f1e3ac6348059c9d30cd32085cc9dc9ae29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Apr 2024 21:46:28 +0200 Subject: [PATCH 003/105] chore(deps): bump secp256k1 from 0.28.2 to 0.29.0 (#1260) Bumps [secp256k1](https://github.com/rust-bitcoin/rust-secp256k1) from 0.28.2 to 0.29.0. - [Changelog](https://github.com/rust-bitcoin/rust-secp256k1/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-bitcoin/rust-secp256k1/compare/secp256k1-0.28.2...secp256k1-0.29.0) --- updated-dependencies: - dependency-name: secp256k1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- crates/precompile/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index efc16bdb..50451980 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2695,9 +2695,9 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.28.2" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10" +checksum = "0e0cc0f1cf93f4969faf3ea1c7d8a9faed25918d96affa959720823dfe86d4f3" dependencies = [ "rand", "secp256k1-sys", @@ -2705,9 +2705,9 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.9.2" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d1746aae42c19d583c3c1a8c646bfad910498e2051c551a7f2e3c0c9fbb7eb" +checksum = "1433bd67156263443f14d603720b082dd3121779323fce20cba2aa07b874bc1b" dependencies = [ "cc", ] diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index 7690195c..72844309 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -26,7 +26,7 @@ c-kzg = { version = "1.0.0", default-features = false, optional = true } # ecRecover precompile k256 = { version = "0.13.3", default-features = false, features = ["ecdsa"] } -secp256k1 = { version = "0.28.2", default-features = false, features = [ +secp256k1 = { version = "0.29.0", default-features = false, features = [ "alloc", "recovery", "rand", From 96dda385ae09963f883ab5506bdfb6f28b7d6df7 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Wed, 3 Apr 2024 21:51:29 +0200 Subject: [PATCH 004/105] feat(interpreter): remove SPEC generic from gas calculation functions (#1243) * feat(interpreter): remove SPEC generic from gas calculation functions * feat(interpreter): make most gas cost calculation functions `const` * set_final_refund * unused * fix: optimism * chore: use `is_london: bool` instead of `SpecId` in `Gas::set_final_refund` --- crates/interpreter/src/gas.rs | 5 +- crates/interpreter/src/gas/calc.rs | 209 +++++++++++------- .../src/instructions/arithmetic.rs | 2 +- crates/interpreter/src/instructions/host.rs | 17 +- .../src/instructions/host/call_helpers.rs | 3 +- crates/interpreter/src/interpreter.rs | 2 +- crates/primitives/src/specification.rs | 8 +- crates/revm/src/handler/mainnet/execution.rs | 12 +- crates/revm/src/handler/mainnet/validation.rs | 3 +- crates/revm/src/optimism/handler_register.rs | 2 +- 10 files changed, 153 insertions(+), 110 deletions(-) diff --git a/crates/interpreter/src/gas.rs b/crates/interpreter/src/gas.rs index 01598cc1..51739b10 100644 --- a/crates/interpreter/src/gas.rs +++ b/crates/interpreter/src/gas.rs @@ -5,7 +5,6 @@ mod constants; pub use calc::*; pub use constants::*; -use revm_primitives::{Spec, SpecId::LONDON}; /// Represents the state of gas during execution. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] @@ -94,8 +93,8 @@ impl Gas { /// /// Related to EIP-3529: Reduction in refunds #[inline] - pub fn set_final_refund(&mut self) { - let max_refund_quotient = if SPEC::enabled(LONDON) { 5 } else { 2 }; + pub fn set_final_refund(&mut self, is_london: bool) { + let max_refund_quotient = if is_london { 5 } else { 2 }; self.refunded = (self.refunded() as u64).min(self.spent() / max_refund_quotient) as i64; } diff --git a/crates/interpreter/src/gas/calc.rs b/crates/interpreter/src/gas/calc.rs index b7f91b18..dcc949c0 100644 --- a/crates/interpreter/src/gas/calc.rs +++ b/crates/interpreter/src/gas/calc.rs @@ -1,13 +1,34 @@ use super::constants::*; use crate::inner_models::SelfDestructResult; -use crate::primitives::{Address, Spec, SpecId::*, U256}; +use crate::primitives::{Address, SpecId, U256}; use std::vec::Vec; +/// `const` Option `?`. +macro_rules! tri { + ($e:expr) => { + match $e { + Some(v) => v, + None => return None, + } + }; +} + +/// `const` unwrap. +macro_rules! opt_unwrap { + ($e:expr) => { + match $e { + Some(v) => v, + None => panic!("unwrap failed"), + } + }; +} + +/// `SSTORE` opcode refund calculation. #[allow(clippy::collapsible_else_if)] -pub fn sstore_refund(original: U256, current: U256, new: U256) -> i64 { - if SPEC::enabled(ISTANBUL) { +pub fn sstore_refund(spec_id: SpecId, original: U256, current: U256, new: U256) -> i64 { + if spec_id.is_enabled_in(SpecId::ISTANBUL) { // EIP-3529: Reduction in refunds - let sstore_clears_schedule = if SPEC::enabled(LONDON) { + let sstore_clears_schedule = if spec_id.is_enabled_in(SpecId::LONDON) { (SSTORE_RESET - COLD_SLOAD_COST + ACCESS_LIST_STORAGE_KEY) as i64 } else { REFUND_SSTORE_CLEARS @@ -29,10 +50,10 @@ pub fn sstore_refund(original: U256, current: U256, new: U256) -> i6 } if original == new { - let (gas_sstore_reset, gas_sload) = if SPEC::enabled(BERLIN) { + let (gas_sstore_reset, gas_sload) = if spec_id.is_enabled_in(SpecId::BERLIN) { (SSTORE_RESET - COLD_SLOAD_COST, WARM_STORAGE_READ_COST) } else { - (SSTORE_RESET, sload_cost::(false)) + (SSTORE_RESET, sload_cost(spec_id, false)) }; if original == U256::ZERO { refund += (SSTORE_SET - gas_sload) as i64; @@ -53,16 +74,12 @@ pub fn sstore_refund(original: U256, current: U256, new: U256) -> i6 } } +/// `CREATE2` opcode cost calculation. #[inline] -pub fn create2_cost(len: usize) -> Option { - let base = CREATE; - // ceil(len / 32.0) - let len = len as u64; - let sha_addup_base = (len / 32) + u64::from((len % 32) != 0); - let sha_addup = KECCAK256WORD.checked_mul(sha_addup_base)?; - let gas = base.checked_add(sha_addup)?; - - Some(gas) +pub const fn create2_cost(len: u64) -> Option { + let sha_addup_base = len.div_ceil(32); + let sha_addup = tri!(KECCAK256WORD.checked_mul(sha_addup_base)); + CREATE.checked_add(sha_addup) } #[inline] @@ -85,13 +102,14 @@ fn log2floor(value: U256) -> u64 { l } +/// `EXP` opcode cost calculation. #[inline] -pub fn exp_cost(power: U256) -> Option { +pub fn exp_cost(spec_id: SpecId, power: U256) -> Option { if power == U256::ZERO { Some(EXP) } else { // EIP-160: EXP cost increase - let gas_byte = U256::from(if SPEC::enabled(SPURIOUS_DRAGON) { + let gas_byte = U256::from(if spec_id.is_enabled_in(SpecId::SPURIOUS_DRAGON) { 50 } else { 10 @@ -103,55 +121,61 @@ pub fn exp_cost(power: U256) -> Option { } } +/// `*COPY` opcodes cost calculation. #[inline] -pub fn verylowcopy_cost(len: u64) -> Option { - let wordd = len / 32; - let wordr = len % 32; - VERYLOW.checked_add(COPY.checked_mul(if wordr == 0 { wordd } else { wordd + 1 })?) +pub const fn verylowcopy_cost(len: u64) -> Option { + VERYLOW.checked_add(tri!(cost_per_word(len, COPY))) } +/// `EXTCODECOPY` opcode cost calculation. #[inline] -pub fn extcodecopy_cost(len: u64, is_cold: bool) -> Option { - let wordd = len / 32; - let wordr = len % 32; - - let base_gas: u64 = if SPEC::enabled(BERLIN) { +pub const fn extcodecopy_cost(spec_id: SpecId, len: u64, is_cold: bool) -> Option { + let base_gas = if spec_id.is_enabled_in(SpecId::BERLIN) { if is_cold { COLD_ACCOUNT_ACCESS_COST } else { WARM_STORAGE_READ_COST } - } else if SPEC::enabled(TANGERINE) { + } else if spec_id.is_enabled_in(SpecId::TANGERINE) { 700 } else { 20 }; - base_gas.checked_add(COPY.checked_mul(if wordr == 0 { wordd } else { wordd + 1 })?) + base_gas.checked_add(tri!(cost_per_word(len, COPY))) } -pub fn account_access_gas(is_cold: bool) -> u64 { - if SPEC::enabled(BERLIN) { +/// `BALANCE` opcode cost calculation. +#[inline] +pub const fn account_access_gas(spec_id: SpecId, is_cold: bool) -> u64 { + if spec_id.is_enabled_in(SpecId::BERLIN) { if is_cold { COLD_ACCOUNT_ACCESS_COST } else { WARM_STORAGE_READ_COST } - } else if SPEC::enabled(ISTANBUL) { + } else if spec_id.is_enabled_in(SpecId::ISTANBUL) { 700 } else { 20 } } -pub fn log_cost(n: u8, len: u64) -> Option { - LOG.checked_add(LOGDATA.checked_mul(len)?)? - .checked_add(LOGTOPIC * n as u64) +/// `LOG` opcode cost calculation. +#[inline] +pub const fn log_cost(n: u8, len: u64) -> Option { + tri!(LOG.checked_add(tri!(LOGDATA.checked_mul(len)))).checked_add(LOGTOPIC * n as u64) } -pub fn keccak256_cost(len: u64) -> Option { - let wordd = len / 32; - let wordr = len % 32; - KECCAK256.checked_add(KECCAK256WORD.checked_mul(if wordr == 0 { wordd } else { wordd + 1 })?) +/// `KECCAK256` opcode cost calculation. +#[inline] +pub const fn keccak256_cost(len: u64) -> Option { + KECCAK256.checked_add(tri!(cost_per_word(len, KECCAK256WORD))) +} + +/// Cost for memory length. `ceil(len / 32) * multiple`. +#[inline] +pub const fn cost_per_word(len: u64, multiple: u64) -> Option { + len.div_ceil(32).checked_mul(multiple) } /// EIP-3860: Limit and meter initcode @@ -160,24 +184,23 @@ pub fn keccak256_cost(len: u64) -> Option { /// /// This cannot overflow as the initcode length is assumed to be checked. #[inline] -pub fn initcode_cost(len: u64) -> u64 { - let wordd = len / 32; - let wordr = len % 32; - INITCODE_WORD_COST * if wordr == 0 { wordd } else { wordd + 1 } +pub const fn initcode_cost(len: u64) -> u64 { + opt_unwrap!(cost_per_word(len, INITCODE_WORD_COST)) } +/// `SLOAD` opcode cost calculation. #[inline] -pub fn sload_cost(is_cold: bool) -> u64 { - if SPEC::enabled(BERLIN) { +pub const fn sload_cost(spec_id: SpecId, is_cold: bool) -> u64 { + if spec_id.is_enabled_in(SpecId::BERLIN) { if is_cold { COLD_SLOAD_COST } else { WARM_STORAGE_READ_COST } - } else if SPEC::enabled(ISTANBUL) { + } else if spec_id.is_enabled_in(SpecId::ISTANBUL) { // EIP-1884: Repricing for trie-size-dependent opcodes INSTANBUL_SLOAD_GAS - } else if SPEC::enabled(TANGERINE) { + } else if spec_id.is_enabled_in(SpecId::TANGERINE) { // EIP-150: Gas cost changes for IO-heavy operations 200 } else { @@ -185,8 +208,10 @@ pub fn sload_cost(is_cold: bool) -> u64 { } } -#[allow(clippy::collapsible_else_if)] -pub fn sstore_cost( +/// `SSTORE` opcode cost calculation. +#[inline] +pub fn sstore_cost( + spec_id: SpecId, original: U256, current: U256, new: U256, @@ -194,11 +219,11 @@ pub fn sstore_cost( is_cold: bool, ) -> Option { // EIP-1706 Disable SSTORE with gasleft lower than call stipend - if SPEC::enabled(ISTANBUL) && gas <= CALL_STIPEND { + if spec_id.is_enabled_in(SpecId::ISTANBUL) && gas <= CALL_STIPEND { return None; } - if SPEC::enabled(BERLIN) { + if spec_id.is_enabled_in(SpecId::BERLIN) { // Berlin specification logic let mut gas_cost = istanbul_sstore_cost::( original, current, new, @@ -208,7 +233,7 @@ pub fn sstore_cost( gas_cost += COLD_SLOAD_COST; } Some(gas_cost) - } else if SPEC::enabled(ISTANBUL) { + } else if spec_id.is_enabled_in(SpecId::ISTANBUL) { // Istanbul logic Some(istanbul_sstore_cost::( original, current, new, @@ -220,7 +245,7 @@ pub fn sstore_cost( } /// EIP-2200: Structured Definitions for Net Gas Metering -#[inline(always)] +#[inline] fn istanbul_sstore_cost( original: U256, current: U256, @@ -237,7 +262,8 @@ fn istanbul_sstore_cost( } } -/// Frontier sstore cost just had two cases set and reset values +/// Frontier sstore cost just had two cases set and reset values. +#[inline] fn frontier_sstore_cost(current: U256, new: U256) -> u64 { if current == U256::ZERO && new != U256::ZERO { SSTORE_SET @@ -246,39 +272,48 @@ fn frontier_sstore_cost(current: U256, new: U256) -> u64 { } } -pub fn selfdestruct_cost(res: SelfDestructResult) -> u64 { +/// `SELFDESTRUCT` opcode cost calculation. +#[inline] +pub const fn selfdestruct_cost(spec_id: SpecId, res: SelfDestructResult) -> u64 { // EIP-161: State trie clearing (invariant-preserving alternative) - let should_charge_topup = if SPEC::enabled(SPURIOUS_DRAGON) { + let should_charge_topup = if spec_id.is_enabled_in(SpecId::SPURIOUS_DRAGON) { res.had_value && !res.target_exists } else { !res.target_exists }; // EIP-150: Gas cost changes for IO-heavy operations - let selfdestruct_gas_topup = if SPEC::enabled(TANGERINE) && should_charge_topup { + let selfdestruct_gas_topup = if spec_id.is_enabled_in(SpecId::TANGERINE) && should_charge_topup + { 25000 } else { 0 }; // EIP-150: Gas cost changes for IO-heavy operations - let selfdestruct_gas = if SPEC::enabled(TANGERINE) { 5000 } else { 0 }; + let selfdestruct_gas = if spec_id.is_enabled_in(SpecId::TANGERINE) { + 5000 + } else { + 0 + }; let mut gas = selfdestruct_gas + selfdestruct_gas_topup; - if SPEC::enabled(BERLIN) && res.is_cold { + if spec_id.is_enabled_in(SpecId::BERLIN) && res.is_cold { gas += COLD_ACCOUNT_ACCESS_COST } gas } -pub fn call_gas(is_cold: bool) -> u64 { - if SPEC::enabled(BERLIN) { +/// Basic `CALL` opcode cost calculation, see [`call_cost`]. +#[inline] +pub const fn call_gas(spec_id: SpecId, is_cold: bool) -> u64 { + if spec_id.is_enabled_in(SpecId::BERLIN) { if is_cold { COLD_ACCOUNT_ACCESS_COST } else { WARM_STORAGE_READ_COST } - } else if SPEC::enabled(TANGERINE) { + } else if spec_id.is_enabled_in(SpecId::TANGERINE) { // EIP-150: Gas cost changes for IO-heavy operations 700 } else { @@ -286,33 +321,23 @@ pub fn call_gas(is_cold: bool) -> u64 { } } -pub fn call_cost( +/// `CALL` opcode cost calculation. +#[inline] +pub const fn call_cost( + spec_id: SpecId, transfers_value: bool, is_new: bool, is_cold: bool, is_call_or_callcode: bool, is_call_or_staticcall: bool, ) -> u64 { - call_gas::(is_cold) + call_gas(spec_id, is_cold) + xfer_cost(is_call_or_callcode, transfers_value) - + new_cost::(is_call_or_staticcall, is_new, transfers_value) -} - -#[inline] -pub fn warm_cold_cost(is_cold: bool, regular_value: u64) -> u64 { - if SPEC::enabled(BERLIN) { - if is_cold { - COLD_ACCOUNT_ACCESS_COST - } else { - WARM_STORAGE_READ_COST - } - } else { - regular_value - } + + new_cost(spec_id, is_call_or_staticcall, is_new, transfers_value) } #[inline] -fn xfer_cost(is_call_or_callcode: bool, transfers_value: bool) -> u64 { +const fn xfer_cost(is_call_or_callcode: bool, transfers_value: bool) -> u64 { if is_call_or_callcode && transfers_value { CALLVALUE } else { @@ -321,21 +346,27 @@ fn xfer_cost(is_call_or_callcode: bool, transfers_value: bool) -> u64 { } #[inline] -fn new_cost(is_call_or_staticcall: bool, is_new: bool, transfers_value: bool) -> u64 { +const fn new_cost( + spec_id: SpecId, + is_call_or_staticcall: bool, + is_new: bool, + transfers_value: bool, +) -> u64 { if !is_call_or_staticcall || !is_new { return 0; } // EIP-161: State trie clearing (invariant-preserving alternative) - if SPEC::enabled(SPURIOUS_DRAGON) && !transfers_value { + if spec_id.is_enabled_in(SpecId::SPURIOUS_DRAGON) && !transfers_value { return 0; } NEWACCOUNT } +/// Memory expansion cost calculation. #[inline] -pub fn memory_gas(a: usize) -> u64 { +pub const fn memory_gas(a: usize) -> u64 { let a = a as u64; MEMORY .saturating_mul(a) @@ -344,7 +375,8 @@ pub fn memory_gas(a: usize) -> u64 { /// Initial gas that is deducted for transaction to be included. /// Initial gas contains initial stipend gas, gas for access list and input data. -pub fn validate_initial_tx_gas( +pub fn validate_initial_tx_gas( + spec_id: SpecId, input: &[u8], is_create: bool, access_list: &[(Address, Vec)], @@ -356,10 +388,15 @@ pub fn validate_initial_tx_gas( // initdate stipend initial_gas += zero_data_len * TRANSACTION_ZERO_DATA; // EIP-2028: Transaction data gas cost reduction - initial_gas += non_zero_data_len * if SPEC::enabled(ISTANBUL) { 16 } else { 68 }; + initial_gas += non_zero_data_len + * if spec_id.is_enabled_in(SpecId::ISTANBUL) { + 16 + } else { + 68 + }; // get number of access list account and storages. - if SPEC::enabled(BERLIN) { + if spec_id.is_enabled_in(SpecId::BERLIN) { let accessed_slots = access_list .iter() .fold(0, |slot_count, (_, slots)| slot_count + slots.len() as u64); @@ -369,7 +406,7 @@ pub fn validate_initial_tx_gas( // base stipend initial_gas += if is_create { - if SPEC::enabled(HOMESTEAD) { + if spec_id.is_enabled_in(SpecId::HOMESTEAD) { // EIP-2: Homestead Hard-fork Changes 53000 } else { @@ -381,7 +418,7 @@ pub fn validate_initial_tx_gas( // EIP-3860: Limit and meter initcode // Initcode stipend for bytecode analysis - if SPEC::enabled(SHANGHAI) && is_create { + if spec_id.is_enabled_in(SpecId::SHANGHAI) && is_create { initial_gas += initcode_cost(input.len() as u64) } diff --git a/crates/interpreter/src/instructions/arithmetic.rs b/crates/interpreter/src/instructions/arithmetic.rs index 2d767279..8d1e5127 100644 --- a/crates/interpreter/src/instructions/arithmetic.rs +++ b/crates/interpreter/src/instructions/arithmetic.rs @@ -65,7 +65,7 @@ pub fn mulmod(interpreter: &mut Interpreter, _host: &mut H) { pub fn exp(interpreter: &mut Interpreter, _host: &mut H) { pop_top!(interpreter, op1, op2); - gas_or_fail!(interpreter, gas::exp_cost::(*op2)); + gas_or_fail!(interpreter, gas::exp_cost(SPEC::SPEC_ID, *op2)); *op2 = op1.pow(*op2); } diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index b19d0dfc..cd5d735e 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -23,7 +23,7 @@ pub fn balance(interpreter: &mut Interpreter, host interpreter, if SPEC::enabled(ISTANBUL) { // EIP-1884: Repricing for trie-size-dependent opcodes - gas::account_access_gas::(is_cold) + gas::account_access_gas(SPEC::SPEC_ID, is_cold) } else if SPEC::enabled(TANGERINE) { 400 } else { @@ -105,7 +105,7 @@ pub fn extcodecopy(interpreter: &mut Interpreter, let len = as_usize_or_fail!(interpreter, len_u256); gas_or_fail!( interpreter, - gas::extcodecopy_cost::(len as u64, is_cold) + gas::extcodecopy_cost(SPEC::SPEC_ID, len as u64, is_cold) ); if len == 0 { return; @@ -146,7 +146,7 @@ pub fn sload(interpreter: &mut Interpreter, host: interpreter.instruction_result = InstructionResult::FatalExternalError; return; }; - gas!(interpreter, gas::sload_cost::(is_cold)); + gas!(interpreter, gas::sload_cost(SPEC::SPEC_ID, is_cold)); push!(interpreter, value); } @@ -166,9 +166,12 @@ pub fn sstore(interpreter: &mut Interpreter, host: }; gas_or_fail!(interpreter, { let remaining_gas = interpreter.gas.remaining(); - gas::sstore_cost::(original, old, new, remaining_gas, is_cold) + gas::sstore_cost(SPEC::SPEC_ID, original, old, new, remaining_gas, is_cold) }); - refund!(interpreter, gas::sstore_refund::(original, old, new)); + refund!( + interpreter, + gas::sstore_refund(SPEC::SPEC_ID, original, old, new) + ); } /// EIP-1153: Transient storage opcodes @@ -240,7 +243,7 @@ pub fn selfdestruct(interpreter: &mut Interpreter, if !SPEC::enabled(LONDON) && !res.previously_destroyed { refund!(interpreter, gas::SELFDESTRUCT) } - gas!(interpreter, gas::selfdestruct_cost::(res)); + gas!(interpreter, gas::selfdestruct_cost(SPEC::SPEC_ID, res)); interpreter.instruction_result = InstructionResult::SelfDestruct; } @@ -285,7 +288,7 @@ pub fn create( // EIP-1014: Skinny CREATE2 let scheme = if IS_CREATE2 { pop!(interpreter, salt); - gas_or_fail!(interpreter, gas::create2_cost(len)); + gas_or_fail!(interpreter, gas::create2_cost(len as u64)); CreateScheme::Create2 { salt } } else { gas!(interpreter, gas::CREATE); diff --git a/crates/interpreter/src/instructions/host/call_helpers.rs b/crates/interpreter/src/instructions/host/call_helpers.rs index 05a7a203..803d0e62 100644 --- a/crates/interpreter/src/instructions/host/call_helpers.rs +++ b/crates/interpreter/src/instructions/host/call_helpers.rs @@ -49,7 +49,8 @@ pub fn calc_call_gas( }; let is_new = !exist; - let call_cost = gas::call_cost::( + let call_cost = gas::call_cost( + SPEC::SPEC_ID, has_transfer, is_new, is_cold, diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index 4ee51db7..cc9184ef 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -217,7 +217,7 @@ impl Interpreter { let out_offset = call_outcome.memory_start(); let out_len = call_outcome.memory_length(); - self.return_data_buffer = call_outcome.output().to_owned(); + self.return_data_buffer.clone_from(call_outcome.output()); let target_len = min(out_len, self.return_data_buffer.len()); match call_outcome.instruction_result() { diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index 6d75e25c..c9767028 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -67,15 +67,19 @@ pub enum SpecId { } impl SpecId { + /// Returns the `SpecId` for the given `u8`. #[inline] pub fn try_from_u8(spec_id: u8) -> Option { Self::n(spec_id) } - pub fn is_enabled_in(&self, other: Self) -> bool { - Self::enabled(*self, other) + /// Returns `true` if the given specification ID is enabled in this spec. + #[inline] + pub const fn is_enabled_in(self, other: Self) -> bool { + Self::enabled(self, other) } + /// Returns `true` if the given specification ID is enabled in this spec. #[inline] pub const fn enabled(our: SpecId, other: SpecId) -> bool { our as u8 >= other as u8 diff --git a/crates/revm/src/handler/mainnet/execution.rs b/crates/revm/src/handler/mainnet/execution.rs index dc1514ea..ba79aabe 100644 --- a/crates/revm/src/handler/mainnet/execution.rs +++ b/crates/revm/src/handler/mainnet/execution.rs @@ -4,12 +4,11 @@ use crate::{ return_ok, return_revert, CallInputs, CreateInputs, CreateOutcome, Gas, InstructionResult, SharedMemory, }, - primitives::{EVMError, Env, Spec}, + primitives::{EVMError, Env, Spec, SpecId}, CallFrame, Context, CreateFrame, Frame, FrameOrResult, FrameResult, }; -use std::boxed::Box; - use revm_interpreter::{CallOutcome, InterpreterResult}; +use std::boxed::Box; /// Helper function called inside [`last_frame_return`] #[inline] @@ -44,7 +43,7 @@ pub fn frame_return_with_refund_flag( // gas spend. (Before london it was 2th part of gas spend) if refund_enabled { // EIP-3529: Reduction in refunds - gas.set_final_refund::(); + gas.set_final_refund(SPEC::SPEC_ID.is_enabled_in(SpecId::LONDON)); } } @@ -139,10 +138,9 @@ pub fn insert_create_outcome( #[cfg(test)] mod tests { - use revm_interpreter::{primitives::CancunSpec, InterpreterResult}; - use revm_precompile::Bytes; - use super::*; + use revm_interpreter::primitives::CancunSpec; + use revm_precompile::Bytes; /// Creates frame result. fn call_last_frame_return(instruction_result: InstructionResult, gas: Gas) -> Gas { diff --git a/crates/revm/src/handler/mainnet/validation.rs b/crates/revm/src/handler/mainnet/validation.rs index 29c441f1..176e0e82 100644 --- a/crates/revm/src/handler/mainnet/validation.rs +++ b/crates/revm/src/handler/mainnet/validation.rs @@ -43,7 +43,8 @@ pub fn validate_initial_tx_gas( let is_create = env.tx.transact_to.is_create(); let access_list = &env.tx.access_list; - let initial_gas_spend = gas::validate_initial_tx_gas::(input, is_create, access_list); + let initial_gas_spend = + gas::validate_initial_tx_gas(SPEC::SPEC_ID, input, is_create, access_list); // Additional check to see if limit is big enough to cover initial gas. if initial_gas_spend > env.tx.gas_limit { diff --git a/crates/revm/src/optimism/handler_register.rs b/crates/revm/src/optimism/handler_register.rs index fe6ee94c..600d6709 100644 --- a/crates/revm/src/optimism/handler_register.rs +++ b/crates/revm/src/optimism/handler_register.rs @@ -133,7 +133,7 @@ pub fn last_frame_return( // Prior to Regolith, deposit transactions did not receive gas refunds. let is_gas_refund_disabled = env.cfg.is_gas_refund_disabled() || (is_deposit && !is_regolith); if !is_gas_refund_disabled { - gas.set_final_refund::(); + gas.set_final_refund(SPEC::SPEC_ID.is_enabled_in(SpecId::LONDON)); } Ok(()) } From 4d64bbcd241540f90f3a6ab2285b6fe6f8febb1f Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Fri, 5 Apr 2024 16:00:03 +0200 Subject: [PATCH 005/105] feat(interpreter): derive Eq for InterpreterAction (#1262) --- crates/interpreter/src/interpreter.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index cc9184ef..4da1b58d 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -52,7 +52,7 @@ pub struct Interpreter { } /// The result of an interpreter operation. -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct InterpreterResult { /// The result of the instruction execution. pub result: InstructionResult, @@ -62,7 +62,7 @@ pub struct InterpreterResult { pub gas: Gas, } -#[derive(Debug, Default, Clone)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] pub enum InterpreterAction { /// CALL, CALLCODE, DELEGATECALL or STATICCALL instruction called. Call { From 5e730a6fad39be2b60f5160664fc32f9f04751bf Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Fri, 5 Apr 2024 23:29:32 +0200 Subject: [PATCH 006/105] chore: add and use EvmContext::take_error (#1264) --- crates/revm/src/context/inner_evm_context.rs | 5 +++++ crates/revm/src/evm.rs | 2 +- crates/revm/src/handler/mainnet/execution.rs | 4 ++-- crates/revm/src/handler/mainnet/post_execution.rs | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/crates/revm/src/context/inner_evm_context.rs b/crates/revm/src/context/inner_evm_context.rs index 98a4d567..16ffe8a2 100644 --- a/crates/revm/src/context/inner_evm_context.rs +++ b/crates/revm/src/context/inner_evm_context.rs @@ -113,6 +113,11 @@ impl InnerEvmContext { &mut self.env } + /// Returns the error by replacing it with `Ok(())`, if any. + pub fn take_error(&mut self) -> Result<(), EVMError> { + core::mem::replace(&mut self.error, Ok(())) + } + /// Fetch block hash from database. #[inline] pub fn block_hash(&mut self, number: U256) -> Result> { diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index 76bf4b63..239aa64e 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -266,7 +266,7 @@ impl Evm<'_, EXT, DB> { // take error and break the loop if there is any. // This error is set From Interpreter when it's interacting with Host. - core::mem::replace(&mut self.context.evm.error, Ok(()))?; + self.context.evm.take_error()?; // take shared memory back. shared_memory = interpreter.take_memory(); diff --git a/crates/revm/src/handler/mainnet/execution.rs b/crates/revm/src/handler/mainnet/execution.rs index ba79aabe..f5c0eb29 100644 --- a/crates/revm/src/handler/mainnet/execution.rs +++ b/crates/revm/src/handler/mainnet/execution.rs @@ -88,7 +88,7 @@ pub fn insert_call_outcome( shared_memory: &mut SharedMemory, outcome: CallOutcome, ) -> Result<(), EVMError> { - core::mem::replace(&mut context.evm.error, Ok(()))?; + context.evm.take_error()?; frame .frame_data_mut() .interpreter @@ -128,7 +128,7 @@ pub fn insert_create_outcome( frame: &mut Frame, outcome: CreateOutcome, ) -> Result<(), EVMError> { - core::mem::replace(&mut context.evm.error, Ok(()))?; + context.evm.take_error()?; frame .frame_data_mut() .interpreter diff --git a/crates/revm/src/handler/mainnet/post_execution.rs b/crates/revm/src/handler/mainnet/post_execution.rs index a0b81a0d..6230b882 100644 --- a/crates/revm/src/handler/mainnet/post_execution.rs +++ b/crates/revm/src/handler/mainnet/post_execution.rs @@ -76,7 +76,7 @@ pub fn output( context: &mut Context, result: FrameResult, ) -> Result> { - core::mem::replace(&mut context.evm.error, Ok(()))?; + context.evm.take_error()?; // used gas with refund calculated. let gas_refunded = result.gas().refunded() as u64; let final_gas_used = result.gas().spent() - gas_refunded; From af5665176271c87c9ff0600f6d8432d117012345 Mon Sep 17 00:00:00 2001 From: evalir Date: Fri, 5 Apr 2024 23:29:56 +0200 Subject: [PATCH 007/105] feat(`db`): Introduce `alloydb` (#1257) * feat: alloydb * chore: turn on needed deps for test * derive * correct address * chore: remove arc * feat: actually make Transport and Network generic to accept any transport or network * chore: condense markers into one, more idiomatic --- Cargo.lock | 627 +++++++++++++++++++++++++++++++++- crates/revm/Cargo.toml | 17 + crates/revm/src/db.rs | 4 + crates/revm/src/db/alloydb.rs | 180 ++++++++++ 4 files changed, 812 insertions(+), 16 deletions(-) create mode 100644 crates/revm/src/db/alloydb.rs diff --git a/Cargo.lock b/Cargo.lock index 50451980..88b5b1e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,6 +44,70 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +[[package]] +name = "alloy-consensus" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-eips", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "serde", + "sha2", +] + +[[package]] +name = "alloy-eips" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "c-kzg", + "once_cell", + "serde", +] + +[[package]] +name = "alloy-genesis" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-primitives", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-json-rpc" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-primitives", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "alloy-network" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-json-rpc", + "alloy-primitives", + "alloy-rpc-types", + "alloy-signer", + "async-trait", + "futures-utils-wasm", + "serde", + "thiserror", +] + [[package]] name = "alloy-primitives" version = "0.7.0" @@ -70,6 +134,32 @@ dependencies = [ "tiny-keccak", ] +[[package]] +name = "alloy-provider" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-json-rpc", + "alloy-network", + "alloy-primitives", + "alloy-rpc-client", + "alloy-rpc-types", + "alloy-rpc-types-trace", + "alloy-transport", + "alloy-transport-http", + "async-stream", + "async-trait", + "auto_impl", + "dashmap", + "futures", + "lru", + "reqwest 0.12.2", + "serde_json", + "tokio", + "tracing", + "url", +] + [[package]] name = "alloy-rlp" version = "0.3.4" @@ -92,6 +182,79 @@ dependencies = [ "syn 2.0.55", ] +[[package]] +name = "alloy-rpc-client" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-json-rpc", + "alloy-transport", + "alloy-transport-http", + "futures", + "pin-project", + "reqwest 0.12.2", + "serde", + "serde_json", + "tokio", + "tokio-stream", + "tower", + "tracing", + "url", +] + +[[package]] +name = "alloy-rpc-types" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-genesis", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "alloy-sol-types", + "itertools 0.12.1", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "alloy-rpc-types-trace" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-primitives", + "alloy-rpc-types", + "alloy-serde", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-serde" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-primitives", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-signer" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-primitives", + "async-trait", + "auto_impl", + "elliptic-curve", + "k256", + "thiserror", +] + [[package]] name = "alloy-sol-macro" version = "0.7.0" @@ -137,6 +300,37 @@ dependencies = [ "serde", ] +[[package]] +name = "alloy-transport" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-json-rpc", + "base64 0.22.0", + "futures-util", + "futures-utils-wasm", + "serde", + "serde_json", + "thiserror", + "tokio", + "tower", + "url", + "wasm-bindgen-futures", +] + +[[package]] +name = "alloy-transport-http" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +dependencies = [ + "alloy-json-rpc", + "alloy-transport", + "reqwest 0.12.2", + "serde_json", + "tower", + "url", +] + [[package]] name = "anes" version = "0.1.6" @@ -200,7 +394,7 @@ dependencies = [ "ark-std 0.4.0", "derivative", "digest 0.10.7", - "itertools", + "itertools 0.10.5", "num-bigint", "num-traits", "paste", @@ -300,6 +494,28 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + [[package]] name = "async-trait" version = "0.1.79" @@ -393,6 +609,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" + [[package]] name = "base64ct" version = "1.6.0" @@ -674,7 +896,7 @@ dependencies = [ "clap 4.5.3", "criterion-plot", "is-terminal", - "itertools", + "itertools 0.10.5", "num-traits", "once_cell", "oorandom", @@ -695,7 +917,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", - "itertools", + "itertools 0.10.5", ] [[package]] @@ -751,6 +973,19 @@ dependencies = [ "typenum", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "data-encoding" version = "2.5.0" @@ -998,7 +1233,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e61ffea29f26e8249d35128a82ec8d3bd4fbc80179ea5f5e5e3daafef6a80fcb" dependencies = [ "ethereum-types", - "itertools", + "itertools 0.10.5", "smallvec", ] @@ -1063,12 +1298,12 @@ dependencies = [ "futures-timer", "futures-util", "hashers", - "http", + "http 0.2.12", "instant", "jsonwebtoken", "once_cell", "pin-project", - "reqwest", + "reqwest 0.11.27", "serde", "serde_json", "thiserror", @@ -1139,6 +1374,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1253,6 +1503,12 @@ dependencies = [ "slab", ] +[[package]] +name = "futures-utils-wasm" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9" + [[package]] name = "fxhash" version = "0.2.1" @@ -1330,7 +1586,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.12", "indexmap", "slab", "tokio", @@ -1445,6 +1701,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -1452,7 +1719,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +dependencies = [ + "bytes", + "futures-core", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -1479,8 +1769,8 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -1492,6 +1782,25 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-rustls" version = "0.24.2" @@ -1499,13 +1808,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", - "hyper", + "http 0.2.12", + "hyper 0.14.28", "rustls", "tokio", "tokio-rustls", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.2.0", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.2.0", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", +] + [[package]] name = "idna" version = "0.5.0" @@ -1618,6 +1963,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.10" @@ -1707,12 +2061,31 @@ version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +[[package]] +name = "lru" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" +dependencies = [ + "hashbrown", +] + [[package]] name = "memchr" version = "2.7.1" @@ -1751,6 +2124,24 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "num" version = "0.4.1" @@ -1916,6 +2307,50 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parity-scale-codec" version = "3.6.9" @@ -1942,6 +2377,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + [[package]] name = "paste" version = "1.0.14" @@ -2026,6 +2474,12 @@ dependencies = [ "spki", ] +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + [[package]] name = "plain_hasher" version = "0.2.3" @@ -2267,6 +2721,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "regex" version = "1.10.4" @@ -2308,9 +2771,9 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", - "hyper", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.28", "hyper-rustls", "ipnet", "js-sys", @@ -2337,10 +2800,53 @@ dependencies = [ "winreg", ] +[[package]] +name = "reqwest" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d66674f2b6fb864665eea7a3c1ac4e3dfacd2fda83cf6f935a612e01b0e3338" +dependencies = [ + "base64 0.21.7", + "bytes", + "futures-core", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "hyper 1.2.0", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + [[package]] name = "revm" version = "8.0.0" dependencies = [ + "alloy-provider", + "alloy-rpc-types", + "alloy-transport", + "alloy-transport-http", "anyhow", "auto_impl", "cfg-if", @@ -2669,6 +3175,21 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "sct" version = "0.7.1" @@ -2712,6 +3233,29 @@ dependencies = [ "cc", ] +[[package]] +name = "security-framework" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "0.11.0" @@ -3190,6 +3734,16 @@ dependencies = [ "syn 2.0.55", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.24.1" @@ -3200,6 +3754,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + [[package]] name = "tokio-tungstenite" version = "0.20.1" @@ -3268,6 +3834,28 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -3280,6 +3868,7 @@ version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -3340,7 +3929,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 0.2.12", "httparse", "log", "rand", @@ -3456,6 +4045,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "vec_map" version = "0.8.2" diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 856bc892..73c7c34f 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -40,12 +40,21 @@ tokio = { version = "1.37", features = [ ethers-providers = { version = "2.0", optional = true } ethers-core = { version = "2.0", optional = true } +# alloydb +alloy-provider = { git = "https://github.com/alloy-rs/alloy.git", optional = true, default-features = false } +alloy-rpc-types = {git = "https://github.com/alloy-rs/alloy.git", optional = true, default-features = false } +alloy-transport = {git = "https://github.com/alloy-rs/alloy.git", optional = true, default-features = false } + [dev-dependencies] ethers-contract = { version = "2.0.14", default-features = false } anyhow = "1.0.81" criterion = "0.5" indicatif = "0.17" +alloy-provider = { git = "https://github.com/alloy-rs/alloy.git", default-features = false, features = ["reqwest"] } +# needed for enabling TLS to use HTTPS connections when testing alloy DB +alloy-transport-http = { git = "https://github.com/alloy-rs/alloy.git" } + [features] default = ["std", "c-kzg", "secp256k1", "portable"] std = [ @@ -82,6 +91,14 @@ ethersdb = [ "ethers-core", ] # Negate optimism default handler +alloydb = [ + "std", + "tokio", + "alloy-provider", + "alloy-rpc-types", + "alloy-transport", +] + dev = [ "memory_limit", "optional_balance_check", diff --git a/crates/revm/src/db.rs b/crates/revm/src/db.rs index f8913580..bcb3aa46 100644 --- a/crates/revm/src/db.rs +++ b/crates/revm/src/db.rs @@ -1,5 +1,7 @@ //! [Database] implementations. +#[cfg(feature = "alloydb")] +pub mod alloydb; pub mod emptydb; #[cfg(feature = "ethersdb")] pub mod ethersdb; @@ -7,6 +9,8 @@ pub mod in_memory_db; pub mod states; pub use crate::primitives::db::*; +#[cfg(feature = "alloydb")] +pub use alloydb::AlloyDB; pub use emptydb::{EmptyDB, EmptyDBTyped}; #[cfg(feature = "ethersdb")] pub use ethersdb::EthersDB; diff --git a/crates/revm/src/db/alloydb.rs b/crates/revm/src/db/alloydb.rs new file mode 100644 index 00000000..a9541991 --- /dev/null +++ b/crates/revm/src/db/alloydb.rs @@ -0,0 +1,180 @@ +use crate::{ + db::{Database, DatabaseRef}, + primitives::{AccountInfo, Address, Bytecode, B256, KECCAK_EMPTY, U256}, +}; +use alloy_provider::{Network, Provider}; +use alloy_rpc_types::BlockId; +use alloy_transport::{Transport, TransportError}; +use tokio::runtime::{Builder, Handle}; + +/// An alloy-powered REVM [Database]. +/// +/// When accessing the database, it'll use the given provider to fetch the corresponding account's data. +#[derive(Debug, Clone)] +pub struct AlloyDB> { + /// The provider to fetch the data from. + provider: P, + /// The block number on which the queries will be based on. + block_number: Option, + _marker: std::marker::PhantomData (T, N)>, +} + +impl> AlloyDB { + /// Create a new AlloyDB instance, with a [Provider] and a block (Use None for latest). + pub fn new(provider: P, block_number: Option) -> Self { + Self { + provider, + block_number, + _marker: std::marker::PhantomData, + } + } + + /// Internal utility function that allows us to block on a future regardless of the runtime flavor. + #[inline] + fn block_on(f: F) -> F::Output + where + F: std::future::Future + Send, + F::Output: Send, + { + match Handle::try_current() { + Ok(handle) => match handle.runtime_flavor() { + // This is essentially equal to tokio::task::spawn_blocking because tokio doesn't + // allow the current_thread runtime to block_in_place. + // See for more info. + tokio::runtime::RuntimeFlavor::CurrentThread => std::thread::scope(move |s| { + s.spawn(move || { + Builder::new_current_thread() + .enable_all() + .build() + .unwrap() + .block_on(f) + }) + .join() + .unwrap() + }), + _ => tokio::task::block_in_place(move || handle.block_on(f)), + }, + Err(_) => Builder::new_current_thread() + .enable_all() + .build() + .unwrap() + .block_on(f), + } + } + + /// Set the block number on which the queries will be based on. + pub fn set_block_number(&mut self, block_number: Option) { + self.block_number = block_number; + } +} + +impl> DatabaseRef for AlloyDB { + type Error = TransportError; + + fn basic_ref(&self, address: Address) -> Result, Self::Error> { + let f = async { + let nonce = self + .provider + .get_transaction_count(address, self.block_number); + let balance = self.provider.get_balance(address, self.block_number); + let code = self + .provider + .get_code_at(address, self.block_number.unwrap_or_default()); + tokio::join!(nonce, balance, code) + }; + + let (nonce, balance, code) = Self::block_on(f); + + let balance = balance?; + let code = Bytecode::new_raw(code?.0.into()); + let code_hash = code.hash_slow(); + let nonce = nonce?; + + Ok(Some(AccountInfo::new( + balance, + nonce.to::(), + code_hash, + code, + ))) + } + + fn block_hash_ref(&self, number: U256) -> Result { + // Saturate usize + if number > U256::from(u64::MAX) { + return Ok(KECCAK_EMPTY); + } + + let block = Self::block_on( + self.provider + // SAFETY: We know number <= u64::MAX, so we can safely convert it to u64 + .get_block_by_number(number.to::().into(), false), + )?; + // SAFETY: If the number is given, the block is supposed to be finalized, so unwrapping is safe. + Ok(B256::new(*block.unwrap().header.hash.unwrap())) + } + + fn code_by_hash_ref(&self, _code_hash: B256) -> Result { + panic!("This should not be called, as the code is already loaded"); + // This is not needed, as the code is already loaded with basic_ref + } + + fn storage_ref(&self, address: Address, index: U256) -> Result { + let slot_val = Self::block_on(self.provider.get_storage_at( + address, + index, + self.block_number, + ))?; + Ok(slot_val) + } +} + +impl> Database for AlloyDB { + type Error = TransportError; + + #[inline] + fn basic(&mut self, address: Address) -> Result, Self::Error> { + ::basic_ref(self, address) + } + + #[inline] + fn code_by_hash(&mut self, code_hash: B256) -> Result { + ::code_by_hash_ref(self, code_hash) + } + + #[inline] + fn storage(&mut self, address: Address, index: U256) -> Result { + ::storage_ref(self, address, index) + } + + #[inline] + fn block_hash(&mut self, number: U256) -> Result { + ::block_hash_ref(self, number) + } +} + +#[cfg(test)] +mod tests { + use alloy_provider::ProviderBuilder; + + use super::*; + + #[test] + fn can_get_basic() { + let client = ProviderBuilder::new() + .on_reqwest_http( + "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27" + .parse() + .unwrap(), + ) + .unwrap(); + let alloydb = AlloyDB::new(client, Some(BlockId::from(16148323))); + + // ETH/USDT pair on Uniswap V2 + let address: Address = "0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852" + .parse() + .unwrap(); + + let acc_info = alloydb.basic_ref(address).unwrap().unwrap(); + assert!(acc_info.exists()); + } +} From eee05416a748d31ad191747cd26c5227e9cbbf6f Mon Sep 17 00:00:00 2001 From: Akash S M Date: Sat, 6 Apr 2024 23:48:52 +0530 Subject: [PATCH 008/105] minor typo fix in docs (#1266) * fix typo * fix typo --- documentation/src/crates/revm/handler.md | 2 +- documentation/src/crates/revm/state.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/src/crates/revm/handler.md b/documentation/src/crates/revm/handler.md index 7980f087..5e9c14fb 100644 --- a/documentation/src/crates/revm/handler.md +++ b/documentation/src/crates/revm/handler.md @@ -33,7 +33,7 @@ They are called in the following order: * `validate_env`: Verifies if all data is set in `Environment` and if valid, for example if `gas_limit` is smaller than block `gas_limit`. * `validate_initial_tx_gas`: - Calculates initial gas needed for the transaction to be executed and checks if it is less them the transaction gas_limit. + Calculates initial gas needed for the transaction to be executed and checks if it is less than the transaction gas_limit. Note that this does not touch the `Database` or state. * `validate_tx_against_state`: Loads the caller account and checks their information. diff --git a/documentation/src/crates/revm/state.md b/documentation/src/crates/revm/state.md index ebeafb20..5951f3cd 100644 --- a/documentation/src/crates/revm/state.md +++ b/documentation/src/crates/revm/state.md @@ -14,7 +14,7 @@ You can implement the traits `Database`, `DatabaseRef` or `Database + DatabaseCo - `DatabaseRef`: Takes a reference on the object. It is useful if you only have a reference on the state and don't want to update anything on it. - It enables `previerify_transaction`, `transact_preverified_ref`, `transact_ref` and `inspect_ref` functions. + It enables `preverify_transaction`, `transact_preverified_ref`, `transact_ref` and `inspect_ref` functions. - `Database + DatabaseCommit`: Allows directly committing changes of a transaction. It enables `transact_commit` and `inspect_commit` functions. From d3db49d66b81241b2e73e478dfd9a654823a0611 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 7 Apr 2024 06:01:08 +0200 Subject: [PATCH 009/105] chore(ci): use more stable rust toolchain plugin (#1269) --- .github/workflows/cachegrind.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/cachegrind.yml b/.github/workflows/cachegrind.yml index ed1d42fa..1e21cc7a 100644 --- a/.github/workflows/cachegrind.yml +++ b/.github/workflows/cachegrind.yml @@ -14,9 +14,7 @@ jobs: uses: actions/checkout@v2 - name: Setup | Rust - uses: ATiltedTree/setup-rust@v1 - with: - rust-version: stable + uses: dtolnay/rust-toolchain@stable - name: Install Valgrind run: | From c96188723e95299055c6a327ce61ac74a7e530d6 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 7 Apr 2024 15:28:34 +0200 Subject: [PATCH 010/105] chore: revert snailtracer without microbench (#1259) * check without microbench * cleanup --- bins/revm-test/src/bin/snailtracer.rs | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/bins/revm-test/src/bin/snailtracer.rs b/bins/revm-test/src/bin/snailtracer.rs index 94f3a6c9..7d1e217b 100644 --- a/bins/revm-test/src/bin/snailtracer.rs +++ b/bins/revm-test/src/bin/snailtracer.rs @@ -1,5 +1,3 @@ -use std::time::Duration; - use revm::{ db::BenchmarkDB, interpreter::analysis::to_analysed, @@ -21,22 +19,14 @@ pub fn simple_example() { }) .build(); - // Microbenchmark - let bench_options = microbench::Options::default().time(Duration::from_secs(2)); - - microbench::bench( - &bench_options, - "Snailtracer Host+Interpreter benchmark", - || { - let _ = evm.transact(); - }, - ); + let _ = evm.transact(); } fn main() { - //println!("Running snailtracer bench!"); + println!("Running snailtracer example!"); + let start = std::time::Instant::now(); simple_example(); - //println!("end!"); + println!("elapsed: {:?}", start.elapsed()); } static CONTRACT_DATA : Bytes = bytes!("608060405234801561001057600080fd5b506004361061004c5760003560e01c806330627b7c1461005157806375ac892a14610085578063784f13661461011d578063c294360114610146575b600080fd5b610059610163565b604080516001600160f81b03199485168152928416602084015292168183015290519081900360600190f35b6100a86004803603604081101561009b57600080fd5b50803590602001356102d1565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100e25781810151838201526020016100ca565b50505050905090810190601f16801561010f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6100596004803603606081101561013357600080fd5b508035906020810135906040013561055b565b6100a86004803603602081101561015c57600080fd5b5035610590565b6000806000610176610400610300610834565b60405180606001604052806001546000546207d5dc028161019357fe5b058152600060208083018290526040928301919091528251600b81905583820151600c81905593830151600d819055835160608082018652928152808401959095528484015282519081018352600654815260075491810191909152600854918101919091526102259161021c916102139161020e91612ef7565b612f64565b6207d5dc612feb565b620f424061301e565b8051600e556020810151600f55604001516010556102416142dd565b61025a816102556102006101806008613064565b613212565b90506102708161025561014561021c6008613064565b905061028481610255610258806008613064565b905061029a8161025561020a61020c6008613064565b90506102a781600461301e565b90506102b1613250565b8051602082015160409092015160f891821b9692821b9550901b92509050565b606060005b6000548112156104c95760006102ed828686613064565b90506002816000015160f81b90808054603f811680603e811461032a576002830184556001831661031c578192505b600160028404019350610342565b600084815260209081902060ff198516905560419094555b505050600190038154600116156103685790600052602060002090602091828204019190065b909190919091601f036101000a81548160ff02191690600160f81b840402179055506002816020015160f81b90808054603f811680603e81146103c557600283018455600183166103b7578192505b6001600284040193506103dd565b600084815260209081902060ff198516905560419094555b505050600190038154600116156104035790600052602060002090602091828204019190065b909190919091601f036101000a81548160ff02191690600160f81b840402179055506002816040015160f81b90808054603f811680603e81146104605760028301845560018316610452578192505b600160028404019350610478565b600084815260209081902060ff198516905560419094555b5050506001900381546001161561049e5790600052602060002090602091828204019190065b815460ff601f929092036101000a9182021916600160f81b90930402919091179055506001016102d6565b506002805460408051602060018416156101000260001901909316849004601f8101849004840282018401909252818152929183018282801561054d5780601f106105225761010080835404028352916020019161054d565b820191906000526020600020905b81548152906001019060200180831161053057829003601f168201915b505050505090505b92915050565b60008060008061056c878787613064565b8051602082015160409092015160f891821b9a92821b9950901b9650945050505050565b600154606090600019015b600081126107a35760005b6000548112156107995760006105bd828487613064565b90506002816000015160f81b90808054603f811680603e81146105fa57600283018455600183166105ec578192505b600160028404019350610612565b600084815260209081902060ff198516905560419094555b505050600190038154600116156106385790600052602060002090602091828204019190065b909190919091601f036101000a81548160ff02191690600160f81b840402179055506002816020015160f81b90808054603f811680603e81146106955760028301845560018316610687578192505b6001600284040193506106ad565b600084815260209081902060ff198516905560419094555b505050600190038154600116156106d35790600052602060002090602091828204019190065b909190919091601f036101000a81548160ff02191690600160f81b840402179055506002816040015160f81b90808054603f811680603e81146107305760028301845560018316610722578192505b600160028404019350610748565b600084815260209081902060ff198516905560419094555b5050506001900381546001161561076e5790600052602060002090602091828204019190065b815460ff601f929092036101000a9182021916600160f81b90930402919091179055506001016105a6565b506000190161059b565b506002805460408051602060018416156101000260001901909316849004601f810184900484028201840190925281815292918301828280156108275780601f106107fc57610100808354040283529160200191610827565b820191906000526020600020905b81548152906001019060200180831161080a57829003601f168201915b505050505090505b919050565b8160008190555080600181905550604051806080016040528060405180606001604052806302faf08081526020016303197500815260200163119e7f8081525081526020016108a460405180606001604052806000815260200161a673198152602001620f423f19815250612f64565b815260006020808301829052604092830182905283518051600355808201516004558301516005558381015180516006559081015160075582015160085582820151600955606092830151600a805460ff1916911515919091179055815192830190915260015490548291906207d5dc028161091c57fe5b058152600060208083018290526040928301919091528251600b81905583820151600c81905593830151600d819055835160608082018652928152808401959095528484015282519081018352600654815260075491810191909152600854918101919091526109979161021c916102139161020e91612ef7565b8051600e55602080820151600f55604091820151601055815160a08101835264174876e8008152825160608082018552641748862a40825263026e8f00828501526304dd1e008286015282840191825284518082018652600080825281860181905281870181905284870191825286518084018852620b71b081526203d09081880181905281890152928501928352608085018181526011805460018082018355919093528651600b9093027f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c688101938455955180517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c69880155808901517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6a8801558901517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6b870155925180517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6c870155808801517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6d8701558801517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6e860155925180517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6f860155958601517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c7085015594909501517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c71830155517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c72909101805492949192909160ff1990911690836002811115610c1057fe5b0217905550505060116040518060a0016040528064174876e8008152602001604051806060016040528064174290493f19815260200163026e8f0081526020016304dd1e008152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806203d09081526020016203d0908152602001620b71b0815250815260200160006002811115610cb657fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff1990921691908490811115610d5857fe5b0217905550505060116040518060a0016040528064174876e800815260200160405180606001604052806302faf080815260200163026e8f00815260200164174876e800815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620b71b08152602001620b71b08152602001620b71b0815250815260200160006002811115610dfd57fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff1990921691908490811115610e9f57fe5b0217905550505060116040518060a0016040528064174876e800815260200160405180606001604052806302faf080815260200163026e8f00815260200164173e54e97f1981525081526020016040518060600160405280600081526020016000815260200160008152508152602001604051806060016040528060008152602001600081526020016000815250815260200160006002811115610f3f57fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff1990921691908490811115610fe157fe5b0217905550505060116040518060a0016040528064174876e800815260200160405180606001604052806302faf080815260200164174876e80081526020016304dd1e00815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620b71b08152602001620b71b08152602001620b71b081525081526020016000600281111561108657fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff199092169190849081111561112857fe5b0217905550505060116040518060a0016040528064174876e800815260200160405180606001604052806302faf080815260200164174399c9ff1981526020016304dd1e00815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620b71b08152602001620b71b08152602001620b71b08152508152602001600060028111156111ce57fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff199092169190849081111561127057fe5b0217905550505060116040518060a0016040528062fbc5208152602001604051806060016040528063019bfcc0815260200162fbc52081526020016302cd29c0815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561131157fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff19909216919084908111156113b357fe5b0217905550505060116040518060a001604052806323c34600815260200160405180606001604052806302faf080815260200163289c455081526020016304dd1e008152508152602001604051806060016040528062b71b00815260200162b71b00815260200162b71b00815250815260200160405180606001604052806000815260200160008152602001600081525081526020016000600281111561145657fe5b905281546001818101845560009384526020938490208351600b90930201918255838301518051838301558085015160028085019190915560409182015160038501558185015180516004860155808701516005860155820151600685015560608501518051600786015595860151600885015594015160098301556080830151600a83018054949593949193909260ff19909216919084908111156114f857fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f208152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016305a1f4a081525081526020016040518060600160405280630459e44081526020016302f34f6081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561160c57fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff19909216919084908111156116fd57fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f20815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001600081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016305a1f4a08152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561180e57fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff19909216919084908111156118ff57fe5b0217905550505060126040518060e001604052806040518060600160405280630555a9608152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e44081526020016302f34f6081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016305a1f4a08152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115611a1357fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff1990921691908490811115611b0457fe5b0217905550505060126040518060e001604052806040518060600160405280630555a960815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016305a1f4a081525081526020016040518060600160405280630459e4408152602001600081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115611c1557fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff1990921691908490811115611d0657fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f208152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e44081526020016302f34f6081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016303aa6a608152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115611e1a57fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff1990921691908490811115611f0b57fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f20815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016303aa6a6081525081526020016040518060600160405280630459e4408152602001600081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561201c57fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff199092169190849081111561210d57fe5b0217905550505060126040518060e001604052806040518060600160405280630555a9608152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016303aa6a6081525081526020016040518060600160405280630459e44081526020016302f34f6081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561222157fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff199092169190849081111561231257fe5b0217905550505060126040518060e001604052806040518060600160405280630555a960815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001600081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016303aa6a608152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561242357fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff199092169190849081111561251457fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f208152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016303aa6a6081525081526020016040518060600160405280630555a9608152602001630188c2e081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561262857fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff199092169190849081111561271957fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f208152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630555a9608152602001630188c2e081526020016304a62f8081525081526020016040518060600160405280630459e4408152602001630188c2e081526020016305a1f4a08152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e5881525081526020016001600281111561282d57fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff199092169190849081111561291e57fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f20815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630555a960815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016303aa6a608152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115612a3257fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff1990921691908490811115612b2357fe5b0217905550505060126040518060e00160405280604051806060016040528063035e1f20815260200163016a8c8081526020016304a62f8081525081526020016040518060600160405280630459e440815260200163016a8c8081526020016305a1f4a081525081526020016040518060600160405280630555a960815260200163016a8c8081526020016304a62f808152508152602001604051806060016040528060008152602001600081526020016000815250815260200160405180606001604052806000815260200160008152602001600081525081526020016040518060600160405280620f3e588152602001620f3e588152602001620f3e58815250815260200160016002811115612c3757fe5b905281546001818101845560009384526020938490208351805160139094029091019283558085015183830155604090810151600280850191909155858501518051600386015580870151600486015582015160058501558185015180516006860155808701516007860155820151600885015560608501518051600986015580870151600a860155820151600b85015560808501518051600c86015580870151600d860155820151600e85015560a08501518051600f860155958601516010850155940151601183015560c0830151601283018054949593949193909260ff1990921691908490811115612d2857fe5b0217905550505060005b601254811015612ef257600060128281548110612d4b57fe5b600091825260209182902060408051610140810182526013909302909101805460e08401908152600182015461010085015260028083015461012086015290845282516060818101855260038401548252600484015482880152600584015482860152858701919091528351808201855260068401548152600784015481880152600884015481860152858501528351808201855260098401548152600a84015481880152600b840154818601528186015283518082018552600c8401548152600d84015481880152600e84015481860152608086015283519081018452600f830154815260108301549581019590955260118201549285019290925260a0830193909352601283015491929160c084019160ff90911690811115612e6c57fe5b6002811115612e7757fe5b815250509050612eac61020e612e95836020015184600001516132cd565b612ea7846040015185600001516132cd565b612ef7565b60128381548110612eb957fe5b60009182526020918290208351600960139093029091019182015590820151600a820155604090910151600b9091015550600101612d32565b505050565b612eff6142dd565b604051806060016040528083602001518560400151028460400151866020015102038152602001836040015185600001510284600001518660400151020381526020018360000151856020015102846020015186600001510203815250905092915050565b612f6c6142dd565b604082015160208301518351600092612f9292918002918002919091019080020161330c565b90506040518060600160405280828560000151620f42400281612fb157fe5b058152602001828560200151620f42400281612fc957fe5b058152602001828560400151620f42400281612fe157fe5b0590529392505050565b612ff36142dd565b5060408051606081018252835183028152602080850151840290820152928101519091029082015290565b6130266142dd565b60405180606001604052808385600001518161303e57fe5b0581526020018385602001518161305157fe5b05815260200183856040015181612fe157fe5b61306c6142dd565b6000546013805463ffffffff1916918502860163ffffffff169190911790556130936142dd565b905060005b828112156131f157600061317261314c61021c613115600b60405180606001604052908160008201548152602001600182015481526020016002820154815250506207a1206000546207a1206130ec613343565b63ffffffff16816130f957fe5b0663ffffffff168d620f424002018161310e57fe5b0503612feb565b60408051606081018252600e548152600f5460208201526010549181019190915260015461025591906207a12090816130ec613343565b604080516060810182526006548152600754602082015260085491810191909152613212565b6040805160e081019091526003546080820190815260045460a083015260055460c083015291925060009181906131ae9061025586608c612feb565b81526020016131bc84612f64565b815260006020820181905260409091015290506131e5846102556131df8461336c565b8861301e565b93505050600101613098565b5061320861021c61320183613753565b60ff612feb565b90505b9392505050565b61321a6142dd565b50604080516060810182528251845101815260208084015181860151019082015291810151928101519092019181019190915290565b60008080556001819055613266906002906142fe565b60006003819055600481905560058190556006819055600781905560088190556009819055600a805460ff19169055600b819055600c819055600d819055600e819055600f81905560108190556132bf90601190614345565b6132cb60126000614366565b565b6132d56142dd565b5060408051606081018252825184510381526020808401518186015103908201528282015184830151039181019190915292915050565b80600260018201055b8181121561333d5780915060028182858161332c57fe5b05018161333557fe5b059050613315565b50919050565b6013805463ffffffff19811663ffffffff9182166341c64e6d0261303901821617918290551690565b6133746142dd565b600a826040015113156133a657604051806060016040528060008152602001600081526020016000815250905061082f565b60008060006133b48561379f565b91945092509050826133e857604051806060016040528060008152602001600081526020016000815250935050505061082f565b6133f0614387565b6133f86143c7565b6134006142dd565b6134086142dd565b600086600181111561341657fe5b1415613505576011858154811061342957fe5b60009182526020918290206040805160a081018252600b90930290910180548352815160608082018452600183015482526002808401548388015260038401548386015285870192909252835180820185526004840154815260058401548188015260068401548186015285850152835180820185526007840154815260088401549681019690965260098301549386019390935291830193909352600a830154919291608084019160ff909116908111156134e157fe5b60028111156134ec57fe5b8152505093508360600151915083604001519050613653565b6012858154811061351257fe5b600091825260209182902060408051610140810182526013909302909101805460e08401908152600182015461010085015260028083015461012086015290845282516060818101855260038401548252600484015482880152600584015482860152858701919091528351808201855260068401548152600784015481880152600884015481860152858501528351808201855260098401548152600a84015481880152600b840154818601528186015283518082018552600c8401548152600d84015481880152600e84015481860152608086015283519081018452600f830154815260108301549581019590955260118201549285019290925260a0830193909352601283015491929160c084019160ff9091169081111561363357fe5b600281111561363e57fe5b8152505092508260a001519150826080015190505b6040820151600190811215613669575060408201515b808360200151131561367c575060208201515b808360400151131561368f575060408201515b60408a01805160010190819052600512156136f75780620f42406136b1613343565b63ffffffff16816136be57fe5b0663ffffffff1612156136e8576136e16136db84620f4240612feb565b8261301e565b92506136f7565b50965061082f95505050505050565b6136ff6142dd565b600088600181111561370d57fe5b14156137255761371e8b878b613a57565b9050613733565b6137308b868b613aec565b90505b6137448361025561021c8785613baa565b9b9a5050505050505050505050565b61375b6142dd565b60405180606001604052806137738460000151613be8565b81526020016137858460200151613be8565b81526020016137978460400151613be8565b905292915050565b60008080808080805b6011548110156138c2576000613890601183815481106137c457fe5b60009182526020918290206040805160a081018252600b90930290910180548352815160608082018452600183015482526002808401548388015260038401548386015285870192909252835180820185526004840154815260058401548188015260068401548186015285850152835180820185526007840154815260088401549681019690965260098301549386019390935291830193909352600a830154919291608084019160ff9091169081111561387c57fe5b600281111561388757fe5b9052508a613c13565b90506000811380156138a957508415806138a957508481125b156138b957809450600093508192505b506001016137a8565b5060005b601254811015613a49576000613a17601283815481106138e257fe5b600091825260209182902060408051610140810182526013909302909101805460e08401908152600182015461010085015260028083015461012086015290845282516060818101855260038401548252600484015482880152600584015482860152858701919091528351808201855260068401548152600784015481880152600884015481860152858501528351808201855260098401548152600a84015481880152600b840154818601528186015283518082018552600c8401548152600d84015481880152600e84015481860152608086015283519081018452600f830154815260108301549581019590955260118201549285019290925260a0830193909352601283015491929160c084019160ff90911690811115613a0357fe5b6002811115613a0e57fe5b9052508a613cbb565b9050600081138015613a305750841580613a3057508481125b15613a4057809450600193508192505b506001016138c6565b509196909550909350915050565b613a5f6142dd565b6000613a7a856000015161025561021c886020015187612feb565b90506000613a8f61020e8387602001516132cd565b9050600085608001516002811115613aa357fe5b1415613ae1576000613ab9828860200151613e0c565b12613acd57613aca81600019612feb565b90505b613ad8868383613e31565b9250505061320b565b613ad8868383613fc1565b613af46142dd565b6000613b0f856000015161025561021c886020015187612feb565b6060860151909150620a2c2a9015613b2757506216e3605b6000620f4240613b3f87606001518960200151613e0c565b81613b4657fe5b05905060008112613b55576000035b64e8d4a5100081800281038380020281900590036000811215613b8c57613b8188858960600151613fc1565b94505050505061320b565b613b9e88858960600151868686614039565b98975050505050505050565b613bb26142dd565b50604080516060810182528251845102815260208084015181860151029082015291810151928101519092029181019190915290565b600080821215613bfa5750600061082f565b620f4240821315613c0f5750620f424061082f565b5090565b600080613c28846020015184600001516132cd565b90506000620f4240613c3e838660200151613e0c565b81613c4557fe5b865191900591506000908002613c5b8480613e0c565b838402030190506000811215613c775760009350505050610555565b613c808161330c565b90506103e88183031315613c9957900391506105559050565b6103e88183011315613caf570191506105559050565b50600095945050505050565b600080613cd0846020015185600001516132cd565b90506000613ce6856040015186600001516132cd565b90506000613cf8856020015183612ef7565b90506000620f4240613d0a8584613e0c565b81613d1157fe5b0590506103e71981138015613d2757506103e881125b15613d39576000945050505050610555565b85518751600091613d49916132cd565b9050600082613d588386613e0c565b81613d5f57fe5b0590506000811280613d735750620f424081135b15613d875760009650505050505050610555565b6000613d938388612ef7565b9050600084613da68b6020015184613e0c565b81613dad57fe5b0590506000811280613dc35750620f4240818401135b15613dd957600098505050505050505050610555565b600085613de68985613e0c565b81613ded57fe5b0590506103e88112156137445760009950505050505050505050610555565b6040808201519083015160208084015190850151845186510291020191020192915050565b613e396142dd565b6000620f424080613e48613343565b63ffffffff1681613e5557fe5b0663ffffffff16625fdfb00281613e6857fe5b0590506000620f4240613e79613343565b63ffffffff1681613e8657fe5b0663ffffffff1690506000613e9a8261330c565b6103e8029050613ea86142dd565b620186a0613eb98760000151614216565b1315613ee657604051806060016040528060008152602001620f4240815260200160008152509050613f09565b6040518060600160405280620f4240815260200160008152602001600081525090505b613f1661020e8288612ef7565b90506000613f2761020e8884612ef7565b9050613f7f61020e613f64613f5285620f424088613f448c61422e565b0281613f4c57fe5b05612feb565b61025585620f424089613f448d61424e565b6102558a613f7689620f42400361330c565b6103e802612feb565b9150613fb460405180608001604052808a81526020018481526020018b6040015181526020018b60600151151581525061336c565b9998505050505050505050565b613fc96142dd565b6000613ffb61020e8660200151613ff686620f4240613fec898c60200151613e0c565b60020281613f4c57fe5b6132cd565b90506140306040518060800160405280868152602001838152602001876040015181526020018760600151151581525061336c565b95945050505050565b6140416142dd565b60608701516000199015614053575060015b600061408961020e61021c61406c8c602001518a612feb565b613ff68b6140798a61330c565b620f42408c8e0205018802612feb565b60608a0151909150620f42408601906140ba57620f42406140aa838a613e0c565b816140b157fe5b05620f42400390505b60408a0151619c406c0c9f2c9cd04674edea40000000620ea6008480028502850285020205019060021261415e5761412a61411f60405180608001604052808d81526020018681526020018e6040015181526020018e6060015115151581525061336c565b82620f424003612feb565b92506141448361025561413e8e8e8e613fc1565b84612feb565b925061415383620f424061301e565b94505050505061420c565b600281056203d09001620f4240614173613343565b63ffffffff168161418057fe5b0663ffffffff1612156141b2576141536141a461419e8d8d8d613fc1565b83612feb565b600283056203d0900161301e565b6142056141f76141ec60405180608001604052808e81526020018781526020018f6040015181526020018f6060015115151581525061336c565b83620f424003612feb565b60028305620b71b00361301e565b9450505050505b9695505050505050565b60008082131561422757508061082f565b5060000390565b60008061423a8361424e565b905061320b81820264e8d4a510000361330c565b60005b600082121561426757625fdfb082019150614251565b5b625fdfb0821261427f57625fdfb082039150614268565b6001828160025b818313156142d457818385028161429957fe5b0585019450620f4240808788860202816142af57fe5b05816142b757fe5b600095909503940592506001810181029190910290600201614286565b50505050919050565b60405180606001604052806000815260200160008152602001600081525090565b50805460018160011615610100020316600290046000825580601f106143245750614342565b601f0160209004906000526020600020908101906143429190614401565b50565b50805460008255600b02906000526020600020908101906143429190614416565b50805460008255601302906000526020600020908101906143429190614475565b6040518060a00160405280600081526020016143a16142dd565b81526020016143ae6142dd565b81526020016143bb6142dd565b81526020016000905290565b6040518060e001604052806143da6142dd565b81526020016143e76142dd565b81526020016143f46142dd565b81526020016143a16142dd565b5b80821115613c0f5760008155600101614402565b5b80821115613c0f57600080825560018201819055600282018190556003820181905560048201819055600582018190556006820181905560078201819055600882018190556009820155600a8101805460ff19169055600b01614417565b5b80821115613c0f576000808255600182018190556002820181905560038201819055600482018190556005820181905560068201819055600782018190556008820181905560098201819055600a8201819055600b8201819055600c8201819055600d8201819055600e8201819055600f820181905560108201819055601182015560128101805460ff1916905560130161447656fea2646970667358221220037024f5647853879c58fbcc61ac3616455f6f731cc6e84f91eb5a3b4e06c00464736f6c63430007060033"); From c1eb0e64c0903b4dcc102b85c18c74f70c17394c Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Sun, 7 Apr 2024 15:39:20 +0200 Subject: [PATCH 011/105] perf(interpreter): use `pop_top!` where possible (#1267) --- .../interpreter/src/instructions/control.rs | 18 ++++---- crates/interpreter/src/instructions/host.rs | 6 +-- crates/interpreter/src/instructions/memory.rs | 24 +++++------ crates/interpreter/src/instructions/system.rs | 41 +++++++++++-------- crates/interpreter/src/interpreter/stack.rs | 2 +- crates/revm/src/evm.rs | 7 ++-- 6 files changed, 53 insertions(+), 45 deletions(-) diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index 26333b77..7e0df530 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -6,27 +6,27 @@ use crate::{ pub fn jump(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::MID); - pop!(interpreter, dest); - jump_inner(interpreter, dest); + pop!(interpreter, target); + jump_inner(interpreter, target); } pub fn jumpi(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::HIGH); - pop!(interpreter, dest, value); - if value != U256::ZERO { - jump_inner(interpreter, dest); + pop!(interpreter, target, cond); + if cond != U256::ZERO { + jump_inner(interpreter, target); } } #[inline(always)] -fn jump_inner(interpreter: &mut Interpreter, dest: U256) { - let dest = as_usize_or_fail!(interpreter, dest, InstructionResult::InvalidJump); - if !interpreter.contract.is_valid_jump(dest) { +fn jump_inner(interpreter: &mut Interpreter, target: U256) { + let target = as_usize_or_fail!(interpreter, target, InstructionResult::InvalidJump); + if !interpreter.contract.is_valid_jump(target) { interpreter.instruction_result = InstructionResult::InvalidJump; return; } // SAFETY: `is_valid_jump` ensures that `dest` is in bounds. - interpreter.instruction_pointer = unsafe { interpreter.contract.bytecode.as_ptr().add(dest) }; + interpreter.instruction_pointer = unsafe { interpreter.contract.bytecode.as_ptr().add(target) }; } pub fn jumpdest(interpreter: &mut Interpreter, _host: &mut H) { diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index cd5d735e..f5069043 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -140,14 +140,14 @@ pub fn blockhash(interpreter: &mut Interpreter, host: &mut H) } pub fn sload(interpreter: &mut Interpreter, host: &mut H) { - pop!(interpreter, index); + pop_top!(interpreter, index); - let Some((value, is_cold)) = host.sload(interpreter.contract.address, index) else { + let Some((value, is_cold)) = host.sload(interpreter.contract.address, *index) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; }; gas!(interpreter, gas::sload_cost(SPEC::SPEC_ID, is_cold)); - push!(interpreter, value); + *index = value; } pub fn sstore(interpreter: &mut Interpreter, host: &mut H) { diff --git a/crates/interpreter/src/instructions/memory.rs b/crates/interpreter/src/instructions/memory.rs index 6ee2d88f..73dd4126 100644 --- a/crates/interpreter/src/instructions/memory.rs +++ b/crates/interpreter/src/instructions/memory.rs @@ -7,26 +7,26 @@ use core::cmp::max; pub fn mload(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); - pop!(interpreter, index); - let index = as_usize_or_fail!(interpreter, index); - resize_memory!(interpreter, index, 32); - push!(interpreter, interpreter.shared_memory.get_u256(index)); + pop_top!(interpreter, offset_ptr); + let offset = as_usize_or_fail!(interpreter, offset_ptr); + resize_memory!(interpreter, offset, 32); + *offset_ptr = interpreter.shared_memory.get_u256(offset); } pub fn mstore(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); - pop!(interpreter, index, value); - let index = as_usize_or_fail!(interpreter, index); - resize_memory!(interpreter, index, 32); - interpreter.shared_memory.set_u256(index, value); + pop!(interpreter, offset, value); + let offset = as_usize_or_fail!(interpreter, offset); + resize_memory!(interpreter, offset, 32); + interpreter.shared_memory.set_u256(offset, value); } pub fn mstore8(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); - pop!(interpreter, index, value); - let index = as_usize_or_fail!(interpreter, index); - resize_memory!(interpreter, index, 1); - interpreter.shared_memory.set_byte(index, value.byte(0)) + pop!(interpreter, offset, value); + let offset = as_usize_or_fail!(interpreter, offset); + resize_memory!(interpreter, offset, 1); + interpreter.shared_memory.set_byte(offset, value.byte(0)) } pub fn msize(interpreter: &mut Interpreter, _host: &mut H) { diff --git a/crates/interpreter/src/instructions/system.rs b/crates/interpreter/src/instructions/system.rs index be81fb31..25cb8dd6 100644 --- a/crates/interpreter/src/instructions/system.rs +++ b/crates/interpreter/src/instructions/system.rs @@ -3,20 +3,20 @@ use crate::{ primitives::{Spec, B256, KECCAK_EMPTY, U256}, Host, InstructionResult, Interpreter, }; +use core::ptr; pub fn keccak256(interpreter: &mut Interpreter, _host: &mut H) { - pop!(interpreter, from, len); - let len = as_usize_or_fail!(interpreter, len); + pop_top!(interpreter, offset, len_ptr); + let len = as_usize_or_fail!(interpreter, len_ptr); gas_or_fail!(interpreter, gas::keccak256_cost(len as u64)); let hash = if len == 0 { KECCAK_EMPTY } else { - let from = as_usize_or_fail!(interpreter, from); + let from = as_usize_or_fail!(interpreter, offset); resize_memory!(interpreter, from, len); crate::primitives::keccak256(interpreter.shared_memory.slice(from, len)) }; - - push_b256!(interpreter, hash); + *len_ptr = hash.into(); } pub fn address(interpreter: &mut Interpreter, _host: &mut H) { @@ -56,18 +56,25 @@ pub fn codecopy(interpreter: &mut Interpreter, _host: &mut H) pub fn calldataload(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); - pop!(interpreter, index); - let index = as_usize_saturated!(index); - let load = if index < interpreter.contract.input.len() { - let have_bytes = 32.min(interpreter.contract.input.len() - index); - let mut bytes = [0u8; 32]; - bytes[..have_bytes].copy_from_slice(&interpreter.contract.input[index..index + have_bytes]); - B256::new(bytes) - } else { - B256::ZERO - }; - - push_b256!(interpreter, load); + pop_top!(interpreter, offset_ptr); + let mut word = B256::ZERO; + let offset = as_usize_saturated!(offset_ptr); + if offset < interpreter.contract.input.len() { + let count = 32.min(interpreter.contract.input.len() - offset); + // SAFETY: count is bounded by the calldata length. + // This is `word[..count].copy_from_slice(input[offset..offset + count])`, written using + // raw pointers as apparently the compiler cannot optimize the slice version, and using + // `get_unchecked` twice is uglier. + debug_assert!(count <= 32 && offset + count <= interpreter.contract.input.len()); + unsafe { + ptr::copy_nonoverlapping( + interpreter.contract.input.as_ptr().add(offset), + word.as_mut_ptr(), + count, + ) + }; + } + *offset_ptr = word.into(); } pub fn calldatasize(interpreter: &mut Interpreter, _host: &mut H) { diff --git a/crates/interpreter/src/interpreter/stack.rs b/crates/interpreter/src/interpreter/stack.rs index 2b2c9b6d..a15b1e9c 100644 --- a/crates/interpreter/src/interpreter/stack.rs +++ b/crates/interpreter/src/interpreter/stack.rs @@ -184,7 +184,7 @@ impl Stack { /// unchanged. #[inline] pub fn push(&mut self, value: U256) -> Result<(), InstructionResult> { - // allows the compiler to optimize out the `Vec::push` capacity check + // Allows the compiler to optimize out the `Vec::push` capacity check. assume!(self.data.capacity() == STACK_LIMIT); if self.data.len() == STACK_LIMIT { return Err(InstructionResult::StackOverflow); diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index 239aa64e..3e627d0e 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -382,13 +382,14 @@ impl Evm<'_, EXT, DB> { } impl Host for Evm<'_, EXT, DB> { - fn env_mut(&mut self) -> &mut Env { - &mut self.context.evm.env - } fn env(&self) -> &Env { &self.context.evm.env } + fn env_mut(&mut self) -> &mut Env { + &mut self.context.evm.env + } + fn block_hash(&mut self, number: U256) -> Option { self.context .evm From 11e819c3764f0ba85cb0f25c22bd7a446109b199 Mon Sep 17 00:00:00 2001 From: Akash S M Date: Sun, 7 Apr 2024 19:10:17 +0530 Subject: [PATCH 012/105] Add the modifies_memory macro (#1270) * feat: add modifies_memory macro * refactor --- crates/interpreter/src/instructions/opcode.rs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index 8896c9da..58aea317 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -496,6 +496,28 @@ impl OpCode { pub const fn get(self) -> u8 { self.0 } + + /// Returns true if the opcode modifies memory. + /// + /// + #[inline] + pub const fn modifies_memory(&self) -> bool { + matches!( + *self, + OpCode::EXTCODECOPY + | OpCode::MLOAD + | OpCode::MSTORE + | OpCode::MSTORE8 + | OpCode::MCOPY + | OpCode::CODECOPY + | OpCode::CALLDATACOPY + | OpCode::RETURNDATACOPY + | OpCode::CALL + | OpCode::CALLCODE + | OpCode::DELEGATECALL + | OpCode::STATICCALL + ) + } } #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] From d06f5d0fa0cf6bbcb696c027bed86a218bea6216 Mon Sep 17 00:00:00 2001 From: Wodann Date: Mon, 8 Apr 2024 07:17:50 -0500 Subject: [PATCH 013/105] feat: pass rand feature to alloy_primitives (#1276) --- Cargo.lock | 1 + crates/primitives/Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 88b5b1e0..d1addf10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -122,6 +122,7 @@ dependencies = [ "derive_arbitrary", "derive_more", "ethereum_ssz", + "getrandom", "hex-literal", "itoa", "k256", diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index e3ef145d..7542c929 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -87,6 +87,7 @@ optional_eip3607 = [] optional_gas_refund = [] optional_no_base_fee = [] optional_beneficiary_reward = [] +rand = ["alloy-primitives/rand"] # See comments in `revm-precompile` c-kzg = ["dep:c-kzg", "dep:once_cell", "dep:derive_more"] From 1edfeb6893a4b053170886a026eb5742c5561fa6 Mon Sep 17 00:00:00 2001 From: Pana Date: Mon, 8 Apr 2024 20:56:55 +0800 Subject: [PATCH 014/105] Update documentation (#1275) * fix examples->generate_block_traces reuse TracerEip3155.gas_inspector issue * fmt code * clear the eip3155 tracer state so that it can be used in next transaction * print summary and clean state when create_end * update documentation * fix left nits * add cancun upgrade block number * remove outdated doc * remove outdated doc * remove empty file * TS is unit used to trigger the hardork --------- Co-authored-by: rakita --- crates/primitives/src/specification.rs | 2 +- crates/revm/src/frame/frame_or_result.rs | 0 crates/revm/src/frame/result.rs | 0 documentation/src/SUMMARY.md | 2 -- documentation/src/crates/primitives.md | 8 +------- documentation/src/crates/primitives/log.md | 2 ++ 6 files changed, 4 insertions(+), 10 deletions(-) delete mode 100644 crates/revm/src/frame/frame_or_result.rs delete mode 100644 crates/revm/src/frame/result.rs diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index c9767028..e106e8fd 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -27,7 +27,7 @@ pub enum SpecId { GRAY_GLACIER = 14, // Gray Glacier 15050000 MERGE = 15, // Paris/Merge 15537394 (TTD: 58750000000000000000000) SHANGHAI = 16, // Shanghai 17034870 (TS: 1681338455) - CANCUN = 17, // Cancun TBD + CANCUN = 17, // Cancun 19426587 (TS: 1710338135) #[default] LATEST = u8::MAX, } diff --git a/crates/revm/src/frame/frame_or_result.rs b/crates/revm/src/frame/frame_or_result.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/crates/revm/src/frame/result.rs b/crates/revm/src/frame/result.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/documentation/src/SUMMARY.md b/documentation/src/SUMMARY.md index 05a92558..d40b1b2b 100644 --- a/documentation/src/SUMMARY.md +++ b/documentation/src/SUMMARY.md @@ -20,10 +20,8 @@ - [result](./crates/primitives/result.md) - [environment](./crates/primitives/environment.md) - [specifications](./crates/primitives/specifications.md) - - [bits](./crates/primitives/bits.md) - [bytecode](./crates/primitives/bytecode.md) - [constants](./crates/primitives/constants.md) - - [log](./crates/primitives/log.md) - [precompile](./crates/primitives/precompile.md) - [state](./crates/primitives/state.md) - [utils](./crates/primitives/utils.md) diff --git a/documentation/src/crates/primitives.md b/documentation/src/crates/primitives.md index bc058e5a..45d57594 100644 --- a/documentation/src/crates/primitives.md +++ b/documentation/src/crates/primitives.md @@ -6,12 +6,10 @@ It is set up to be compatible with environments that do not include Rust's stand ### Modules: -- [bits](./primitives/bits.md): This module provides types for handling specific sizes of byte arrays (Address and B256). - [bytecode](./primitives/bytecode.md): This module provides functionality related to EVM bytecode. - [constants](./primitives/constants.md): This module contains constant values used throughout the EVM implementation. - [db](./primitives/database.md): This module contains data structures and functions related to the EVM's database implementation. - [env](./primitives/environment.md): This module contains types and functions related to the EVM's environment, including block headers, and environment values. -- [log](./primitives/log.md): This module provides types and functionality for Ethereum logs. - [precompile](./primitives/precompile.md): This module contains types related to Ethereum's precompiled contracts. - [result](./primitives/result.md): This module provides types for representing execution results and errors in the EVM. - [specification](./primitives/specifications.md): This module defines types related to Ethereum specifications (also known as hard forks). @@ -30,10 +28,6 @@ It is set up to be compatible with environments that do not include Rust's stand - `ruint`: The ruint crate provides types and functions for big unsigned integer arithmetic. - `c-kzg`: A minimal implementation of the Polynomial Commitments API for EIP-4844, written in C. (With rust bindings) -### Type Aliases: - -- `Hash`: An alias for B256, typically used to represent 256-bit hashes or integer values in Ethereum. - ### Re-exported Types: - `Address`: A type representing a 160-bit (or 20-byte) array, typically used for Ethereum addresses. @@ -43,4 +37,4 @@ It is set up to be compatible with environments that do not include Rust's stand - `HashMap` and `HashSet`: High-performance hash map and hash set data structures from the hashbrown crate. Re-exported Modules: -All types, constants, and functions from the `bytecode`, `constants`, `env`, `log`, `precompile`, `result`, `specification`, `state`, `utilities`, `KzgSettings`, `EnvKzgSettings`, `trusted_setup_points` types and methods were all re-exported, allowing users to import these items directly from the `primitives` crate. +All types, constants, and functions from the `bytecode`, `constants`, `env`, `precompile`, `result`, `specification`, `state`, `utilities`, `KzgSettings`, `EnvKzgSettings`, `trusted_setup_points` types and methods were all re-exported, allowing users to import these items directly from the `primitives` crate. diff --git a/documentation/src/crates/primitives/log.md b/documentation/src/crates/primitives/log.md index 6bd7bcc1..accd1be6 100644 --- a/documentation/src/crates/primitives/log.md +++ b/documentation/src/crates/primitives/log.md @@ -1,5 +1,7 @@ # Log +> NOTE: This module's types have been replaced by [`alloy_primitives`](https://github.com/alloy-rs/core)'s `Log` and `LogData`. + This piece of Rust code defines a structure called Log which represents an Ethereum log entry. These logs are integral parts of the Ethereum network and are typically produced by smart contracts during execution. Each Log has three components: - `address`: This field represents the address of the log originator, typically the smart contract that generated the log. The `Address` data type signifies a 160-bit Ethereum address. From b4a87a42745772a752def844a895e1d6c53b2c99 Mon Sep 17 00:00:00 2001 From: rakita Date: Wed, 10 Apr 2024 01:48:18 +0200 Subject: [PATCH 015/105] feat: EOF (Ethereum Object Format) (#1143) * eof * feat(EOF): Header decoder * EofBody decode * disable eof deprecated opcodes * add eof instructions * temp tests * rjump instructions * eof rjump with tests * EOF bytecode * callf, retf, jumpf * tests for callf,retf,jumpf * small rename * add dataload, dataloadn and datacopy opcodes * refactor calls * blueprint for creates * eof create inputs * some wip * add eofcreate structs and exccall flow * wip eofcreate code flow and handlers * fix tests * eof creates * refactor eofcreate a little * some work on extcall * feat: refactor simplify CallInput, eof extcalls * feat: restructure OpCode and add stack input/output num * add flags for stack_io and not_eof * wip eof verification * wip validation * EOF Bytecode validity * insturction and jump validation seems good * merged eof validate function * EOP test runner, fex fixes * RETURNDATALOAD, fix call bugs, refactor gas warm/cold calc * debug session, rjumpv imm fix * fixing validation bugs, bytecode decoder for EOF in revme * pass most of validation tests * bounds check moved to decode * Fix merge compilation, fmt * TXCREATE work * remove training wheels, panic on eof * test fix and std * std * fix test * fix valgrind * fix tests * clippy * removed checked logic * small change * no std revm-test * check pending TODOs * build check no_std * doc * chore: move some files. cleanup comments * fix fmt,clippy and compile error --- Cargo.lock | 2 + bins/revm-test/Cargo.toml | 2 +- bins/revm-test/src/bin/analysis.rs | 16 +- bins/revme/src/cmd.rs | 7 + bins/revme/src/cmd/bytecode.rs | 39 + bins/revme/src/cmd/statetest/runner.rs | 8 +- crates/interpreter/Cargo.toml | 10 + crates/interpreter/src/function_stack.rs | 61 + crates/interpreter/src/gas.rs | 2 +- crates/interpreter/src/gas/calc.rs | 168 +- crates/interpreter/src/gas/constants.rs | 9 + crates/interpreter/src/host.rs | 26 +- crates/interpreter/src/host/dummy.rs | 6 +- crates/interpreter/src/inner_models.rs | 170 - crates/interpreter/src/instruction_result.rs | 21 +- crates/interpreter/src/instructions.rs | 7 +- .../interpreter/src/instructions/contract.rs | 638 +++ .../src/instructions/contract/call_helpers.rs | 69 + .../interpreter/src/instructions/control.rs | 250 +- crates/interpreter/src/instructions/data.rs | 214 + crates/interpreter/src/instructions/host.rs | 338 +- .../interpreter/src/instructions/host_env.rs | 2 +- crates/interpreter/src/instructions/i256.rs | 18 +- crates/interpreter/src/instructions/macros.rs | 64 +- crates/interpreter/src/instructions/memory.rs | 6 +- crates/interpreter/src/instructions/stack.rs | 111 +- crates/interpreter/src/instructions/system.rs | 71 +- .../interpreter/src/instructions/utility.rs | 7 + crates/interpreter/src/interpreter.rs | 179 +- .../interpreter/src/interpreter/analysis.rs | 629 ++- .../interpreter/src/interpreter/contract.rs | 53 +- .../src/interpreter/shared_memory.rs | 19 +- crates/interpreter/src/interpreter/stack.rs | 45 +- crates/interpreter/src/interpreter_action.rs | 67 + .../src/interpreter_action/call_inputs.rs | 99 + .../{ => interpreter_action}/call_outcome.rs | 0 .../src/interpreter_action/create_inputs.rs | 51 + .../create_outcome.rs | 0 .../interpreter_action/eof_create_inputs.rs | 41 + .../interpreter_action/eof_create_outcome.rs | 87 + crates/interpreter/src/lib.rs | 29 +- crates/interpreter/src/opcode.rs | 745 +++ crates/interpreter/src/opcode/eof_printer.rs | 67 + .../tests/EOFTests/EIP3540/validInvalid.json | 489 ++ .../tests/EOFTests/EIP3670/validInvalid.json | 2568 +++++++++ .../tests/EOFTests/EIP4200/validInvalid.json | 513 ++ .../tests/EOFTests/EIP4750/validInvalid.json | 323 ++ .../tests/EOFTests/EIP5450/validInvalid.json | 1730 ++++++ .../EOFTests/efExample/validInvalid.json | 485 ++ .../tests/EOFTests/efExample/ymlExample.json | 51 + .../eof_validation/EOF1_callf_truncated.json | 24 + .../EOF1_code_section_0_size.json | 24 + .../EOF1_code_section_missing.json | 24 + .../EOF1_code_section_offset.json | 14 + .../EOF1_data_section_0_size.json | 14 + ...EOF1_data_section_before_code_section.json | 15 + ...OF1_data_section_before_types_section.json | 15 + .../EOF1_dataloadn_truncated.json | 24 + .../EOF1_embedded_container.json | 55 + .../EOF1_embedded_container_invalid.json | 87 + .../EOF1_eofcreate_invalid.json | 51 + .../eof_validation/EOF1_eofcreate_valid.json | 30 + .../EOF1_header_not_terminated.json | 78 + .../EOF1_incomplete_section_size.json | 69 + .../EOF1_invalid_section_0_type.json | 42 + .../EOF1_invalid_type_section_size.json | 51 + .../EOF1_multiple_data_sections.json | 15 + .../EOF1_multiple_type_sections.json | 24 + .../eof_validation/EOF1_no_type_section.json | 24 + .../EOF1_returncontract_invalid.json | 42 + .../EOF1_returncontract_valid.json | 30 + .../EOF1_rjump_invalid_destination.json | 78 + .../eof_validation/EOF1_rjump_truncated.json | 24 + .../EOF1_rjumpi_invalid_destination.json | 78 + .../eof_validation/EOF1_rjumpi_truncated.json | 24 + .../EOF1_rjumpv_invalid_destination.json | 114 + .../eof_validation/EOF1_rjumpv_truncated.json | 42 + .../eof_validation/EOF1_section_order.json | 94 + .../EOF1_too_many_code_sections.json | 23 + .../eof_validation/EOF1_trailing_bytes.json | 24 + .../eof_validation/EOF1_truncated_push.json | 5014 +++++++++++++++++ .../EOF1_truncated_section.json | 49 + .../EOF1_type_section_missing.json | 33 + .../EOF1_type_section_not_first.json | 42 + .../EOF1_types_section_0_size.json | 24 + .../EOF1_types_section_missing.json | 24 + .../EOF1_undefined_opcodes.json | 1677 ++++++ .../eof_validation/EOF1_unknown_section.json | 60 + .../eof_validation/EOF1_valid_rjump.json | 30 + .../eof_validation/EOF1_valid_rjumpi.json | 30 + .../eof_validation/EOF1_valid_rjumpv.json | 38 + .../callf_into_nonreturning.json | 15 + .../callf_invalid_code_section_index.json | 15 + .../eof_validation/data_section_missing.json | 15 + .../EOFTests/eof_validation/dataloadn.json | 75 + .../deprecated_instructions.json | 150 + .../incomplete_section_size.json | 15 + .../jumpf_compatible_outputs.json | 14 + .../eof_validation/jumpf_equal_outputs.json | 14 + .../jumpf_incompatible_outputs.json | 15 + .../many_code_sections_1023.json | 14 + .../many_code_sections_1024.json | 14 + .../eof_validation/max_arguments_count.json | 57 + .../eof_validation/max_stack_height.json | 84 + .../minimal_valid_EOF1_code.json | 14 + .../minimal_valid_EOF1_code_with_data.json | 14 + ...mal_valid_EOF1_multiple_code_sections.json | 31 + .../multiple_code_sections_headers.json | 15 + .../eof_validation/non_returning_status.json | 124 + .../eof_validation/stack/backwards_rjump.json | 57 + .../stack/backwards_rjump_variable_stack.json | 75 + .../stack/backwards_rjumpi.json | 100 + .../backwards_rjumpi_variable_stack.json | 82 + .../stack/backwards_rjumpv.json | 74 + .../backwards_rjumpv_variable_stack.json | 74 + .../stack/callf_stack_overflow.json | 49 + .../callf_stack_overflow_variable_stack.json | 58 + .../stack/callf_stack_validation.json | 32 + .../callf_with_inputs_stack_overflow.json | 58 + ..._inputs_stack_overflow_variable_stack.json | 94 + .../stack/dupn_stack_validation.json | 58 + .../stack/exchange_deep_stack_validation.json | 14 + .../exchange_empty_stack_validation.json | 15 + .../stack/exchange_stack_validation.json | 201 + .../eof_validation/stack/forwards_rjump.json | 46 + .../stack/forwards_rjump_variable_stack.json | 46 + .../eof_validation/stack/forwards_rjumpi.json | 110 + .../stack/forwards_rjumpi_variable_stack.json | 110 + .../eof_validation/stack/forwards_rjumpv.json | 86 + .../stack/forwards_rjumpv_variable_stack.json | 86 + .../stack/jumpf_stack_overflow.json | 49 + .../jumpf_stack_overflow_variable_stack.json | 58 + .../stack/jumpf_to_nonreturning.json | 47 + .../jumpf_to_nonreturning_variable_stack.json | 40 + .../stack/jumpf_to_returning.json | 101 + .../jumpf_to_returning_variable_stack.json | 78 + .../jumpf_with_inputs_stack_overflow.json | 32 + ..._inputs_stack_overflow_variable_stack.json | 50 + .../stack/no_terminating_instruction.json | 33 + .../stack/non_constant_stack_height.json | 31 + .../stack/retf_stack_validation.json | 40 + .../stack/retf_variable_stack.json | 42 + .../stack/self_referencing_jumps.json | 32 + ...self_referencing_jumps_variable_stack.json | 32 + .../stack/stack_range_maximally_broad.json | 23 + .../stack/swapn_stack_validation.json | 58 + .../eof_validation/stack/underflow.json | 51 + .../stack/underflow_variable_stack.json | 96 + .../stack/unreachable_instructions.json | 33 + .../too_many_code_sections.json | 15 + .../unreachable_code_sections.json | 78 + .../eof_validation/validate_EOF_prefix.json | 87 + .../eof_validation/validate_EOF_version.json | 51 + .../eof_validation/validate_empty_code.json | 15 + .../tests/EOFTests/ori/validInvalid.json | 677 +++ crates/interpreter/tests/eof.rs | 184 + crates/precompile/src/blake2.rs | 2 +- crates/precompile/src/lib.rs | 2 +- crates/primitives/src/bytecode.rs | 178 +- crates/primitives/src/bytecode/eof.rs | 156 + crates/primitives/src/bytecode/eof/body.rs | 109 + .../src/bytecode/eof/decode_helpers.rs | 20 + crates/primitives/src/bytecode/eof/header.rs | 257 + .../src/bytecode/eof/types_section.rs | 62 + crates/primitives/src/bytecode/legacy.rs | 63 + .../src/bytecode/legacy/jump_map.rs | 36 + crates/primitives/src/db.rs | 6 + crates/primitives/src/env.rs | 85 +- crates/primitives/src/env/handler_cfg.rs | 4 +- crates/primitives/src/lib.rs | 1 + crates/primitives/src/result.rs | 12 + crates/primitives/src/specification.rs | 32 +- crates/primitives/src/state.rs | 2 +- crates/revm/benches/bench.rs | 18 +- crates/revm/src/context/evm_context.rs | 72 +- crates/revm/src/context/inner_evm_context.rs | 123 +- crates/revm/src/db/emptydb.rs | 2 +- crates/revm/src/db/in_memory_db.rs | 4 +- crates/revm/src/evm.rs | 19 +- crates/revm/src/frame.rs | 53 +- .../src/handler/handle_types/execution.rs | 75 +- crates/revm/src/handler/mainnet.rs | 5 +- crates/revm/src/handler/mainnet/execution.rs | 44 +- crates/revm/src/handler/mainnet/validation.rs | 3 +- crates/revm/src/inspector.rs | 23 +- crates/revm/src/inspector/customprinter.rs | 16 +- crates/revm/src/inspector/eip3155.rs | 7 +- crates/revm/src/inspector/handler_register.rs | 12 +- crates/revm/src/journaled_state.rs | 25 +- .../src/crates/primitives/bytecode.md | 6 +- 190 files changed, 23572 insertions(+), 1101 deletions(-) create mode 100644 bins/revme/src/cmd/bytecode.rs create mode 100644 crates/interpreter/src/function_stack.rs delete mode 100644 crates/interpreter/src/inner_models.rs create mode 100644 crates/interpreter/src/instructions/contract.rs create mode 100644 crates/interpreter/src/instructions/contract/call_helpers.rs create mode 100644 crates/interpreter/src/instructions/data.rs create mode 100644 crates/interpreter/src/instructions/utility.rs create mode 100644 crates/interpreter/src/interpreter_action.rs create mode 100644 crates/interpreter/src/interpreter_action/call_inputs.rs rename crates/interpreter/src/{ => interpreter_action}/call_outcome.rs (100%) create mode 100644 crates/interpreter/src/interpreter_action/create_inputs.rs rename crates/interpreter/src/{ => interpreter_action}/create_outcome.rs (100%) create mode 100644 crates/interpreter/src/interpreter_action/eof_create_inputs.rs create mode 100644 crates/interpreter/src/interpreter_action/eof_create_outcome.rs create mode 100644 crates/interpreter/src/opcode.rs create mode 100644 crates/interpreter/src/opcode/eof_printer.rs create mode 100644 crates/interpreter/tests/EOFTests/EIP3540/validInvalid.json create mode 100644 crates/interpreter/tests/EOFTests/EIP3670/validInvalid.json create mode 100644 crates/interpreter/tests/EOFTests/EIP4200/validInvalid.json create mode 100644 crates/interpreter/tests/EOFTests/EIP4750/validInvalid.json create mode 100644 crates/interpreter/tests/EOFTests/EIP5450/validInvalid.json create mode 100644 crates/interpreter/tests/EOFTests/efExample/validInvalid.json create mode 100644 crates/interpreter/tests/EOFTests/efExample/ymlExample.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_callf_truncated.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_code_section_0_size.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_code_section_missing.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_code_section_offset.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_data_section_0_size.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_data_section_before_code_section.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_data_section_before_types_section.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_dataloadn_truncated.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_embedded_container.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_embedded_container_invalid.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_eofcreate_invalid.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_eofcreate_valid.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_header_not_terminated.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_incomplete_section_size.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_invalid_section_0_type.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_invalid_type_section_size.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_multiple_data_sections.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_multiple_type_sections.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_no_type_section.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_returncontract_invalid.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_returncontract_valid.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjump_invalid_destination.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjump_truncated.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjumpi_invalid_destination.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjumpi_truncated.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjumpv_invalid_destination.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjumpv_truncated.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_section_order.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_too_many_code_sections.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_trailing_bytes.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_truncated_push.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_truncated_section.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_type_section_missing.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_type_section_not_first.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_types_section_0_size.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_types_section_missing.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_undefined_opcodes.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_unknown_section.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_valid_rjump.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_valid_rjumpi.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/EOF1_valid_rjumpv.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/callf_into_nonreturning.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/callf_invalid_code_section_index.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/data_section_missing.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/dataloadn.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/deprecated_instructions.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/incomplete_section_size.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/jumpf_compatible_outputs.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/jumpf_equal_outputs.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/jumpf_incompatible_outputs.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/many_code_sections_1023.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/many_code_sections_1024.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/max_arguments_count.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/max_stack_height.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/minimal_valid_EOF1_code.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/minimal_valid_EOF1_code_with_data.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/minimal_valid_EOF1_multiple_code_sections.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/multiple_code_sections_headers.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/non_returning_status.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjump.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjump_variable_stack.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjumpi.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjumpi_variable_stack.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjumpv.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjumpv_variable_stack.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/callf_stack_overflow.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/callf_stack_overflow_variable_stack.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/callf_stack_validation.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/callf_with_inputs_stack_overflow.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/callf_with_inputs_stack_overflow_variable_stack.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/dupn_stack_validation.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/exchange_deep_stack_validation.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/exchange_empty_stack_validation.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/exchange_stack_validation.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjump.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjump_variable_stack.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjumpi.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjumpi_variable_stack.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjumpv.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjumpv_variable_stack.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_stack_overflow.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_stack_overflow_variable_stack.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_to_nonreturning.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_to_nonreturning_variable_stack.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_to_returning.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_to_returning_variable_stack.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_with_inputs_stack_overflow.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_with_inputs_stack_overflow_variable_stack.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/no_terminating_instruction.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/non_constant_stack_height.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/retf_stack_validation.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/retf_variable_stack.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/self_referencing_jumps.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/self_referencing_jumps_variable_stack.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/stack_range_maximally_broad.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/swapn_stack_validation.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/underflow.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/underflow_variable_stack.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/stack/unreachable_instructions.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/too_many_code_sections.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/unreachable_code_sections.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/validate_EOF_prefix.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/validate_EOF_version.json create mode 100644 crates/interpreter/tests/EOFTests/eof_validation/validate_empty_code.json create mode 100644 crates/interpreter/tests/EOFTests/ori/validInvalid.json create mode 100644 crates/interpreter/tests/eof.rs create mode 100644 crates/primitives/src/bytecode/eof.rs create mode 100644 crates/primitives/src/bytecode/eof/body.rs create mode 100644 crates/primitives/src/bytecode/eof/decode_helpers.rs create mode 100644 crates/primitives/src/bytecode/eof/header.rs create mode 100644 crates/primitives/src/bytecode/eof/types_section.rs create mode 100644 crates/primitives/src/bytecode/legacy.rs create mode 100644 crates/primitives/src/bytecode/legacy/jump_map.rs diff --git a/Cargo.lock b/Cargo.lock index d1addf10..d008a35c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2870,6 +2870,8 @@ version = "4.0.0" dependencies = [ "revm-primitives", "serde", + "serde_json", + "walkdir", ] [[package]] diff --git a/bins/revm-test/Cargo.toml b/bins/revm-test/Cargo.toml index 6034e26f..f26c4e78 100644 --- a/bins/revm-test/Cargo.toml +++ b/bins/revm-test/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] bytes = "1.6" hex = "0.4" -revm = { path = "../../crates/revm", version = "8.0.0",default-features=false } +revm = { path = "../../crates/revm", version = "8.0.0", default-features=false } microbench = "0.5" alloy-sol-macro = "0.7.0" alloy-sol-types = "0.7.0" diff --git a/bins/revm-test/src/bin/analysis.rs b/bins/revm-test/src/bin/analysis.rs index b8557b69..40bbcf39 100644 --- a/bins/revm-test/src/bin/analysis.rs +++ b/bins/revm-test/src/bin/analysis.rs @@ -7,10 +7,9 @@ use revm::{ use std::time::Instant; fn main() { - let contract_data : Bytes = hex::decode( "6060604052341561000f57600080fd5b604051610dd1380380610dd18339810160405280805190602001909190805182019190602001805190602001909190805182019190505083600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508360008190555082600390805190602001906100a79291906100e3565b5081600460006101000a81548160ff021916908360ff16021790555080600590805190602001906100d99291906100e3565b5050505050610188565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061012457805160ff1916838001178555610152565b82800160010185558215610152579182015b82811115610151578251825591602001919060010190610136565b5b50905061015f9190610163565b5090565b61018591905b80821115610181576000816000905550600101610169565b5090565b90565b610c3a806101976000396000f3006060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b4578063095ea7b31461014257806318160ddd1461019c57806323b872dd146101c557806327e235e31461023e578063313ce5671461028b5780635c658165146102ba57806370a082311461032657806395d89b4114610373578063a9059cbb14610401578063dd62ed3e1461045b575b600080fd5b34156100bf57600080fd5b6100c76104c7565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101075780820151818401526020810190506100ec565b50505050905090810190601f1680156101345780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561014d57600080fd5b610182600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610565565b604051808215151515815260200191505060405180910390f35b34156101a757600080fd5b6101af610657565b6040518082815260200191505060405180910390f35b34156101d057600080fd5b610224600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061065d565b604051808215151515815260200191505060405180910390f35b341561024957600080fd5b610275600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506108f7565b6040518082815260200191505060405180910390f35b341561029657600080fd5b61029e61090f565b604051808260ff1660ff16815260200191505060405180910390f35b34156102c557600080fd5b610310600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610922565b6040518082815260200191505060405180910390f35b341561033157600080fd5b61035d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610947565b6040518082815260200191505060405180910390f35b341561037e57600080fd5b610386610990565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103c65780820151818401526020810190506103ab565b50505050905090810190601f1680156103f35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561040c57600080fd5b610441600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610a2e565b604051808215151515815260200191505060405180910390f35b341561046657600080fd5b6104b1600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b87565b6040518082815260200191505060405180910390f35b60038054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561055d5780601f106105325761010080835404028352916020019161055d565b820191906000526020600020905b81548152906001019060200180831161054057829003601f168201915b505050505081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60005481565b600080600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015801561072e5750828110155b151561073957600080fd5b82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555082600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8110156108865782600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a360019150509392505050565b60016020528060005260406000206000915090505481565b600460009054906101000a900460ff1681565b6002602052816000526040600020602052806000526040600020600091509150505481565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60058054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a265780601f106109fb57610100808354040283529160200191610a26565b820191906000526020600020905b815481529060010190602001808311610a0957829003601f168201915b505050505081565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a7e57600080fd5b81600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050929150505600a165627a7a72305820df254047bc8f2904ad3e966b6db116d703bebd40efadadb5e738c836ffc8f58a0029" ).unwrap().into(); + let contract_data : Bytes = hex::decode( "6060604052341561000f57600080fd5b604051610dd1380380610dd18339810160405280805190602001909190805182019190602001805190602001909190805182019190505083600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508360008190555082600390805190602001906100a79291906100e3565b5081600460006101000a81548160ff021916908360ff16021790555080600590805190602001906100d99291906100e3565b5050505050610188565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061012457805160ff1916838001178555610152565b82800160010185558215610152579182015b82811115610151578251825591602001919060010190610136565b5b50905061015f9190610163565b5090565b61018591905b80821115610181576000816000905550600101610169565b5090565b90565b610c3a806101976000396000f3006060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b4578063095ea7b31461014257806318160ddd1461019c57806323b872dd146101c557806327e235e31461023e578063313ce5671461028b5780635c658165146102ba57806370a082311461032657806395d89b4114610373578063a9059cbb14610401578063dd62ed3e1461045b575b600080fd5b34156100bf57600080fd5b6100c76104c7565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101075780820151818401526020810190506100ec565b50505050905090810190601f1680156101345780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561014d57600080fd5b610182600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610565565b604051808215151515815260200191505060405180910390f35b34156101a757600080fd5b6101af610657565b6040518082815260200191505060405180910390f35b34156101d057600080fd5b610224600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061065d565b604051808215151515815260200191505060405180910390f35b341561024957600080fd5b610275600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506108f7565b6040518082815260200191505060405180910390f35b341561029657600080fd5b61029e61090f565b604051808260ff1660ff16815260200191505060405180910390f35b34156102c557600080fd5b610310600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610922565b6040518082815260200191505060405180910390f35b341561033157600080fd5b61035d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610947565b6040518082815260200191505060405180910390f35b341561037e57600080fd5b610386610990565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103c65780820151818401526020810190506103ab565b50505050905090810190601f1680156103f35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561040c57600080fd5b610441600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610a2e565b604051808215151515815260200191505060405180910390f35b341561046657600080fd5b6104b1600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b87565b6040518082815260200191505060405180910390f35b60038054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561055d5780601f106105325761010080835404028352916020019161055d565b820191906000526020600020905b81548152906001019060200180831161054057829003601f168201915b505050505081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60005481565b600080600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015801561072e5750828110155b151561073957600080fd5b82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555082600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8110156108865782600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a360019150509392505050565b60016020528060005260406000206000915090505481565b600460009054906101000a900460ff1681565b6002602052816000526040600020602052806000526040600020600091509150505481565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60058054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a265780601f106109fb57610100808354040283529160200191610a26565b820191906000526020600020905b815481529060010190602001808311610a0957829003601f168201915b505050505081565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a7e57600080fd5b81600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050929150505600a165627a7a72305820df254047bc8f2904ad3e966b6db116d703bebd40efadadb5e738c836ffc8f58a0029").unwrap().into(); let bytecode_raw = Bytecode::new_raw(contract_data.clone()); - let bytecode_checked = Bytecode::new_raw(contract_data.clone()).to_checked(); let bytecode_analysed = to_analysed(Bytecode::new_raw(contract_data)); // BenchmarkDB is dummy state that implements Database trait. @@ -36,17 +35,6 @@ fn main() { } println!("Raw elapsed time: {:?}", timer.elapsed()); - let mut evm = evm - .modify() - .reset_handler_with_db(BenchmarkDB::new_bytecode(bytecode_checked)) - .build(); - - let timer = Instant::now(); - for _ in 0..30000 { - let _ = evm.transact().unwrap(); - } - println!("Checked elapsed time: {:?}", timer.elapsed()); - let mut evm = evm .modify() .reset_handler_with_db(BenchmarkDB::new_bytecode(bytecode_analysed)) @@ -56,5 +44,5 @@ fn main() { for _ in 0..30000 { let _ = evm.transact().unwrap(); } - println!("Analysed elapsed time: {:?}", timer.elapsed()); + println!("Analyzed elapsed time: {:?}", timer.elapsed()); } diff --git a/bins/revme/src/cmd.rs b/bins/revme/src/cmd.rs index 3734b69b..ec4d419a 100644 --- a/bins/revme/src/cmd.rs +++ b/bins/revme/src/cmd.rs @@ -1,3 +1,4 @@ +pub mod bytecode; pub mod evmrunner; pub mod format_kzg_setup; pub mod statetest; @@ -18,6 +19,8 @@ pub enum MainCmd { about = "Evm runner command allows running arbitrary evm bytecode.\nBytecode can be provided from cli or from file with --path option." )] Evm(evmrunner::Cmd), + #[structopt(alias = "bc", about = "Prints the opcodes of an hex Bytecodes.")] + Bytecode(bytecode::Cmd), } #[derive(Debug, thiserror::Error)] @@ -36,6 +39,10 @@ impl MainCmd { Self::Statetest(cmd) => cmd.run().map_err(Into::into), Self::FormatKzgSetup(cmd) => cmd.run().map_err(Into::into), Self::Evm(cmd) => cmd.run().map_err(Into::into), + Self::Bytecode(cmd) => { + cmd.run(); + Ok(()) + } } } } diff --git a/bins/revme/src/cmd/bytecode.rs b/bins/revme/src/cmd/bytecode.rs new file mode 100644 index 00000000..9bc8a92e --- /dev/null +++ b/bins/revme/src/cmd/bytecode.rs @@ -0,0 +1,39 @@ +use revm::{ + interpreter::opcode::eof_printer::print_eof_code, + primitives::{Bytes, Eof}, +}; +use structopt::StructOpt; + +/// Statetest command +#[derive(StructOpt, Debug)] +pub struct Cmd { + /// EOF bytecode in hex format. It bytes start with 0xFE it will be interpreted as a EOF. + /// Otherwise, it will be interpreted as a EOF bytecode. + #[structopt(required = true)] + bytes: String, +} + +impl Cmd { + /// Run statetest command. + pub fn run(&self) { + let trimmed = self.bytes.trim_start_matches("0x"); + let Ok(bytes) = hex::decode(trimmed) else { + eprintln!("Invalid hex string"); + return; + }; + let bytes: Bytes = bytes.into(); + if bytes.is_empty() { + eprintln!("Empty hex string"); + return; + } + if bytes[0] == 0xEF { + let Ok(eof) = Eof::decode(bytes) else { + eprintln!("Invalid EOF bytecode"); + return; + }; + println!("{:#?}", eof); + } else { + print_eof_code(&bytes) + } + } +} diff --git a/bins/revme/src/cmd/statetest/runner.rs b/bins/revme/src/cmd/statetest/runner.rs index b62e20c3..f2a58b61 100644 --- a/bins/revme/src/cmd/statetest/runner.rs +++ b/bins/revme/src/cmd/statetest/runner.rs @@ -8,7 +8,6 @@ use revm::{ db::EmptyDB, inspector_handle_register, inspectors::TracerEip3155, - interpreter::CreateScheme, primitives::{ calc_excess_blob_gas, keccak256, Bytecode, Bytes, EVMResultGeneric, Env, ExecutionResult, SpecId, TransactTo, B256, U256, @@ -332,7 +331,7 @@ pub fn execute_test_suite( let to = match unit.transaction.to { Some(add) => TransactTo::Call(add), - None => TransactTo::Create(CreateScheme::Create), + None => TransactTo::Create, }; env.tx.transact_to = to; @@ -398,7 +397,7 @@ pub fn execute_test_suite( // print only once or // if we are already in trace mode, just return error static FAILED: AtomicBool = AtomicBool::new(false); - if FAILED.swap(true, Ordering::SeqCst) { + if trace || FAILED.swap(true, Ordering::SeqCst) { return Err(e); } @@ -418,7 +417,8 @@ pub fn execute_test_suite( let mut evm = Evm::builder() .with_spec_id(spec_id) .with_db(state) - .with_external_context(TracerEip3155::new(Box::new(stdout()))) + .with_env(env.clone()) + .with_external_context(TracerEip3155::new(Box::new(stdout())).without_summary()) .append_handler_register(inspector_handle_register) .build(); let _ = evm.transact_commit(); diff --git a/crates/interpreter/Cargo.toml b/crates/interpreter/Cargo.toml index e2bc35ff..e828fb07 100644 --- a/crates/interpreter/Cargo.toml +++ b/crates/interpreter/Cargo.toml @@ -22,6 +22,16 @@ serde = { version = "1.0", default-features = false, features = [ "rc", ], optional = true } +[dev-dependencies] +walkdir = "2.5" +serde_json = { version = "1.0"} + +[[test]] +name = "eof" +path = "tests/eof.rs" +required-features = ["serde"] + + [features] default = ["std"] std = ["serde?/std", "revm-primitives/std"] diff --git a/crates/interpreter/src/function_stack.rs b/crates/interpreter/src/function_stack.rs new file mode 100644 index 00000000..ef786cd6 --- /dev/null +++ b/crates/interpreter/src/function_stack.rs @@ -0,0 +1,61 @@ +use std::vec::Vec; +/// Function return frame. +/// Needed information for returning from a function. +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] +pub struct FunctionReturnFrame { + /// The index of the code container that this frame is executing. + pub idx: usize, + /// The program counter where frame execution should continue. + pub pc: usize, +} + +impl FunctionReturnFrame { + /// Return new function frame. + pub fn new(idx: usize, pc: usize) -> Self { + Self { idx, pc } + } +} + +/// Function Stack +#[derive(Debug, Default)] +pub struct FunctionStack { + pub return_stack: Vec, + pub current_code_idx: usize, +} + +impl FunctionStack { + /// Returns new function stack. + pub fn new() -> Self { + Self { + return_stack: Vec::new(), + current_code_idx: 0, + } + } + + /// Pushes a new frame to the stack. and sets current_code_idx to new value. + pub fn push(&mut self, program_counter: usize, new_idx: usize) { + self.return_stack.push(FunctionReturnFrame { + idx: self.current_code_idx, + pc: program_counter, + }); + self.current_code_idx = new_idx; + } + + /// Return stack length + pub fn return_stack_len(&self) -> usize { + self.return_stack.len() + } + + /// Pops a frame from the stack and sets current_code_idx to the popped frame's idx. + pub fn pop(&mut self) -> Option { + self.return_stack.pop().map(|frame| { + self.current_code_idx = frame.idx; + frame + }) + } + + /// Sets current_code_idx, this is needed for JUMPF opcode. + pub fn set_current_code_idx(&mut self, idx: usize) { + self.current_code_idx = idx; + } +} diff --git a/crates/interpreter/src/gas.rs b/crates/interpreter/src/gas.rs index 51739b10..94c440f4 100644 --- a/crates/interpreter/src/gas.rs +++ b/crates/interpreter/src/gas.rs @@ -107,7 +107,7 @@ impl Gas { /// Records an explicit cost. /// /// Returns `false` if the gas limit is exceeded. - #[inline(always)] + #[inline] pub fn record_cost(&mut self, cost: u64) -> bool { let (remaining, overflow) = self.remaining.overflowing_sub(cost); if overflow { diff --git a/crates/interpreter/src/gas/calc.rs b/crates/interpreter/src/gas/calc.rs index dcc949c0..18d0fd70 100644 --- a/crates/interpreter/src/gas/calc.rs +++ b/crates/interpreter/src/gas/calc.rs @@ -1,6 +1,14 @@ +use revm_primitives::Bytes; + use super::constants::*; -use crate::inner_models::SelfDestructResult; -use crate::primitives::{Address, SpecId, U256}; +use crate::{ + primitives::{ + Address, SpecId, + SpecId::{BERLIN, SPURIOUS_DRAGON, TANGERINE}, + U256, + }, + SelfDestructResult, +}; use std::vec::Vec; /// `const` Option `?`. @@ -13,18 +21,9 @@ macro_rules! tri { }; } -/// `const` unwrap. -macro_rules! opt_unwrap { - ($e:expr) => { - match $e { - Some(v) => v, - None => panic!("unwrap failed"), - } - }; -} - /// `SSTORE` opcode refund calculation. #[allow(clippy::collapsible_else_if)] +#[inline] pub fn sstore_refund(spec_id: SpecId, original: U256, current: U256, new: U256) -> i64 { if spec_id.is_enabled_in(SpecId::ISTANBUL) { // EIP-3529: Reduction in refunds @@ -77,17 +76,14 @@ pub fn sstore_refund(spec_id: SpecId, original: U256, current: U256, new: U256) /// `CREATE2` opcode cost calculation. #[inline] pub const fn create2_cost(len: u64) -> Option { - let sha_addup_base = len.div_ceil(32); - let sha_addup = tri!(KECCAK256WORD.checked_mul(sha_addup_base)); - CREATE.checked_add(sha_addup) + CREATE.checked_add(tri!(cost_per_word(len, KECCAK256WORD))) } #[inline] -fn log2floor(value: U256) -> u64 { - assert!(value != U256::ZERO); +const fn log2floor(value: U256) -> u64 { let mut l: u64 = 256; - for i in 0..4 { - let i = 3 - i; + let mut i = 3; + loop { if value.as_limbs()[i] == 0u64 { l -= 64; } else { @@ -98,6 +94,10 @@ fn log2floor(value: U256) -> u64 { return l - 1; } } + if i == 0 { + break; + } + i -= 1; } l } @@ -131,11 +131,7 @@ pub const fn verylowcopy_cost(len: u64) -> Option { #[inline] pub const fn extcodecopy_cost(spec_id: SpecId, len: u64, is_cold: bool) -> Option { let base_gas = if spec_id.is_enabled_in(SpecId::BERLIN) { - if is_cold { - COLD_ACCOUNT_ACCESS_COST - } else { - WARM_STORAGE_READ_COST - } + warm_cold_cost(is_cold) } else if spec_id.is_enabled_in(SpecId::TANGERINE) { 700 } else { @@ -144,22 +140,6 @@ pub const fn extcodecopy_cost(spec_id: SpecId, len: u64, is_cold: bool) -> Optio base_gas.checked_add(tri!(cost_per_word(len, COPY))) } -/// `BALANCE` opcode cost calculation. -#[inline] -pub const fn account_access_gas(spec_id: SpecId, is_cold: bool) -> u64 { - if spec_id.is_enabled_in(SpecId::BERLIN) { - if is_cold { - COLD_ACCOUNT_ACCESS_COST - } else { - WARM_STORAGE_READ_COST - } - } else if spec_id.is_enabled_in(SpecId::ISTANBUL) { - 700 - } else { - 20 - } -} - /// `LOG` opcode cost calculation. #[inline] pub const fn log_cost(n: u8, len: u64) -> Option { @@ -172,10 +152,10 @@ pub const fn keccak256_cost(len: u64) -> Option { KECCAK256.checked_add(tri!(cost_per_word(len, KECCAK256WORD))) } -/// Cost for memory length. `ceil(len / 32) * multiple`. +/// Calculate the cost of buffer per word. #[inline] pub const fn cost_per_word(len: u64, multiple: u64) -> Option { - len.div_ceil(32).checked_mul(multiple) + multiple.checked_mul(len.div_ceil(32)) } /// EIP-3860: Limit and meter initcode @@ -185,7 +165,10 @@ pub const fn cost_per_word(len: u64, multiple: u64) -> Option { /// This cannot overflow as the initcode length is assumed to be checked. #[inline] pub const fn initcode_cost(len: u64) -> u64 { - opt_unwrap!(cost_per_word(len, INITCODE_WORD_COST)) + let Some(cost) = cost_per_word(len, INITCODE_WORD_COST) else { + panic!("initcode cost overflow") + }; + cost } /// `SLOAD` opcode cost calculation. @@ -304,64 +287,59 @@ pub const fn selfdestruct_cost(spec_id: SpecId, res: SelfDestructResult) -> u64 gas } -/// Basic `CALL` opcode cost calculation, see [`call_cost`]. -#[inline] -pub const fn call_gas(spec_id: SpecId, is_cold: bool) -> u64 { - if spec_id.is_enabled_in(SpecId::BERLIN) { - if is_cold { - COLD_ACCOUNT_ACCESS_COST - } else { - WARM_STORAGE_READ_COST - } - } else if spec_id.is_enabled_in(SpecId::TANGERINE) { - // EIP-150: Gas cost changes for IO-heavy operations - 700 - } else { - 40 - } -} - -/// `CALL` opcode cost calculation. +/// Calculate call gas cost for the call instruction. +/// +/// There is three types of gas. +/// * Account access gas. after berlin it can be cold or warm. +/// * Transfer value gas. If value is transferred and balance of target account is updated. +/// * If account is not existing and needs to be created. After Spurious dragon +/// this is only accounted if value is transferred. #[inline] pub const fn call_cost( spec_id: SpecId, transfers_value: bool, - is_new: bool, is_cold: bool, - is_call_or_callcode: bool, - is_call_or_staticcall: bool, + new_account_accounting: bool, ) -> u64 { - call_gas(spec_id, is_cold) - + xfer_cost(is_call_or_callcode, transfers_value) - + new_cost(spec_id, is_call_or_staticcall, is_new, transfers_value) -} - -#[inline] -const fn xfer_cost(is_call_or_callcode: bool, transfers_value: bool) -> u64 { - if is_call_or_callcode && transfers_value { - CALLVALUE + // Account access. + let mut gas = if spec_id.is_enabled_in(BERLIN) { + warm_cold_cost(is_cold) + } else if spec_id.is_enabled_in(TANGERINE) { + // EIP-150: Gas cost changes for IO-heavy operations + 700 } else { - 0 - } -} + 40 + }; -#[inline] -const fn new_cost( - spec_id: SpecId, - is_call_or_staticcall: bool, - is_new: bool, - transfers_value: bool, -) -> u64 { - if !is_call_or_staticcall || !is_new { - return 0; + // transfer value cost + if transfers_value { + gas += CALLVALUE; } - // EIP-161: State trie clearing (invariant-preserving alternative) - if spec_id.is_enabled_in(SpecId::SPURIOUS_DRAGON) && !transfers_value { - return 0; + // new account cost + if new_account_accounting { + // EIP-161: State trie clearing (invariant-preserving alternative) + if spec_id.is_enabled_in(SPURIOUS_DRAGON) { + // account only if there is value transferred. + if transfers_value { + gas += NEWACCOUNT; + } + } else { + gas += NEWACCOUNT; + } } - NEWACCOUNT + gas +} + +/// Berlin warm and cold storage access cost for account access. +#[inline] +pub const fn warm_cold_cost(is_cold: bool) -> u64 { + if is_cold { + COLD_ACCOUNT_ACCESS_COST + } else { + WARM_STORAGE_READ_COST + } } /// Memory expansion cost calculation. @@ -380,10 +358,18 @@ pub fn validate_initial_tx_gas( input: &[u8], is_create: bool, access_list: &[(Address, Vec)], + initcodes: &[Bytes], ) -> u64 { let mut initial_gas = 0; - let zero_data_len = input.iter().filter(|v| **v == 0).count() as u64; - let non_zero_data_len = input.len() as u64 - zero_data_len; + let mut zero_data_len = input.iter().filter(|v| **v == 0).count() as u64; + let mut non_zero_data_len = input.len() as u64 - zero_data_len; + + // Enabling of initcode is checked in `validate_env` handler. + for initcode in initcodes { + let zeros = initcode.iter().filter(|v| **v == 0).count() as u64; + zero_data_len += zeros; + non_zero_data_len += initcode.len() as u64 - zeros; + } // initdate stipend initial_gas += zero_data_len * TRANSACTION_ZERO_DATA; diff --git a/crates/interpreter/src/gas/constants.rs b/crates/interpreter/src/gas/constants.rs index ed3c7aa3..9475e3b3 100644 --- a/crates/interpreter/src/gas/constants.rs +++ b/crates/interpreter/src/gas/constants.rs @@ -1,6 +1,13 @@ pub const ZERO: u64 = 0; pub const BASE: u64 = 2; + pub const VERYLOW: u64 = 3; +pub const DATA_LOADN_GAS: u64 = 3; + +pub const CONDITION_JUMP_GAS: u64 = 4; +pub const RETF_GAS: u64 = 4; +pub const DATA_LOAD_GAS: u64 = 4; + pub const LOW: u64 = 5; pub const MID: u64 = 8; pub const HIGH: u64 = 10; @@ -30,6 +37,8 @@ pub const TRANSACTION_ZERO_DATA: u64 = 4; pub const TRANSACTION_NON_ZERO_DATA_INIT: u64 = 16; pub const TRANSACTION_NON_ZERO_DATA_FRONTIER: u64 = 68; +pub const EOF_CREATE_GAS: u64 = 32000; + // berlin eip2929 constants pub const ACCESS_LIST_ADDRESS: u64 = 2400; pub const ACCESS_LIST_STORAGE_KEY: u64 = 1900; diff --git a/crates/interpreter/src/host.rs b/crates/interpreter/src/host.rs index 6caecee4..49ffbd02 100644 --- a/crates/interpreter/src/host.rs +++ b/crates/interpreter/src/host.rs @@ -1,7 +1,4 @@ -use crate::{ - primitives::{Address, Bytecode, Env, Log, B256, U256}, - SelfDestructResult, -}; +use crate::primitives::{Address, Bytecode, Env, Log, B256, U256}; mod dummy; pub use dummy::DummyHost; @@ -17,7 +14,7 @@ pub trait Host { /// Load an account. /// /// Returns (is_cold, is_new_account) - fn load_account(&mut self, address: Address) -> Option<(bool, bool)>; + fn load_account(&mut self, address: Address) -> Option; /// Get the block hash of the given block `number`. fn block_hash(&mut self, number: U256) -> Option; @@ -66,6 +63,25 @@ pub struct SStoreResult { pub is_cold: bool, } +/// Result of the account load from Journal state. +#[derive(Debug, Clone, Default, PartialEq, Eq)] +pub struct LoadAccountResult { + /// Is account cold loaded + pub is_cold: bool, + /// Is account empty, if true account is not created. + pub is_empty: bool, +} + +/// Result of a selfdestruct instruction. +#[derive(Default, Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SelfDestructResult { + pub had_value: bool, + pub target_exists: bool, + pub is_cold: bool, + pub previously_destroyed: bool, +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/interpreter/src/host/dummy.rs b/crates/interpreter/src/host/dummy.rs index 519d3e06..4a069bfa 100644 --- a/crates/interpreter/src/host/dummy.rs +++ b/crates/interpreter/src/host/dummy.rs @@ -5,6 +5,8 @@ use crate::{ }; use std::vec::Vec; +use super::LoadAccountResult; + /// A dummy [Host] implementation. #[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct DummyHost { @@ -44,8 +46,8 @@ impl Host for DummyHost { } #[inline] - fn load_account(&mut self, _address: Address) -> Option<(bool, bool)> { - Some((true, true)) + fn load_account(&mut self, _address: Address) -> Option { + Some(LoadAccountResult::default()) } #[inline] diff --git a/crates/interpreter/src/inner_models.rs b/crates/interpreter/src/inner_models.rs deleted file mode 100644 index 550fab19..00000000 --- a/crates/interpreter/src/inner_models.rs +++ /dev/null @@ -1,170 +0,0 @@ -pub use crate::primitives::CreateScheme; -use crate::primitives::{Address, Bytes, TransactTo, TxEnv, U256}; -use core::ops::Range; -use std::boxed::Box; - -/// Inputs for a call. -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct CallInputs { - /// The target of the call. - pub contract: Address, - /// The transfer, if any, in this call. - pub transfer: Transfer, - /// The call data of the call. - pub input: Bytes, - /// The gas limit of the call. - pub gas_limit: u64, - /// The context of the call. - pub context: CallContext, - /// Whether this is a static call. - pub is_static: bool, - /// The return memory offset where the output of the call is written. - pub return_memory_offset: Range, -} - -/// Inputs for a create call. -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct CreateInputs { - /// Caller address of the EVM. - pub caller: Address, - /// The create scheme. - pub scheme: CreateScheme, - /// The value to transfer. - pub value: U256, - /// The init code of the contract. - pub init_code: Bytes, - /// The gas limit of the call. - pub gas_limit: u64, -} - -impl CallInputs { - /// Creates new call inputs. - pub fn new(tx_env: &TxEnv, gas_limit: u64) -> Option { - let TransactTo::Call(address) = tx_env.transact_to else { - return None; - }; - - Some(CallInputs { - contract: address, - transfer: Transfer { - source: tx_env.caller, - target: address, - value: tx_env.value, - }, - input: tx_env.data.clone(), - gas_limit, - context: CallContext { - caller: tx_env.caller, - address, - code_address: address, - apparent_value: tx_env.value, - scheme: CallScheme::Call, - }, - is_static: false, - return_memory_offset: 0..0, - }) - } - - /// Returns boxed call inputs. - pub fn new_boxed(tx_env: &TxEnv, gas_limit: u64) -> Option> { - Self::new(tx_env, gas_limit).map(Box::new) - } -} - -impl CreateInputs { - /// Creates new create inputs. - pub fn new(tx_env: &TxEnv, gas_limit: u64) -> Option { - let TransactTo::Create(scheme) = tx_env.transact_to else { - return None; - }; - - Some(CreateInputs { - caller: tx_env.caller, - scheme, - value: tx_env.value, - init_code: tx_env.data.clone(), - gas_limit, - }) - } - - /// Returns boxed create inputs. - pub fn new_boxed(tx_env: &TxEnv, gas_limit: u64) -> Option> { - Self::new(tx_env, gas_limit).map(Box::new) - } - - /// Returns the address that this create call will create. - pub fn created_address(&self, nonce: u64) -> Address { - match self.scheme { - CreateScheme::Create => self.caller.create(nonce), - CreateScheme::Create2 { salt } => self - .caller - .create2_from_code(salt.to_be_bytes(), &self.init_code), - } - } -} - -/// Call schemes. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub enum CallScheme { - /// `CALL`. - Call, - /// `CALLCODE` - CallCode, - /// `DELEGATECALL` - DelegateCall, - /// `STATICCALL` - StaticCall, -} - -/// Context of a runtime call. -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct CallContext { - /// Execution address. - pub address: Address, - /// Caller address of the EVM. - pub caller: Address, - /// The address the contract code was loaded from, if any. - pub code_address: Address, - /// Apparent value of the EVM. - pub apparent_value: U256, - /// The scheme used for the call. - pub scheme: CallScheme, -} - -impl Default for CallContext { - fn default() -> Self { - CallContext { - address: Address::default(), - caller: Address::default(), - code_address: Address::default(), - apparent_value: U256::default(), - scheme: CallScheme::Call, - } - } -} - -/// Transfer from source to target, with given value. -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct Transfer { - /// The source address. - pub source: Address, - /// The target address. - pub target: Address, - /// The transfer value. - pub value: U256, -} - -/// Result of a call that resulted in a self destruct. -#[derive(Default, Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct SelfDestructResult { - pub had_value: bool, - pub target_exists: bool, - pub is_cold: bool, - pub previously_destroyed: bool, -} diff --git a/crates/interpreter/src/instruction_result.rs b/crates/interpreter/src/instruction_result.rs index 13e250ee..9e0f6e12 100644 --- a/crates/interpreter/src/instruction_result.rs +++ b/crates/interpreter/src/instruction_result.rs @@ -10,6 +10,7 @@ pub enum InstructionResult { Stop, Return, SelfDestruct, + ReturnContract, // revert codes Revert = 0x10, // revert opcode @@ -44,9 +45,14 @@ pub enum InstructionResult { CreateContractStartingWithEF, /// EIP-3860: Limit and meter initcode. Initcode size limit exceeded. CreateInitCodeSizeLimit, - /// Fatal external error. Returned by database. FatalExternalError, + /// RETURNCONTRACT called in not init eof code. + ReturnContractInNotInitEOF, + /// Legacy contract is calling opcode that is enabled only in EOF. + EOFOpcodeDisabledInLegacy, + /// EOF function stack overflow + EOFFunctionStackOverflow, } impl From for InstructionResult { @@ -100,6 +106,7 @@ macro_rules! return_ok { | InstructionResult::Stop | InstructionResult::Return | InstructionResult::SelfDestruct + | InstructionResult::ReturnContract }; } @@ -135,6 +142,9 @@ macro_rules! return_error { | InstructionResult::CreateContractStartingWithEF | InstructionResult::CreateInitCodeSizeLimit | InstructionResult::FatalExternalError + | InstructionResult::ReturnContractInNotInitEOF + | InstructionResult::EOFOpcodeDisabledInLegacy + | InstructionResult::EOFFunctionStackOverflow }; } @@ -230,7 +240,9 @@ impl From for SuccessOrHalt { InstructionResult::InvalidOperandOOG => { Self::Halt(HaltReason::OutOfGas(OutOfGasError::InvalidOperand)) } - InstructionResult::OpcodeNotFound => Self::Halt(HaltReason::OpcodeNotFound), + InstructionResult::OpcodeNotFound | InstructionResult::ReturnContractInNotInitEOF => { + Self::Halt(HaltReason::OpcodeNotFound) + } InstructionResult::CallNotAllowedInsideStatic => { Self::Halt(HaltReason::CallNotAllowedInsideStatic) } // first call is not static call @@ -255,6 +267,11 @@ impl From for SuccessOrHalt { Self::Halt(HaltReason::CreateInitCodeSizeLimit) } InstructionResult::FatalExternalError => Self::FatalExternalError, + InstructionResult::EOFOpcodeDisabledInLegacy => Self::Halt(HaltReason::OpcodeNotFound), + InstructionResult::EOFFunctionStackOverflow => Self::FatalExternalError, + InstructionResult::ReturnContract => { + panic!("Unexpected EOF internal Return Contract") + } } } } diff --git a/crates/interpreter/src/instructions.rs b/crates/interpreter/src/instructions.rs index ae560156..7f11f93f 100644 --- a/crates/interpreter/src/instructions.rs +++ b/crates/interpreter/src/instructions.rs @@ -2,16 +2,15 @@ #[macro_use] pub mod macros; - pub mod arithmetic; pub mod bitwise; +pub mod contract; pub mod control; +pub mod data; pub mod host; pub mod host_env; pub mod i256; pub mod memory; -pub mod opcode; pub mod stack; pub mod system; - -pub use opcode::{Instruction, OpCode, OPCODE_JUMPMAP}; +pub mod utility; diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs new file mode 100644 index 00000000..4d3924be --- /dev/null +++ b/crates/interpreter/src/instructions/contract.rs @@ -0,0 +1,638 @@ +mod call_helpers; + +pub use call_helpers::{ + calc_call_gas, get_memory_input_and_out_ranges, resize_memory_and_return_range, +}; +use revm_primitives::{keccak256, BerlinSpec}; + +use crate::{ + analysis::validate_eof, + gas::{self, cost_per_word, BASE, EOF_CREATE_GAS, KECCAK256WORD}, + instructions::utility::read_u16, + interpreter::Interpreter, + primitives::{Address, Bytes, Eof, Spec, SpecId::*, B256, U256}, + CallInputs, CallScheme, CreateInputs, CreateScheme, EOFCreateInput, Host, InstructionResult, + InterpreterAction, InterpreterResult, LoadAccountResult, TransferValue, MAX_INITCODE_SIZE, +}; +use core::{cmp::max, ops::Range}; +use std::boxed::Box; + +/// Resize memory and return memory range if successful. +/// Return `None` if there is not enough gas. And if `len` +/// is zero return `Some(usize::MAX..usize::MAX)`. +pub fn resize_memory( + interpreter: &mut Interpreter, + offset: U256, + len: U256, +) -> Option> { + let len = as_usize_or_fail_ret!(interpreter, len, None); + if len != 0 { + let offset = as_usize_or_fail_ret!(interpreter, offset, None); + resize_memory!(interpreter, offset, len, None); + // range is checked in resize_memory! macro and it is bounded by usize. + Some(offset..offset + len) + } else { + //unrealistic value so we are sure it is not used + Some(usize::MAX..usize::MAX) + } +} + +/// EOF Create instruction +pub fn eofcreate(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); + gas!(interpreter, EOF_CREATE_GAS); + let initcontainer_index = unsafe { *interpreter.instruction_pointer }; + pop!(interpreter, value, salt, data_offset, data_size); + + let sub_container = interpreter + .eof() + .expect("EOF is set") + .body + .container_section + .get(initcontainer_index as usize) + .cloned() + .expect("EOF is checked"); + + // resize memory and get return range. + let Some(return_range) = resize_memory(interpreter, data_offset, data_size) else { + return; + }; + + let eof = Eof::decode(sub_container.clone()).expect("Subcontainer is verified"); + + if !eof.body.is_data_filled { + // should be always false as it is verified by eof verification. + panic!("Panic if data section is not full"); + } + + // deduct gas for hash that is needed to calculate address. + gas_or_fail!( + interpreter, + cost_per_word(sub_container.len() as u64, KECCAK256WORD) + ); + + let created_address = interpreter + .contract + .caller + .create2(salt.to_be_bytes(), keccak256(sub_container)); + + // Send container for execution container is preverified. + interpreter.next_action = InterpreterAction::EOFCreate { + inputs: Box::new(EOFCreateInput::new( + interpreter.contract.target_address, + created_address, + value, + eof, + interpreter.gas().remaining(), + return_range, + )), + }; + + interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(1) }; +} + +pub fn txcreate(interpreter: &mut Interpreter, host: &mut H) { + error_on_disabled_eof!(interpreter); + gas!(interpreter, EOF_CREATE_GAS); + pop!( + interpreter, + tx_initcode_hash, + value, + salt, + data_offset, + data_size + ); + let tx_initcode_hash = B256::from(tx_initcode_hash); + + // resize memory and get return range. + let Some(return_range) = resize_memory(interpreter, data_offset, data_size) else { + return; + }; + + // fetch initcode, if not found push ZERO. + let Some(initcode) = host + .env() + .tx + .eof_initcodes_hashed + .get(&tx_initcode_hash) + .cloned() + else { + push!(interpreter, U256::ZERO); + return; + }; + + // deduct gas for validation + gas_or_fail!(interpreter, cost_per_word(initcode.len() as u64, BASE)); + + // deduct gas for hash. TODO check order of actions. + gas_or_fail!( + interpreter, + cost_per_word(initcode.len() as u64, KECCAK256WORD) + ); + + let Ok(eof) = Eof::decode(initcode.clone()) else { + push!(interpreter, U256::ZERO); + return; + }; + + // Data section should be full, push zero to stack and return if not. + if !eof.body.is_data_filled { + push!(interpreter, U256::ZERO); + return; + } + + // Validate initcode + if validate_eof(&eof).is_err() { + push!(interpreter, U256::ZERO); + return; + } + + // Create new address. Gas for it is already deducted. + let created_address = interpreter + .contract + .caller + .create2(salt.to_be_bytes(), tx_initcode_hash); + + let gas_limit = interpreter.gas().remaining(); + // spend all gas. It will be reimbursed after frame returns. + gas!(interpreter, gas_limit); + + interpreter.next_action = InterpreterAction::EOFCreate { + inputs: Box::new(EOFCreateInput::new( + interpreter.contract.target_address, + created_address, + value, + eof, + gas_limit, + return_range, + )), + }; + interpreter.instruction_result = InstructionResult::CallOrCreate; +} + +pub fn return_contract(interpreter: &mut Interpreter, _host: &mut H) { + error_on_not_init_eof!(interpreter); + let deploy_container_index = unsafe { read_u16(interpreter.instruction_pointer) }; + pop!(interpreter, aux_data_offset, aux_data_size); + let aux_data_size = as_usize_or_fail!(interpreter, aux_data_size); + // important: offset must be ignored if len is zeros + let container = interpreter + .eof() + .expect("EOF is set") + .body + .container_section + .get(deploy_container_index as usize) + .expect("EOF is checked"); + + // convert to EOF so we can check data section size. + let new_eof = Eof::decode(container.clone()).expect("Container is verified"); + + let aux_slice = if aux_data_size != 0 { + let aux_data_offset = as_usize_or_fail!(interpreter, aux_data_offset); + resize_memory!(interpreter, aux_data_offset, aux_data_size); + + interpreter + .shared_memory + .slice(aux_data_offset, aux_data_size) + } else { + &[] + }; + + let new_data_size = new_eof.body.data_section.len() + aux_slice.len(); + if new_data_size > 0xFFFF { + // aux data is too big + interpreter.instruction_result = InstructionResult::FatalExternalError; + return; + } + if new_data_size < new_eof.header.data_size as usize { + // aux data is too small + interpreter.instruction_result = InstructionResult::FatalExternalError; + return; + } + + // append data bytes + let output = [new_eof.raw(), aux_slice].concat().into(); + + let result = InstructionResult::ReturnContract; + interpreter.instruction_result = result; + interpreter.next_action = crate::InterpreterAction::Return { + result: InterpreterResult { + output, + gas: interpreter.gas, + result, + }, + }; +} + +pub fn extcall_input(interpreter: &mut Interpreter) -> Option { + pop_ret!(interpreter, input_offset, input_size, None); + + let return_memory_offset = + resize_memory_and_return_range(interpreter, input_offset, input_size)?; + + Some(Bytes::copy_from_slice( + interpreter + .shared_memory + .slice_range(return_memory_offset.clone()), + )) +} + +pub fn extcall_gas_calc( + interpreter: &mut Interpreter, + host: &mut H, + target: Address, + transfers_value: bool, +) -> Option { + let Some(load_result) = host.load_account(target) else { + interpreter.instruction_result = InstructionResult::FatalExternalError; + return None; + }; + + if load_result.is_cold { + gas!(interpreter, gas::COLD_ACCOUNT_ACCESS_COST, None); + } + + // TODO(EOF) is_empty should only be checked on delegatecall + let call_cost = gas::call_cost( + BerlinSpec::SPEC_ID, + transfers_value, + load_result.is_cold, + load_result.is_empty, + ); + gas!(interpreter, call_cost, None); + + // 7. Calculate the gas available to callee as caller’s + // remaining gas reduced by max(ceil(gas/64), MIN_RETAINED_GAS) (MIN_RETAINED_GAS is 5000). + let gas_reduce = max(interpreter.gas.remaining() / 64, 5000); + let gas_limit = interpreter.gas().remaining().saturating_sub(gas_reduce); + + if gas_limit < 2300 { + interpreter.instruction_result = InstructionResult::CallNotAllowedInsideStatic; + // TODO(EOF) error; + // interpreter.instruction_result = InstructionResult::CallGasTooLow; + return None; + } + + // TODO check remaining gas more then N + + gas!(interpreter, gas_limit, None); + Some(gas_limit) +} + +pub fn extcall(interpreter: &mut Interpreter, host: &mut H) { + error_on_disabled_eof!(interpreter); + pop_address!(interpreter, target_address); + + // input call + let Some(input) = extcall_input(interpreter) else { + return; + }; + + pop!(interpreter, value); + let has_transfer = value != U256::ZERO; + + let Some(gas_limit) = extcall_gas_calc(interpreter, host, target_address, has_transfer) else { + return; + }; + // TODO Check if static and value 0 + + // Call host to interact with target contract + interpreter.next_action = InterpreterAction::Call { + inputs: Box::new(CallInputs { + input, + gas_limit, + target_address, + caller: interpreter.contract.target_address, + bytecode_address: target_address, + value: TransferValue::Value(value), + scheme: CallScheme::Call, + is_static: interpreter.is_static, + is_eof: true, + return_memory_offset: 0..0, + }), + }; + interpreter.instruction_result = InstructionResult::CallOrCreate; +} + +pub fn extdcall(interpreter: &mut Interpreter, host: &mut H) { + error_on_disabled_eof!(interpreter); + pop_address!(interpreter, target_address); + + // input call + let Some(input) = extcall_input(interpreter) else { + return; + }; + + let Some(gas_limit) = extcall_gas_calc(interpreter, host, target_address, false) else { + return; + }; + // TODO Check if static and value 0 + + // Call host to interact with target contract + interpreter.next_action = InterpreterAction::Call { + inputs: Box::new(CallInputs { + input, + gas_limit, + target_address, + caller: interpreter.contract.target_address, + bytecode_address: target_address, + value: TransferValue::ApparentValue(interpreter.contract.call_value), + // TODO(EOF) should be EofDelegateCall? + scheme: CallScheme::DelegateCall, + is_static: interpreter.is_static, + is_eof: true, + return_memory_offset: 0..0, + }), + }; + interpreter.instruction_result = InstructionResult::CallOrCreate; +} + +pub fn extscall(interpreter: &mut Interpreter, host: &mut H) { + error_on_disabled_eof!(interpreter); + pop_address!(interpreter, target_address); + + // input call + let Some(input) = extcall_input(interpreter) else { + return; + }; + + let Some(gas_limit) = extcall_gas_calc(interpreter, host, target_address, false) else { + return; + }; + + // Call host to interact with target contract + interpreter.next_action = InterpreterAction::Call { + inputs: Box::new(CallInputs { + input, + gas_limit, + target_address, + caller: interpreter.contract.target_address, + bytecode_address: target_address, + value: TransferValue::Value(U256::ZERO), + scheme: CallScheme::Call, + is_static: interpreter.is_static, + is_eof: true, + return_memory_offset: 0..0, + }), + }; + interpreter.instruction_result = InstructionResult::CallOrCreate; +} + +pub fn create( + interpreter: &mut Interpreter, + host: &mut H, +) { + error_on_static_call!(interpreter); + + // EIP-1014: Skinny CREATE2 + if IS_CREATE2 { + check!(interpreter, PETERSBURG); + } + + pop!(interpreter, value, code_offset, len); + let len = as_usize_or_fail!(interpreter, len); + + let mut code = Bytes::new(); + if len != 0 { + // EIP-3860: Limit and meter initcode + if SPEC::enabled(SHANGHAI) { + // Limit is set as double of max contract bytecode size + let max_initcode_size = host + .env() + .cfg + .limit_contract_code_size + .map(|limit| limit.saturating_mul(2)) + .unwrap_or(MAX_INITCODE_SIZE); + if len > max_initcode_size { + interpreter.instruction_result = InstructionResult::CreateInitCodeSizeLimit; + return; + } + gas!(interpreter, gas::initcode_cost(len as u64)); + } + + let code_offset = as_usize_or_fail!(interpreter, code_offset); + resize_memory!(interpreter, code_offset, len); + code = Bytes::copy_from_slice(interpreter.shared_memory.slice(code_offset, len)); + } + + // EIP-1014: Skinny CREATE2 + let scheme = if IS_CREATE2 { + pop!(interpreter, salt); + // SAFETY: len is reasonable in size as gas for it is already deducted. + gas_or_fail!(interpreter, gas::create2_cost(len.try_into().unwrap())); + CreateScheme::Create2 { salt } + } else { + gas!(interpreter, gas::CREATE); + CreateScheme::Create + }; + + let mut gas_limit = interpreter.gas().remaining(); + + // EIP-150: Gas cost changes for IO-heavy operations + if SPEC::enabled(TANGERINE) { + // take remaining gas and deduce l64 part of it. + gas_limit -= gas_limit / 64 + } + gas!(interpreter, gas_limit); + + // Call host to interact with target contract + interpreter.next_action = InterpreterAction::Create { + inputs: Box::new(CreateInputs { + caller: interpreter.contract.target_address, + scheme, + value, + init_code: code, + gas_limit, + }), + }; + interpreter.instruction_result = InstructionResult::CallOrCreate; +} + +pub fn call(interpreter: &mut Interpreter, host: &mut H) { + pop!(interpreter, local_gas_limit); + pop_address!(interpreter, to); + // max gas limit is not possible in real ethereum situation. + let local_gas_limit = u64::try_from(local_gas_limit).unwrap_or(u64::MAX); + + pop!(interpreter, value); + let has_transfer = value != U256::ZERO; + if interpreter.is_static && has_transfer { + interpreter.instruction_result = InstructionResult::CallNotAllowedInsideStatic; + return; + } + + let Some((input, return_memory_offset)) = get_memory_input_and_out_ranges(interpreter) else { + return; + }; + + let Some(LoadAccountResult { is_cold, is_empty }) = host.load_account(to) else { + interpreter.instruction_result = InstructionResult::FatalExternalError; + return; + }; + let Some(mut gas_limit) = calc_call_gas::( + interpreter, + is_cold, + has_transfer, + is_empty, + local_gas_limit, + ) else { + return; + }; + + gas!(interpreter, gas_limit); + + // add call stipend if there is value to be transferred. + if has_transfer { + gas_limit = gas_limit.saturating_add(gas::CALL_STIPEND); + } + + // Call host to interact with target contract + interpreter.next_action = InterpreterAction::Call { + inputs: Box::new(CallInputs { + input, + gas_limit, + target_address: to, + caller: interpreter.contract.target_address, + bytecode_address: to, + value: TransferValue::Value(value), + scheme: CallScheme::Call, + is_static: interpreter.is_static, + is_eof: false, + return_memory_offset, + }), + }; + interpreter.instruction_result = InstructionResult::CallOrCreate; +} + +pub fn call_code(interpreter: &mut Interpreter, host: &mut H) { + pop!(interpreter, local_gas_limit); + pop_address!(interpreter, to); + // max gas limit is not possible in real ethereum situation. + let local_gas_limit = u64::try_from(local_gas_limit).unwrap_or(u64::MAX); + + pop!(interpreter, value); + let Some((input, return_memory_offset)) = get_memory_input_and_out_ranges(interpreter) else { + return; + }; + + let Some(LoadAccountResult { is_cold, .. }) = host.load_account(to) else { + interpreter.instruction_result = InstructionResult::FatalExternalError; + return; + }; + + let Some(mut gas_limit) = calc_call_gas::( + interpreter, + is_cold, + value != U256::ZERO, + false, + local_gas_limit, + ) else { + return; + }; + + gas!(interpreter, gas_limit); + + // add call stipend if there is value to be transferred. + if value != U256::ZERO { + gas_limit = gas_limit.saturating_add(gas::CALL_STIPEND); + } + + // Call host to interact with target contract + interpreter.next_action = InterpreterAction::Call { + inputs: Box::new(CallInputs { + input, + gas_limit, + target_address: interpreter.contract.target_address, + caller: interpreter.contract.target_address, + bytecode_address: to, + value: TransferValue::Value(value), + scheme: CallScheme::CallCode, + is_static: interpreter.is_static, + is_eof: false, + return_memory_offset, + }), + }; + interpreter.instruction_result = InstructionResult::CallOrCreate; +} + +pub fn delegate_call(interpreter: &mut Interpreter, host: &mut H) { + check!(interpreter, HOMESTEAD); + pop!(interpreter, local_gas_limit); + pop_address!(interpreter, to); + // max gas limit is not possible in real ethereum situation. + let local_gas_limit = u64::try_from(local_gas_limit).unwrap_or(u64::MAX); + + let Some((input, return_memory_offset)) = get_memory_input_and_out_ranges(interpreter) else { + return; + }; + + let Some(LoadAccountResult { is_cold, .. }) = host.load_account(to) else { + interpreter.instruction_result = InstructionResult::FatalExternalError; + return; + }; + let Some(gas_limit) = + calc_call_gas::(interpreter, is_cold, false, false, local_gas_limit) + else { + return; + }; + + gas!(interpreter, gas_limit); + + // Call host to interact with target contract + interpreter.next_action = InterpreterAction::Call { + inputs: Box::new(CallInputs { + input, + gas_limit, + target_address: interpreter.contract.target_address, + caller: interpreter.contract.caller, + bytecode_address: to, + value: TransferValue::ApparentValue(interpreter.contract.call_value), + scheme: CallScheme::DelegateCall, + is_static: interpreter.is_static, + is_eof: false, + return_memory_offset, + }), + }; + interpreter.instruction_result = InstructionResult::CallOrCreate; +} + +pub fn static_call(interpreter: &mut Interpreter, host: &mut H) { + check!(interpreter, BYZANTIUM); + pop!(interpreter, local_gas_limit); + pop_address!(interpreter, to); + // max gas limit is not possible in real ethereum situation. + let local_gas_limit = u64::try_from(local_gas_limit).unwrap_or(u64::MAX); + + let Some((input, return_memory_offset)) = get_memory_input_and_out_ranges(interpreter) else { + return; + }; + + let Some(LoadAccountResult { is_cold, .. }) = host.load_account(to) else { + interpreter.instruction_result = InstructionResult::FatalExternalError; + return; + }; + + let Some(gas_limit) = + calc_call_gas::(interpreter, is_cold, false, false, local_gas_limit) + else { + return; + }; + gas!(interpreter, gas_limit); + + // Call host to interact with target contract + interpreter.next_action = InterpreterAction::Call { + inputs: Box::new(CallInputs { + input, + gas_limit, + target_address: to, + caller: interpreter.contract.target_address, + bytecode_address: to, + value: TransferValue::Value(U256::ZERO), + scheme: CallScheme::StaticCall, + is_static: true, + is_eof: false, + return_memory_offset, + }), + }; + interpreter.instruction_result = InstructionResult::CallOrCreate; +} diff --git a/crates/interpreter/src/instructions/contract/call_helpers.rs b/crates/interpreter/src/instructions/contract/call_helpers.rs new file mode 100644 index 00000000..ae8b9ed6 --- /dev/null +++ b/crates/interpreter/src/instructions/contract/call_helpers.rs @@ -0,0 +1,69 @@ +use revm_primitives::U256; + +use crate::{ + gas, + interpreter::Interpreter, + primitives::{Bytes, Spec, SpecId::*}, + Host, +}; +use core::{cmp::min, ops::Range}; + +#[inline] +pub fn get_memory_input_and_out_ranges( + interpreter: &mut Interpreter, +) -> Option<(Bytes, Range)> { + pop_ret!(interpreter, in_offset, in_len, out_offset, out_len, None); + + let in_range = resize_memory_and_return_range(interpreter, in_offset, in_len)?; + + let mut input = Bytes::new(); + if !in_range.is_empty() { + input = Bytes::copy_from_slice(interpreter.shared_memory.slice_range(in_range)); + } + + let ret_range = resize_memory_and_return_range(interpreter, out_offset, out_len)?; + Some((input, ret_range)) +} + +/// Resize memory and return range of memory. +/// If `len` is 0 dont touch memory and return `usize::MAX` as offset and 0 as length. +#[inline] +pub fn resize_memory_and_return_range( + interpreter: &mut Interpreter, + offset: U256, + len: U256, +) -> Option> { + let len = as_usize_or_fail_ret!(interpreter, len, None); + let offset = if len != 0 { + let offset = as_usize_or_fail_ret!(interpreter, offset, None); + resize_memory!(interpreter, offset, len, None); + offset + } else { + usize::MAX //unrealistic value so we are sure it is not used + }; + Some(offset..offset + len) +} + +#[inline] +pub fn calc_call_gas( + interpreter: &mut Interpreter, + is_cold: bool, + has_transfer: bool, + new_account_accounting: bool, + local_gas_limit: u64, +) -> Option { + let call_cost = gas::call_cost(SPEC::SPEC_ID, has_transfer, is_cold, new_account_accounting); + + gas!(interpreter, call_cost, None); + + // EIP-150: Gas cost changes for IO-heavy operations + let gas_limit = if SPEC::enabled(TANGERINE) { + let gas = interpreter.gas().remaining(); + // take l64 part of gas_limit + min(gas - gas / 64, local_gas_limit) + } else { + local_gas_limit + }; + + Some(gas_limit) +} diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index 7e0df530..02e2de7d 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -1,9 +1,58 @@ +use super::utility::{read_i16, read_u16}; use crate::{ gas, primitives::{Bytes, Spec, U256}, Host, InstructionResult, Interpreter, InterpreterResult, }; +pub fn rjump(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); + gas!(interpreter, gas::BASE); + let offset = unsafe { read_i16(interpreter.instruction_pointer) } as isize; + // In spec it is +3 but pointer is already incremented in + // `Interpreter::step` so for revm is +2. + interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(offset + 2) }; +} + +pub fn rjumpi(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); + gas!(interpreter, gas::CONDITION_JUMP_GAS); + pop!(interpreter, condition); + // In spec it is +3 but pointer is already incremented in + // `Interpreter::step` so for revm is +2. + let mut offset = 2; + if !condition.is_zero() { + offset += unsafe { read_i16(interpreter.instruction_pointer) } as isize; + } + + interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(offset) }; +} + +pub fn rjumpv(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); + gas!(interpreter, gas::CONDITION_JUMP_GAS); + pop!(interpreter, case); + let case = as_isize_saturated!(case); + + let max_index = unsafe { *interpreter.instruction_pointer } as isize; + // for number of items we are adding 1 to max_index, multiply by 2 as each offset is 2 bytes + // and add 1 for max_index itself. Note that revm already incremented the instruction pointer + let mut offset = (max_index + 1) * 2 + 1; + + if case <= max_index { + offset += unsafe { + read_i16( + interpreter + .instruction_pointer + // offset for max_index that is one byte + .offset(1 + case * 2), + ) + } as isize; + } + + interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(offset) }; +} + pub fn jump(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::MID); pop!(interpreter, target); @@ -18,7 +67,7 @@ pub fn jumpi(interpreter: &mut Interpreter, _host: &mut H) { } } -#[inline(always)] +#[inline] fn jump_inner(interpreter: &mut Interpreter, target: U256) { let target = as_usize_or_fail!(interpreter, target, InstructionResult::InvalidJump); if !interpreter.contract.is_valid_jump(target) { @@ -26,20 +75,64 @@ fn jump_inner(interpreter: &mut Interpreter, target: U256) { return; } // SAFETY: `is_valid_jump` ensures that `dest` is in bounds. - interpreter.instruction_pointer = unsafe { interpreter.contract.bytecode.as_ptr().add(target) }; + interpreter.instruction_pointer = unsafe { interpreter.bytecode.as_ptr().add(target) }; } -pub fn jumpdest(interpreter: &mut Interpreter, _host: &mut H) { +pub fn jumpdest_or_nop(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::JUMPDEST); } +pub fn callf(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); + gas!(interpreter, gas::LOW); + + let idx = unsafe { read_u16(interpreter.instruction_pointer) } as usize; + // TODO Check stack with EOF types. + + if interpreter.function_stack.return_stack_len() == 1024 { + interpreter.instruction_result = InstructionResult::EOFFunctionStackOverflow; + return; + } + + // push current idx and PC to the callf stack. + // PC is incremented by 2 to point to the next instruction after callf. + interpreter + .function_stack + .push(interpreter.program_counter() + 2, idx); + + interpreter.load_eof_code(idx, 0) +} + +pub fn retf(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); + gas!(interpreter, gas::RETF_GAS); + + let Some(fframe) = interpreter.function_stack.pop() else { + panic!("Expected function frame") + }; + + interpreter.load_eof_code(fframe.idx, fframe.pc); +} + +pub fn jumpf(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); + gas!(interpreter, gas::LOW); + + let idx = unsafe { read_u16(interpreter.instruction_pointer) } as usize; + + // TODO(EOF) do types stack checks + + interpreter.function_stack.set_current_code_idx(idx); + interpreter.load_eof_code(idx, 0) +} + pub fn pc(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); // - 1 because we have already advanced the instruction pointer in `Interpreter::step` push!(interpreter, U256::from(interpreter.program_counter() - 1)); } -#[inline(always)] +#[inline] fn return_inner(interpreter: &mut Interpreter, instruction_result: InstructionResult) { // zero gas cost // gas!(interpreter, gas::ZERO); @@ -87,3 +180,152 @@ pub fn invalid(interpreter: &mut Interpreter, _host: &mut H) { pub fn unknown(interpreter: &mut Interpreter, _host: &mut H) { interpreter.instruction_result = InstructionResult::OpcodeNotFound; } + +#[cfg(test)] +mod test { + use revm_primitives::{bytes, Bytecode, Eof, PragueSpec}; + + use super::*; + use crate::{ + opcode::{make_instruction_table, CALLF, JUMPF, NOP, RETF, RJUMP, RJUMPI, RJUMPV, STOP}, + DummyHost, FunctionReturnFrame, Gas, Interpreter, + }; + + #[test] + fn rjump() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + let mut interp = Interpreter::new_bytecode(Bytecode::LegacyRaw(Bytes::from([ + RJUMP, 0x00, 0x02, STOP, STOP, + ]))); + interp.is_eof = true; + interp.gas = Gas::new(10000); + + interp.step(&table, &mut host); + assert_eq!(interp.program_counter(), 5); + } + + #[test] + fn rjumpi() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + let mut interp = Interpreter::new_bytecode(Bytecode::LegacyRaw(Bytes::from([ + RJUMPI, 0x00, 0x03, RJUMPI, 0x00, 0x01, STOP, STOP, + ]))); + interp.is_eof = true; + interp.stack.push(U256::from(1)).unwrap(); + interp.stack.push(U256::from(0)).unwrap(); + interp.gas = Gas::new(10000); + + // dont jump + interp.step(&table, &mut host); + assert_eq!(interp.program_counter(), 3); + // jumps to last opcode + interp.step(&table, &mut host); + assert_eq!(interp.program_counter(), 7); + } + + #[test] + fn rjumpv() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + let mut interp = Interpreter::new_bytecode(Bytecode::LegacyRaw(Bytes::from([ + RJUMPV, + 0x01, // max index, 0 and 1 + 0x00, // first x0001 + 0x01, + 0x00, // second 0x002 + 0x02, + NOP, + NOP, + NOP, + RJUMP, + 0xFF, + (-12i8) as u8, + STOP, + ]))); + interp.is_eof = true; + interp.gas = Gas::new(1000); + + // more then max_index + interp.stack.push(U256::from(10)).unwrap(); + interp.step(&table, &mut host); + assert_eq!(interp.program_counter(), 6); + + // cleanup + interp.step(&table, &mut host); + interp.step(&table, &mut host); + interp.step(&table, &mut host); + interp.step(&table, &mut host); + assert_eq!(interp.program_counter(), 0); + + // jump to first index of vtable + interp.stack.push(U256::from(0)).unwrap(); + interp.step(&table, &mut host); + assert_eq!(interp.program_counter(), 7); + + // cleanup + interp.step(&table, &mut host); + interp.step(&table, &mut host); + interp.step(&table, &mut host); + assert_eq!(interp.program_counter(), 0); + + // jump to second index of vtable + interp.stack.push(U256::from(1)).unwrap(); + interp.step(&table, &mut host); + assert_eq!(interp.program_counter(), 8); + } + + fn dummy_eof() -> Eof { + let bytes = bytes!("ef000101000402000100010400000000800000fe"); + Eof::decode(bytes).unwrap() + } + + #[test] + fn callf_retf_jumpf() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + let mut eof = dummy_eof(); + + eof.body.code_section.clear(); + eof.header.code_sizes.clear(); + + let bytes1 = Bytes::from([CALLF, 0x00, 0x01, JUMPF, 0x00, 0x01]); + eof.header.code_sizes.push(bytes1.len() as u16); + eof.body.code_section.push(bytes1.clone()); + let bytes2 = Bytes::from([STOP, RETF]); + eof.header.code_sizes.push(bytes2.len() as u16); + eof.body.code_section.push(bytes2.clone()); + + let mut interp = Interpreter::new_bytecode(Bytecode::Eof(eof)); + interp.gas = Gas::new(10000); + + assert_eq!(interp.function_stack.current_code_idx, 0); + assert!(interp.function_stack.return_stack.is_empty()); + + // CALLF + interp.step(&table, &mut host); + + assert_eq!(interp.function_stack.current_code_idx, 1); + assert_eq!( + interp.function_stack.return_stack[0], + FunctionReturnFrame::new(0, 3) + ); + assert_eq!(interp.instruction_pointer, bytes2.as_ptr()); + + // STOP + interp.step(&table, &mut host); + // RETF + interp.step(&table, &mut host); + + assert_eq!(interp.function_stack.current_code_idx, 0); + assert_eq!(interp.function_stack.return_stack, Vec::new()); + assert_eq!(interp.program_counter(), 3); + + // JUMPF + interp.step(&table, &mut host); + assert_eq!(interp.function_stack.current_code_idx, 1); + assert_eq!(interp.function_stack.return_stack, Vec::new()); + assert_eq!(interp.instruction_pointer, bytes2.as_ptr()); + } +} diff --git a/crates/interpreter/src/instructions/data.rs b/crates/interpreter/src/instructions/data.rs new file mode 100644 index 00000000..1475d24c --- /dev/null +++ b/crates/interpreter/src/instructions/data.rs @@ -0,0 +1,214 @@ +use crate::{ + gas::{BASE, DATA_LOAD_GAS, VERYLOW}, + instructions::utility::read_u16, + interpreter::Interpreter, + primitives::U256, + Host, +}; + +pub fn data_load(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); + gas!(interpreter, DATA_LOAD_GAS); + pop_top!(interpreter, offset); + + let offset_usize = as_usize_saturated!(offset); + + let slice = interpreter + .contract + .bytecode + .eof() + .expect("eof") + .data_slice(offset_usize, 32); + + let mut word = [0u8; 32]; + word[..slice.len()].copy_from_slice(slice); + + *offset = U256::from_be_bytes(word); +} + +pub fn data_loadn(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); + gas!(interpreter, VERYLOW); + let offset = unsafe { read_u16(interpreter.instruction_pointer) } as usize; + + let slice = interpreter + .contract + .bytecode + .eof() + .expect("eof") + .data_slice(offset, 32); + + let mut word = [0u8; 32]; + word[..slice.len()].copy_from_slice(slice); + + push_b256!(interpreter, word.into()); + + // add +2 to the instruction pointer to skip the offset + interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(2) }; +} + +pub fn data_size(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); + gas!(interpreter, BASE); + let data_size = interpreter.eof().expect("eof").header.data_size; + + push!(interpreter, U256::from(data_size)); +} + +pub fn data_copy(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); + gas!(interpreter, VERYLOW); + pop!(interpreter, mem_offset, offset, size); + + // sizes more than u64::MAX will spend all the gas in memmory resize. + let size = as_usize_or_fail!(interpreter, size); + // size of zero should not change the memory + if size == 0 { + return; + } + // fail if mem offset is big as it will spend all the gas + let mem_offset = as_usize_or_fail!(interpreter, mem_offset); + resize_memory!(interpreter, mem_offset, size); + + let offset = as_usize_saturated!(offset); + let data = interpreter.contract.bytecode.eof().expect("EOF").data(); + + // set data from the eof to the shared memory. Padd it with zeros. + interpreter + .shared_memory + .set_data(mem_offset, offset, size, data); +} + +#[cfg(test)] +mod test { + use revm_primitives::{b256, bytes, Bytecode, Bytes, Eof, PragueSpec}; + + use super::*; + use crate::{ + opcode::{make_instruction_table, DATACOPY, DATALOAD, DATALOADN, DATASIZE}, + DummyHost, Gas, Interpreter, + }; + + fn dummy_eof(code_bytes: Bytes) -> Bytecode { + let bytes = bytes!("ef000101000402000100010400000000800000fe"); + let mut eof = Eof::decode(bytes).unwrap(); + + eof.body.data_section = + bytes!("000000000000000000000000000000000000000000000000000000000000000102030405"); + eof.header.data_size = eof.body.data_section.len() as u16; + + eof.header.code_sizes[0] = code_bytes.len() as u16; + eof.body.code_section[0] = code_bytes; + Bytecode::Eof(eof) + } + + #[test] + fn dataload_dataloadn() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + let eof = dummy_eof(Bytes::from([ + DATALOAD, DATALOADN, 0x00, 0x00, DATALOAD, DATALOADN, 0x00, 35, DATALOAD, DATALOADN, + 0x00, 36, DATASIZE, + ])); + + let mut interp = Interpreter::new_bytecode(eof); + interp.gas = Gas::new(10000); + + // DATALOAD + interp.stack.push(U256::from(0)).unwrap(); + interp.step(&table, &mut host); + assert_eq!(interp.stack.data(), &vec![U256::from(0x01)]); + interp.stack.pop().unwrap(); + + // DATALOADN + interp.step(&table, &mut host); + assert_eq!(interp.stack.data(), &vec![U256::from(0x01)]); + interp.stack.pop().unwrap(); + + // DATALOAD (padding) + interp.stack.push(U256::from(35)).unwrap(); + interp.step(&table, &mut host); + assert_eq!( + interp.stack.data(), + &vec![b256!("0500000000000000000000000000000000000000000000000000000000000000").into()] + ); + interp.stack.pop().unwrap(); + + // DATALOADN (padding) + interp.step(&table, &mut host); + assert_eq!( + interp.stack.data(), + &vec![b256!("0500000000000000000000000000000000000000000000000000000000000000").into()] + ); + interp.stack.pop().unwrap(); + + // DATALOAD (out of bounds) + interp.stack.push(U256::from(36)).unwrap(); + interp.step(&table, &mut host); + assert_eq!(interp.stack.data(), &vec![U256::ZERO]); + interp.stack.pop().unwrap(); + + // DATALOADN (out of bounds) + interp.step(&table, &mut host); + assert_eq!(interp.stack.data(), &vec![U256::ZERO]); + interp.stack.pop().unwrap(); + + // DATA SIZE + interp.step(&table, &mut host); + assert_eq!(interp.stack.data(), &vec![U256::from(36)]); + } + + #[test] + fn data_copy() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + let eof = dummy_eof(Bytes::from([DATACOPY, DATACOPY, DATACOPY, DATACOPY])); + + let mut interp = Interpreter::new_bytecode(eof); + interp.gas = Gas::new(10000); + + // Data copy + // size, offset mem_offset, + interp.stack.push(U256::from(32)).unwrap(); + interp.stack.push(U256::from(0)).unwrap(); + interp.stack.push(U256::from(0)).unwrap(); + interp.step(&table, &mut host); + assert_eq!( + interp.shared_memory.context_memory(), + &bytes!("0000000000000000000000000000000000000000000000000000000000000001") + ); + + // Data copy (Padding) + // size, offset mem_offset, + interp.stack.push(U256::from(2)).unwrap(); + interp.stack.push(U256::from(35)).unwrap(); + interp.stack.push(U256::from(1)).unwrap(); + interp.step(&table, &mut host); + assert_eq!( + interp.shared_memory.context_memory(), + &bytes!("0005000000000000000000000000000000000000000000000000000000000001") + ); + + // Data copy (Out of bounds) + // size, offset mem_offset, + interp.stack.push(U256::from(2)).unwrap(); + interp.stack.push(U256::from(37)).unwrap(); + interp.stack.push(U256::from(1)).unwrap(); + interp.step(&table, &mut host); + assert_eq!( + interp.shared_memory.context_memory(), + &bytes!("0000000000000000000000000000000000000000000000000000000000000001") + ); + + // Data copy (Size == 0) + // mem_offset, offset, size + interp.stack.push(U256::from(0)).unwrap(); + interp.stack.push(U256::from(37)).unwrap(); + interp.stack.push(U256::from(1)).unwrap(); + interp.step(&table, &mut host); + assert_eq!( + interp.shared_memory.context_memory(), + &bytes!("0000000000000000000000000000000000000000000000000000000000000001") + ); + } +} diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index f5069043..77fdf0df 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -1,17 +1,12 @@ -mod call_helpers; - -pub use call_helpers::{calc_call_gas, get_memory_input_and_out_ranges}; - use crate::{ - gas::{self, COLD_ACCOUNT_ACCESS_COST, WARM_STORAGE_READ_COST}, - interpreter::{Interpreter, InterpreterAction}, + gas::{self, warm_cold_cost}, + interpreter::Interpreter, primitives::{Bytes, Log, LogData, Spec, SpecId::*, B256, U256}, - CallContext, CallInputs, CallScheme, CreateInputs, CreateScheme, Host, InstructionResult, - SStoreResult, Transfer, MAX_INITCODE_SIZE, + Host, InstructionResult, SStoreResult, }; use core::cmp::min; use revm_primitives::BLOCK_HASH_HISTORY; -use std::{boxed::Box, vec::Vec}; +use std::vec::Vec; pub fn balance(interpreter: &mut Interpreter, host: &mut H) { pop_address!(interpreter, address); @@ -21,9 +16,11 @@ pub fn balance(interpreter: &mut Interpreter, host }; gas!( interpreter, - if SPEC::enabled(ISTANBUL) { + if SPEC::enabled(BERLIN) { + warm_cold_cost(is_cold) + } else if SPEC::enabled(ISTANBUL) { // EIP-1884: Repricing for trie-size-dependent opcodes - gas::account_access_gas(SPEC::SPEC_ID, is_cold) + 700 } else if SPEC::enabled(TANGERINE) { 400 } else { @@ -37,7 +34,7 @@ pub fn balance(interpreter: &mut Interpreter, host pub fn selfbalance(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, ISTANBUL); gas!(interpreter, gas::LOW); - let Some((balance, _)) = host.balance(interpreter.contract.address) else { + let Some((balance, _)) = host.balance(interpreter.contract.target_address) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; }; @@ -51,14 +48,7 @@ pub fn extcodesize(interpreter: &mut Interpreter, return; }; if SPEC::enabled(BERLIN) { - gas!( - interpreter, - if is_cold { - COLD_ACCOUNT_ACCESS_COST - } else { - WARM_STORAGE_READ_COST - } - ); + gas!(interpreter, warm_cold_cost(is_cold)); } else if SPEC::enabled(TANGERINE) { gas!(interpreter, 700); } else { @@ -77,14 +67,7 @@ pub fn extcodehash(interpreter: &mut Interpreter, return; }; if SPEC::enabled(BERLIN) { - gas!( - interpreter, - if is_cold { - COLD_ACCOUNT_ACCESS_COST - } else { - WARM_STORAGE_READ_COST - } - ); + gas!(interpreter, warm_cold_cost(is_cold)); } else if SPEC::enabled(ISTANBUL) { gas!(interpreter, 700); } else { @@ -117,7 +100,7 @@ pub fn extcodecopy(interpreter: &mut Interpreter, // Note: this can't panic because we resized memory to fit. interpreter .shared_memory - .set_data(memory_offset, code_offset, len, code.bytes()); + .set_data(memory_offset, code_offset, len, &code.original_bytes()); } pub fn blockhash(interpreter: &mut Interpreter, host: &mut H) { @@ -141,8 +124,7 @@ pub fn blockhash(interpreter: &mut Interpreter, host: &mut H) pub fn sload(interpreter: &mut Interpreter, host: &mut H) { pop_top!(interpreter, index); - - let Some((value, is_cold)) = host.sload(interpreter.contract.address, *index) else { + let Some((value, is_cold)) = host.sload(interpreter.contract.target_address, *index) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; }; @@ -151,7 +133,7 @@ pub fn sload(interpreter: &mut Interpreter, host: } pub fn sstore(interpreter: &mut Interpreter, host: &mut H) { - check_staticcall!(interpreter); + error_on_static_call!(interpreter); pop!(interpreter, index, value); let Some(SStoreResult { @@ -159,7 +141,7 @@ pub fn sstore(interpreter: &mut Interpreter, host: present_value: old, new_value: new, is_cold, - }) = host.sstore(interpreter.contract.address, index, value) + }) = host.sstore(interpreter.contract.target_address, index, value) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; @@ -178,12 +160,12 @@ pub fn sstore(interpreter: &mut Interpreter, host: /// Store value to transient storage pub fn tstore(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, CANCUN); - check_staticcall!(interpreter); + error_on_static_call!(interpreter); gas!(interpreter, gas::WARM_STORAGE_READ_COST); pop!(interpreter, index, value); - host.tstore(interpreter.contract.address, index, value); + host.tstore(interpreter.contract.target_address, index, value); } /// EIP-1153: Transient storage opcodes @@ -194,11 +176,11 @@ pub fn tload(interpreter: &mut Interpreter, host: pop_top!(interpreter, index); - *index = host.tload(interpreter.contract.address, *index); + *index = host.tload(interpreter.contract.target_address, *index); } pub fn log(interpreter: &mut Interpreter, host: &mut H) { - check_staticcall!(interpreter); + error_on_static_call!(interpreter); pop!(interpreter, offset, len); let len = as_usize_or_fail!(interpreter, len); @@ -223,7 +205,7 @@ pub fn log(interpreter: &mut Interpreter, host } let log = Log { - address: interpreter.contract.address, + address: interpreter.contract.target_address, data: LogData::new(topics, data).expect("LogData should have <=4 topics"), }; @@ -231,10 +213,10 @@ pub fn log(interpreter: &mut Interpreter, host } pub fn selfdestruct(interpreter: &mut Interpreter, host: &mut H) { - check_staticcall!(interpreter); + error_on_static_call!(interpreter); pop_address!(interpreter, target); - let Some(res) = host.selfdestruct(interpreter.contract.address, target) else { + let Some(res) = host.selfdestruct(interpreter.contract.target_address, target) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; }; @@ -247,279 +229,3 @@ pub fn selfdestruct(interpreter: &mut Interpreter, interpreter.instruction_result = InstructionResult::SelfDestruct; } - -pub fn create( - interpreter: &mut Interpreter, - host: &mut H, -) { - check_staticcall!(interpreter); - - // EIP-1014: Skinny CREATE2 - if IS_CREATE2 { - check!(interpreter, PETERSBURG); - } - - pop!(interpreter, value, code_offset, len); - let len = as_usize_or_fail!(interpreter, len); - - let mut code = Bytes::new(); - if len != 0 { - // EIP-3860: Limit and meter initcode - if SPEC::enabled(SHANGHAI) { - // Limit is set as double of max contract bytecode size - let max_initcode_size = host - .env() - .cfg - .limit_contract_code_size - .map(|limit| limit.saturating_mul(2)) - .unwrap_or(MAX_INITCODE_SIZE); - if len > max_initcode_size { - interpreter.instruction_result = InstructionResult::CreateInitCodeSizeLimit; - return; - } - gas!(interpreter, gas::initcode_cost(len as u64)); - } - - let code_offset = as_usize_or_fail!(interpreter, code_offset); - resize_memory!(interpreter, code_offset, len); - code = Bytes::copy_from_slice(interpreter.shared_memory.slice(code_offset, len)); - } - - // EIP-1014: Skinny CREATE2 - let scheme = if IS_CREATE2 { - pop!(interpreter, salt); - gas_or_fail!(interpreter, gas::create2_cost(len as u64)); - CreateScheme::Create2 { salt } - } else { - gas!(interpreter, gas::CREATE); - CreateScheme::Create - }; - - let mut gas_limit = interpreter.gas().remaining(); - - // EIP-150: Gas cost changes for IO-heavy operations - if SPEC::enabled(TANGERINE) { - // take remaining gas and deduce l64 part of it. - gas_limit -= gas_limit / 64 - } - gas!(interpreter, gas_limit); - - // Call host to interact with target contract - interpreter.next_action = InterpreterAction::Create { - inputs: Box::new(CreateInputs { - caller: interpreter.contract.address, - scheme, - value, - init_code: code, - gas_limit, - }), - }; - interpreter.instruction_result = InstructionResult::CallOrCreate; -} - -pub fn call(interpreter: &mut Interpreter, host: &mut H) { - pop!(interpreter, local_gas_limit); - pop_address!(interpreter, to); - // max gas limit is not possible in real ethereum situation. - let local_gas_limit = u64::try_from(local_gas_limit).unwrap_or(u64::MAX); - - pop!(interpreter, value); - if interpreter.is_static && value != U256::ZERO { - interpreter.instruction_result = InstructionResult::CallNotAllowedInsideStatic; - return; - } - - let Some((input, return_memory_offset)) = get_memory_input_and_out_ranges(interpreter) else { - return; - }; - - let Some(mut gas_limit) = calc_call_gas::( - interpreter, - host, - to, - value != U256::ZERO, - local_gas_limit, - true, - true, - ) else { - return; - }; - - gas!(interpreter, gas_limit); - - // add call stipend if there is value to be transferred. - if value != U256::ZERO { - gas_limit = gas_limit.saturating_add(gas::CALL_STIPEND); - } - - // Call host to interact with target contract - interpreter.next_action = InterpreterAction::Call { - inputs: Box::new(CallInputs { - contract: to, - transfer: Transfer { - source: interpreter.contract.address, - target: to, - value, - }, - input, - gas_limit, - context: CallContext { - address: to, - caller: interpreter.contract.address, - code_address: to, - apparent_value: value, - scheme: CallScheme::Call, - }, - is_static: interpreter.is_static, - return_memory_offset, - }), - }; - interpreter.instruction_result = InstructionResult::CallOrCreate; -} - -pub fn call_code(interpreter: &mut Interpreter, host: &mut H) { - pop!(interpreter, local_gas_limit); - pop_address!(interpreter, to); - // max gas limit is not possible in real ethereum situation. - let local_gas_limit = u64::try_from(local_gas_limit).unwrap_or(u64::MAX); - - pop!(interpreter, value); - let Some((input, return_memory_offset)) = get_memory_input_and_out_ranges(interpreter) else { - return; - }; - - let Some(mut gas_limit) = calc_call_gas::( - interpreter, - host, - to, - value != U256::ZERO, - local_gas_limit, - true, - false, - ) else { - return; - }; - - gas!(interpreter, gas_limit); - - // add call stipend if there is value to be transferred. - if value != U256::ZERO { - gas_limit = gas_limit.saturating_add(gas::CALL_STIPEND); - } - - // Call host to interact with target contract - interpreter.next_action = InterpreterAction::Call { - inputs: Box::new(CallInputs { - contract: to, - transfer: Transfer { - source: interpreter.contract.address, - target: interpreter.contract.address, - value, - }, - input, - gas_limit, - context: CallContext { - address: interpreter.contract.address, - caller: interpreter.contract.address, - code_address: to, - apparent_value: value, - scheme: CallScheme::CallCode, - }, - is_static: interpreter.is_static, - return_memory_offset, - }), - }; - interpreter.instruction_result = InstructionResult::CallOrCreate; -} - -pub fn delegate_call(interpreter: &mut Interpreter, host: &mut H) { - check!(interpreter, HOMESTEAD); - pop!(interpreter, local_gas_limit); - pop_address!(interpreter, to); - // max gas limit is not possible in real ethereum situation. - let local_gas_limit = u64::try_from(local_gas_limit).unwrap_or(u64::MAX); - - let Some((input, return_memory_offset)) = get_memory_input_and_out_ranges(interpreter) else { - return; - }; - - let Some(gas_limit) = - calc_call_gas::(interpreter, host, to, false, local_gas_limit, false, false) - else { - return; - }; - - gas!(interpreter, gas_limit); - - // Call host to interact with target contract - interpreter.next_action = InterpreterAction::Call { - inputs: Box::new(CallInputs { - contract: to, - // This is dummy send for StaticCall and DelegateCall, - // it should do nothing and not touch anything. - transfer: Transfer { - source: interpreter.contract.address, - target: interpreter.contract.address, - value: U256::ZERO, - }, - input, - gas_limit, - context: CallContext { - address: interpreter.contract.address, - caller: interpreter.contract.caller, - code_address: to, - apparent_value: interpreter.contract.value, - scheme: CallScheme::DelegateCall, - }, - is_static: interpreter.is_static, - return_memory_offset, - }), - }; - interpreter.instruction_result = InstructionResult::CallOrCreate; -} - -pub fn static_call(interpreter: &mut Interpreter, host: &mut H) { - check!(interpreter, BYZANTIUM); - pop!(interpreter, local_gas_limit); - pop_address!(interpreter, to); - // max gas limit is not possible in real ethereum situation. - let local_gas_limit = u64::try_from(local_gas_limit).unwrap_or(u64::MAX); - - let value = U256::ZERO; - let Some((input, return_memory_offset)) = get_memory_input_and_out_ranges(interpreter) else { - return; - }; - - let Some(gas_limit) = - calc_call_gas::(interpreter, host, to, false, local_gas_limit, false, true) - else { - return; - }; - gas!(interpreter, gas_limit); - - // Call host to interact with target contract - interpreter.next_action = InterpreterAction::Call { - inputs: Box::new(CallInputs { - contract: to, - // This is dummy send for StaticCall and DelegateCall, - // it should do nothing and not touch anything. - transfer: Transfer { - source: interpreter.contract.address, - target: interpreter.contract.address, - value: U256::ZERO, - }, - input, - gas_limit, - context: CallContext { - address: to, - caller: interpreter.contract.address, - code_address: to, - apparent_value: value, - scheme: CallScheme::StaticCall, - }, - is_static: true, - return_memory_offset, - }), - }; - interpreter.instruction_result = InstructionResult::CallOrCreate; -} diff --git a/crates/interpreter/src/instructions/host_env.rs b/crates/interpreter/src/instructions/host_env.rs index 1b0c3995..ce934d49 100644 --- a/crates/interpreter/src/instructions/host_env.rs +++ b/crates/interpreter/src/instructions/host_env.rs @@ -21,7 +21,7 @@ pub fn timestamp(interpreter: &mut Interpreter, host: &mut H) push!(interpreter, host.env().block.timestamp); } -pub fn number(interpreter: &mut Interpreter, host: &mut H) { +pub fn block_number(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, host.env().block.number); } diff --git a/crates/interpreter/src/instructions/i256.rs b/crates/interpreter/src/instructions/i256.rs index 0067c666..d806eacf 100644 --- a/crates/interpreter/src/instructions/i256.rs +++ b/crates/interpreter/src/instructions/i256.rs @@ -11,7 +11,14 @@ pub enum Sign { Plus = 1, } -const MIN_NEGATIVE_VALUE: U256 = U256::from_limbs([ +pub const MAX_POSITIVE_VALUE: U256 = U256::from_limbs([ + 0xffffffffffffffff, + 0xffffffffffffffff, + 0xffffffffffffffff, + 0x7fffffffffffffff, +]); + +pub const MIN_NEGATIVE_VALUE: U256 = U256::from_limbs([ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, @@ -125,15 +132,8 @@ pub fn i256_mod(mut first: U256, mut second: U256) -> U256 { #[cfg(test)] mod tests { use super::*; + use crate::primitives::uint; use core::num::Wrapping; - use revm_primitives::uint; - - const MAX_POSITIVE_VALUE: U256 = U256::from_limbs([ - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0x7fffffffffffffff, - ]); #[test] fn div_i256() { diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index b194f36a..a50dddfc 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -2,7 +2,7 @@ /// Fails the instruction if the current call is static. #[macro_export] -macro_rules! check_staticcall { +macro_rules! error_on_static_call { ($interp:expr) => { if $interp.is_static { $interp.instruction_result = $crate::InstructionResult::StateChangeDuringStaticCall; @@ -11,7 +11,29 @@ macro_rules! check_staticcall { }; } -/// Fails the instruction if the `min` is not enabled in `SPEC`. +/// Error if the current call is executing EOF. +#[macro_export] +macro_rules! error_on_disabled_eof { + ($interp:expr) => { + if !$interp.is_eof { + $interp.instruction_result = $crate::InstructionResult::EOFOpcodeDisabledInLegacy; + return; + } + }; +} + +/// Error if not init eof call. +#[macro_export] +macro_rules! error_on_not_init_eof { + ($interp:expr) => { + if !$interp.is_eof_init { + $interp.instruction_result = $crate::InstructionResult::ReturnContractInNotInitEOF; + return; + } + }; +} + +/// Check if the `SPEC` is enabled, and fail the instruction if it is not. #[macro_export] macro_rules! check { ($interp:expr, $min:ident) => { @@ -96,19 +118,30 @@ macro_rules! resize_memory { #[macro_export] macro_rules! pop_address { ($interp:expr, $x1:ident) => { + pop_address_ret!($interp, $x1, ()) + }; + ($interp:expr, $x1:ident, $x2:ident) => { + pop_address_ret!($interp, $x1, $x2, ()) + }; +} + +/// Pop `Address` values from the stack, returns `ret` on stack underflow. +#[macro_export] +macro_rules! pop_address_ret { + ($interp:expr, $x1:ident, $ret:expr) => { if $interp.stack.len() < 1 { $interp.instruction_result = $crate::InstructionResult::StackUnderflow; - return; + return $ret; } // SAFETY: Length is checked above. let $x1 = $crate::primitives::Address::from_word($crate::primitives::B256::from(unsafe { $interp.stack.pop_unsafe() })); }; - ($interp:expr, $x1:ident, $x2:ident) => { + ($interp:expr, $x1:ident, $x2:ident, $ret:expr) => { if $interp.stack.len() < 2 { $interp.instruction_result = $crate::InstructionResult::StackUnderflow; - return; + return $ret; } // SAFETY: Length is checked above. let $x1 = $crate::primitives::Address::from_word($crate::primitives::B256::from(unsafe { @@ -135,6 +168,9 @@ macro_rules! pop { ($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident) => { $crate::pop_ret!($interp, $x1, $x2, $x3, $x4, ()) }; + ($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident, $x5:ident) => { + pop_ret!($interp, $x1, $x2, $x3, $x4, $x5, ()) + }; } /// Pops `U256` values from the stack, and returns `ret`. @@ -173,6 +209,14 @@ macro_rules! pop_ret { // SAFETY: Length is checked above. let ($x1, $x2, $x3, $x4) = unsafe { $interp.stack.pop4_unsafe() }; }; + ($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident, $x5:ident, $ret:expr) => { + if $interp.stack.len() < 4 { + $interp.instruction_result = $crate::InstructionResult::StackUnderflow; + return $ret; + } + // SAFETY: Length is checked above. + let ($x1, $x2, $x3, $x4, $x5) = unsafe { $interp.stack.pop5_unsafe() }; + }; } /// Pops `U256` values from the stack, and returns a reference to the top of the stack. @@ -254,6 +298,16 @@ macro_rules! as_usize_saturated { }; } +/// Converts a `U256` value to a `isize`, saturating to `isize::MAX` if the value is too large. +#[macro_export] +macro_rules! as_isize_saturated { + ($v:expr) => { + // `isize_try_from(u64::MAX)`` will fail and return isize::MAX + // this is expected behavior as we are saturating the value. + isize::try_from($crate::as_u64_saturated!($v)).unwrap_or(isize::MAX) + }; +} + /// Converts a `U256` value to a `usize`, failing the instruction if the value is too large. #[macro_export] macro_rules! as_usize_or_fail { diff --git a/crates/interpreter/src/instructions/memory.rs b/crates/interpreter/src/instructions/memory.rs index 73dd4126..e5bdde91 100644 --- a/crates/interpreter/src/instructions/memory.rs +++ b/crates/interpreter/src/instructions/memory.rs @@ -7,10 +7,10 @@ use core::cmp::max; pub fn mload(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); - pop_top!(interpreter, offset_ptr); - let offset = as_usize_or_fail!(interpreter, offset_ptr); + pop_top!(interpreter, top); + let offset = as_usize_or_fail!(interpreter, top); resize_memory!(interpreter, offset, 32); - *offset_ptr = interpreter.shared_memory.get_u256(offset); + *top = interpreter.shared_memory.get_u256(offset); } pub fn mstore(interpreter: &mut Interpreter, _host: &mut H) { diff --git a/crates/interpreter/src/instructions/stack.rs b/crates/interpreter/src/instructions/stack.rs index 52676875..fa6c1be9 100644 --- a/crates/interpreter/src/instructions/stack.rs +++ b/crates/interpreter/src/instructions/stack.rs @@ -39,14 +39,121 @@ pub fn push(interpreter: &mut Interpreter, _ho pub fn dup(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); - if let Err(result) = interpreter.stack.dup::() { + if let Err(result) = interpreter.stack.dup(N) { interpreter.instruction_result = result; } } pub fn swap(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); - if let Err(result) = interpreter.stack.swap::() { + if let Err(result) = interpreter.stack.swap(N) { interpreter.instruction_result = result; } } + +pub fn dupn(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); + gas!(interpreter, gas::VERYLOW); + let imm = unsafe { *interpreter.instruction_pointer }; + if let Err(result) = interpreter.stack.dup(imm as usize + 1) { + interpreter.instruction_result = result; + } + interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(1) }; +} + +pub fn swapn(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); + gas!(interpreter, gas::VERYLOW); + let imm = unsafe { *interpreter.instruction_pointer }; + if let Err(result) = interpreter.stack.swap(imm as usize + 1) { + interpreter.instruction_result = result; + } + interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(1) }; +} + +pub fn exchange(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); + gas!(interpreter, gas::VERYLOW); + let imm = unsafe { *interpreter.instruction_pointer }; + let n = (imm >> 4) + 1; + let m = (imm & 0x0F) + 1; + if let Err(result) = interpreter.stack.exchange(n as usize, m as usize) { + interpreter.instruction_result = result; + } + + interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(1) }; +} + +#[cfg(test)] +mod test { + use super::*; + use crate::{ + opcode::{make_instruction_table, DUPN, EXCHANGE, SWAPN}, + primitives::{Bytecode, Bytes, PragueSpec}, + DummyHost, Gas, InstructionResult, Interpreter, + }; + + #[test] + fn dupn() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + let mut interp = Interpreter::new_bytecode(Bytecode::LegacyRaw(Bytes::from([ + DUPN, 0x00, DUPN, 0x01, DUPN, 0x02, + ]))); + interp.is_eof = true; + interp.gas = Gas::new(10000); + + interp.stack.push(U256::from(10)).unwrap(); + interp.stack.push(U256::from(20)).unwrap(); + interp.step(&table, &mut host); + assert_eq!(interp.stack.pop(), Ok(U256::from(20))); + interp.step(&table, &mut host); + assert_eq!(interp.stack.pop(), Ok(U256::from(10))); + interp.step(&table, &mut host); + assert_eq!(interp.instruction_result, InstructionResult::StackUnderflow); + } + + #[test] + fn swapn() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + let mut interp = + Interpreter::new_bytecode(Bytecode::LegacyRaw(Bytes::from([SWAPN, 0x00, SWAPN, 0x01]))); + interp.is_eof = true; + interp.gas = Gas::new(10000); + + interp.stack.push(U256::from(10)).unwrap(); + interp.stack.push(U256::from(20)).unwrap(); + interp.stack.push(U256::from(0)).unwrap(); + interp.step(&table, &mut host); + assert_eq!(interp.stack.peek(0), Ok(U256::from(20))); + assert_eq!(interp.stack.peek(1), Ok(U256::from(0))); + interp.step(&table, &mut host); + assert_eq!(interp.stack.peek(0), Ok(U256::from(10))); + assert_eq!(interp.stack.peek(2), Ok(U256::from(20))); + } + + #[test] + fn exchange() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + let mut interp = Interpreter::new_bytecode(Bytecode::LegacyRaw(Bytes::from([ + EXCHANGE, 0x00, EXCHANGE, 0x11, + ]))); + interp.is_eof = true; + interp.gas = Gas::new(10000); + + interp.stack.push(U256::from(1)).unwrap(); + interp.stack.push(U256::from(5)).unwrap(); + interp.stack.push(U256::from(10)).unwrap(); + interp.stack.push(U256::from(15)).unwrap(); + interp.stack.push(U256::from(0)).unwrap(); + + interp.step(&table, &mut host); + assert_eq!(interp.stack.peek(1), Ok(U256::from(10))); + assert_eq!(interp.stack.peek(2), Ok(U256::from(15))); + interp.step(&table, &mut host); + assert_eq!(interp.stack.peek(2), Ok(U256::from(1))); + assert_eq!(interp.stack.peek(4), Ok(U256::from(15))); + } +} diff --git a/crates/interpreter/src/instructions/system.rs b/crates/interpreter/src/instructions/system.rs index 25cb8dd6..a5cec536 100644 --- a/crates/interpreter/src/instructions/system.rs +++ b/crates/interpreter/src/instructions/system.rs @@ -21,7 +21,7 @@ pub fn keccak256(interpreter: &mut Interpreter, _host: &mut H) pub fn address(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); - push_b256!(interpreter, interpreter.contract.address.into_word()); + push_b256!(interpreter, interpreter.contract.target_address.into_word()); } pub fn caller(interpreter: &mut Interpreter, _host: &mut H) { @@ -50,7 +50,7 @@ pub fn codecopy(interpreter: &mut Interpreter, _host: &mut H) memory_offset, code_offset, len, - interpreter.contract.bytecode.original_bytecode_slice(), + &interpreter.contract.bytecode.original_bytes(), ); } @@ -84,7 +84,7 @@ pub fn calldatasize(interpreter: &mut Interpreter, _host: &mut pub fn callvalue(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); - push!(interpreter, interpreter.contract.value); + push!(interpreter, interpreter.contract.call_value); } pub fn calldatacopy(interpreter: &mut Interpreter, _host: &mut H) { @@ -124,8 +124,8 @@ pub fn returndatacopy(interpreter: &mut Interprete let len = as_usize_or_fail!(interpreter, len); gas_or_fail!(interpreter, gas::verylowcopy_cost(len as u64)); let data_offset = as_usize_saturated!(offset); - let (data_end, overflow) = data_offset.overflowing_add(len); - if overflow || data_end > interpreter.return_data_buffer.len() { + let data_end = data_offset.saturating_add(len); + if data_end > interpreter.return_data_buffer.len() { interpreter.instruction_result = InstructionResult::OutOfOffset; return; } @@ -139,7 +139,68 @@ pub fn returndatacopy(interpreter: &mut Interprete } } +/// Part of EOF ``. +pub fn returndataload(interpreter: &mut Interpreter, _host: &mut H) { + error_on_disabled_eof!(interpreter); + gas!(interpreter, gas::VERYLOW); + pop_top!(interpreter, offset); + let offset_usize = as_usize_or_fail!(interpreter, offset); + if offset_usize.saturating_add(32) > interpreter.return_data_buffer.len() { + // TODO(EOF) proper error. + interpreter.instruction_result = InstructionResult::OutOfOffset; + return; + } + *offset = + B256::from_slice(&interpreter.return_data_buffer[offset_usize..offset_usize + 32]).into(); +} + pub fn gas(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); push!(interpreter, U256::from(interpreter.gas.remaining())); } + +#[cfg(test)] +mod test { + use super::*; + use crate::{ + opcode::{make_instruction_table, RETURNDATALOAD}, + primitives::{bytes, Bytecode, PragueSpec, U256}, + DummyHost, Gas, Interpreter, + }; + + #[test] + fn returndataload() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + + let mut interp = Interpreter::new_bytecode(Bytecode::LegacyRaw( + [RETURNDATALOAD, RETURNDATALOAD, RETURNDATALOAD].into(), + )); + interp.is_eof = true; + interp.gas = Gas::new(10000); + + interp.stack.push(U256::from(0)).unwrap(); + interp.return_data_buffer = + bytes!("000000000000000400000000000000030000000000000002000000000000000100"); + interp.step(&table, &mut host); + assert_eq!( + interp.stack.data(), + &vec![U256::from_limbs([0x01, 0x02, 0x03, 0x04])] + ); + + let _ = interp.stack.pop(); + let _ = interp.stack.push(U256::from(1)); + + interp.step(&table, &mut host); + assert_eq!(interp.instruction_result, InstructionResult::Continue); + assert_eq!( + interp.stack.data(), + &vec![U256::from_limbs([0x0100, 0x0200, 0x0300, 0x0400])] + ); + + let _ = interp.stack.pop(); + let _ = interp.stack.push(U256::from(2)); + interp.step(&table, &mut host); + assert_eq!(interp.instruction_result, InstructionResult::OutOfOffset); + } +} diff --git a/crates/interpreter/src/instructions/utility.rs b/crates/interpreter/src/instructions/utility.rs new file mode 100644 index 00000000..55b12127 --- /dev/null +++ b/crates/interpreter/src/instructions/utility.rs @@ -0,0 +1,7 @@ +pub(crate) unsafe fn read_i16(ptr: *const u8) -> i16 { + i16::from_be_bytes(core::slice::from_raw_parts(ptr, 2).try_into().unwrap()) +} + +pub(crate) unsafe fn read_u16(ptr: *const u8) -> u16 { + u16::from_be_bytes(core::slice::from_raw_parts(ptr, 2).try_into().unwrap()) +} diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index 4da1b58d..6d0b6320 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -3,32 +3,39 @@ mod contract; mod shared_memory; mod stack; -pub use analysis::BytecodeLocked; pub use contract::Contract; pub use shared_memory::{next_multiple_of_32, SharedMemory, EMPTY_SHARED_MEMORY}; pub use stack::{Stack, STACK_LIMIT}; +use crate::EOFCreateOutcome; use crate::{ - primitives::Bytes, push, push_b256, return_ok, return_revert, CallInputs, CallOutcome, - CreateInputs, CreateOutcome, Gas, Host, InstructionResult, + primitives::Bytes, push, push_b256, return_ok, return_revert, CallOutcome, CreateOutcome, + FunctionStack, Gas, Host, InstructionResult, InterpreterAction, }; use core::cmp::min; -use revm_primitives::U256; +use revm_primitives::{Bytecode, Eof, U256}; use std::borrow::ToOwned; -use std::boxed::Box; /// EVM bytecode interpreter. #[derive(Debug)] pub struct Interpreter { - /// Contract information and invoking data - pub contract: Contract, /// The current instruction pointer. pub instruction_pointer: *const u8, + /// The gas state. + pub gas: Gas, + /// Contract information and invoking data + pub contract: Contract, /// The execution control flag. If this is not set to `Continue`, the interpreter will stop /// execution. pub instruction_result: InstructionResult, - /// The gas state. - pub gas: Gas, + /// Currently run Bytecode that instruction result will point to. + /// Bytecode is owned by the contract. + pub bytecode: Bytes, + /// Whether we are Interpreting the Ethereum Object Format (EOF) bytecode. + /// This is local field that is set from `contract.is_eof()`. + pub is_eof: bool, + /// Is init flag for eof create + pub is_eof_init: bool, /// Shared memory. /// /// Note: This field is only set while running the interpreter loop. @@ -36,6 +43,8 @@ pub struct Interpreter { pub shared_memory: SharedMemory, /// Stack. pub stack: Stack, + /// EOF function stack. + pub function_stack: FunctionStack, /// The return data buffer for internal calls. /// It has multi usage: /// @@ -51,6 +60,12 @@ pub struct Interpreter { pub next_action: InterpreterAction, } +impl Default for Interpreter { + fn default() -> Self { + Self::new(Contract::default(), 0, false) + } +} + /// The result of an interpreter operation. #[derive(Clone, Debug, PartialEq, Eq)] pub struct InterpreterResult { @@ -62,66 +77,24 @@ pub struct InterpreterResult { pub gas: Gas, } -#[derive(Clone, Debug, Default, PartialEq, Eq)] -pub enum InterpreterAction { - /// CALL, CALLCODE, DELEGATECALL or STATICCALL instruction called. - Call { - /// Call inputs - inputs: Box, - }, - /// CREATE or CREATE2 instruction called. - Create { inputs: Box }, - /// Interpreter finished execution. - Return { result: InterpreterResult }, - /// No action - #[default] - None, -} - -impl InterpreterAction { - /// Returns true if action is call. - pub fn is_call(&self) -> bool { - matches!(self, InterpreterAction::Call { .. }) - } - - /// Returns true if action is create. - pub fn is_create(&self) -> bool { - matches!(self, InterpreterAction::Create { .. }) - } - - /// Returns true if action is return. - pub fn is_return(&self) -> bool { - matches!(self, InterpreterAction::Return { .. }) - } - - /// Returns true if action is none. - pub fn is_none(&self) -> bool { - matches!(self, InterpreterAction::None) - } - - /// Returns true if action is some. - pub fn is_some(&self) -> bool { - !self.is_none() - } - - /// Returns result if action is return. - pub fn into_result_return(self) -> Option { - match self { - InterpreterAction::Return { result } => Some(result), - _ => None, - } - } -} - impl Interpreter { /// Create new interpreter pub fn new(contract: Contract, gas_limit: u64, is_static: bool) -> Self { + if !contract.bytecode.is_execution_ready() { + panic!("Contract is not execution ready {:?}", contract.bytecode); + } + let is_eof = contract.bytecode.is_eof(); + let bytecode = contract.bytecode.bytecode_bytes(); Self { - instruction_pointer: contract.bytecode.as_ptr(), + instruction_pointer: bytecode.as_ptr(), + bytecode, contract, gas: Gas::new(gas_limit), instruction_result: InstructionResult::Continue, + function_stack: FunctionStack::default(), is_static, + is_eof, + is_eof_init: false, return_data_buffer: Bytes::new(), shared_memory: EMPTY_SHARED_MEMORY, stack: Stack::new(), @@ -129,6 +102,47 @@ impl Interpreter { } } + /// Set set is_eof_init to true, this is used to enable `RETURNCONTRACT` opcode. + #[inline] + pub fn set_is_eof_init(&mut self) { + self.is_eof_init = true; + } + + #[inline] + pub fn eof(&self) -> Option<&Eof> { + self.contract.bytecode.eof() + } + + /// Test related helper + #[cfg(test)] + pub fn new_bytecode(bytecode: Bytecode) -> Self { + Self::new( + Contract::new( + Bytes::new(), + bytecode, + None, + crate::primitives::Address::default(), + crate::primitives::Address::default(), + U256::ZERO, + ), + 0, + false, + ) + } + + /// Load EOF code into interpreter. PC is assumed to be correctly set + pub(crate) fn load_eof_code(&mut self, idx: usize, pc: usize) { + // SAFETY: eof flag is true only if bytecode is Eof. + let Bytecode::Eof(eof) = &self.contract.bytecode else { + panic!("Expected EOF bytecode") + }; + let Some(code) = eof.body.code(idx) else { + panic!("Code not found") + }; + self.bytecode = code.clone(); + self.instruction_pointer = unsafe { self.bytecode.as_ptr().add(pc) }; + } + /// Inserts the output of a `create` call into the interpreter. /// /// This function is used after a `create` call has been executed. It processes the outcome @@ -186,6 +200,36 @@ impl Interpreter { } } + pub fn insert_eofcreate_outcome(&mut self, create_outcome: EOFCreateOutcome) { + let instruction_result = create_outcome.instruction_result(); + + self.return_data_buffer = if *instruction_result == InstructionResult::Revert { + // Save data to return data buffer if the create reverted + create_outcome.output().to_owned() + } else { + // Otherwise clear it. Note that RETURN opcode should abort. + Bytes::new() + }; + + match instruction_result { + InstructionResult::ReturnContract => { + push_b256!(self, create_outcome.address.into_word()); + self.gas.erase_cost(create_outcome.gas().remaining()); + self.gas.record_refund(create_outcome.gas().refunded()); + } + return_revert!() => { + push!(self, U256::ZERO); + self.gas.erase_cost(create_outcome.gas().remaining()); + } + InstructionResult::FatalExternalError => { + panic!("Fatal external error in insert_eofcreate_outcome"); + } + _ => { + push!(self, U256::ZERO); + } + } + } + /// Inserts the outcome of a call into the virtual machine's state. /// /// This function takes the result of a call, represented by `CallOutcome`, @@ -214,12 +258,12 @@ impl Interpreter { call_outcome: CallOutcome, ) { self.instruction_result = InstructionResult::Continue; + self.return_data_buffer.clone_from(call_outcome.output()); + let out_offset = call_outcome.memory_start(); let out_len = call_outcome.memory_length(); - self.return_data_buffer.clone_from(call_outcome.output()); let target_len = min(out_len, self.return_data_buffer.len()); - match call_outcome.instruction_result() { return_ok!() => { // return unspend gas. @@ -273,17 +317,14 @@ impl Interpreter { pub fn program_counter(&self) -> usize { // SAFETY: `instruction_pointer` should be at an offset from the start of the bytecode. // In practice this is always true unless a caller modifies the `instruction_pointer` field manually. - unsafe { - self.instruction_pointer - .offset_from(self.contract.bytecode.as_ptr()) as usize - } + unsafe { self.instruction_pointer.offset_from(self.bytecode.as_ptr()) as usize } } /// Executes the instruction at the current instruction pointer. /// /// Internally it will increment instruction pointer by one. - #[inline(always)] - fn step(&mut self, instruction_table: &[FN; 256], host: &mut H) + #[inline] + pub(crate) fn step(&mut self, instruction_table: &[FN; 256], host: &mut H) where FN: Fn(&mut Interpreter, &mut H), { diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index 4b363a84..bc2d96d2 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -1,36 +1,44 @@ -use crate::opcode; -use crate::primitives::{ - bitvec::prelude::{bitvec, BitVec, Lsb0}, - keccak256, Bytecode, BytecodeState, Bytes, JumpMap, B256, KECCAK_EMPTY, +use revm_primitives::{eof::EofDecodeError, HashSet}; + +use crate::{ + instructions::utility::{read_i16, read_u16}, + opcode, + primitives::{ + bitvec::prelude::{bitvec, BitVec, Lsb0}, + eof::TypesSection, + legacy::JumpTable, + Bytecode, Bytes, Eof, LegacyAnalyzedBytecode, + }, + OPCODE_INFO_JUMPTABLE, STACK_LIMIT, }; -use core::fmt; -use std::sync::Arc; +use std::{sync::Arc, vec, vec::Vec}; + +const EOF_NON_RETURNING_FUNCTION: u8 = 0x80; /// Perform bytecode analysis. /// /// The analysis finds and caches valid jump destinations for later execution as an optimization step. /// /// If the bytecode is already analyzed, it is returned as-is. +#[inline] pub fn to_analysed(bytecode: Bytecode) -> Bytecode { - let (bytecode, len) = match bytecode.state { - BytecodeState::Raw => { - let len = bytecode.bytecode.len(); - let checked = bytecode.to_checked(); - (checked.bytecode, len) + let (bytes, len) = match bytecode { + Bytecode::LegacyRaw(bytecode) => { + let len = bytecode.len(); + let mut padded_bytecode = Vec::with_capacity(len + 33); + padded_bytecode.extend_from_slice(&bytecode); + padded_bytecode.resize(len + 33, 0); + (Bytes::from(padded_bytecode), len) } - BytecodeState::Checked { len } => (bytecode.bytecode, len), - _ => return bytecode, + n => return n, }; - let jump_map = analyze(bytecode.as_ref()); + let jump_table = analyze(bytes.as_ref()); - Bytecode { - bytecode, - state: BytecodeState::Analysed { len, jump_map }, - } + Bytecode::LegacyAnalyzed(LegacyAnalyzedBytecode::new(bytes, len, jump_table)) } /// Analyze bytecode to build a jump map. -fn analyze(code: &[u8]) -> JumpMap { +fn analyze(code: &[u8]) -> JumpTable { let mut jumps: BitVec = bitvec![u8, Lsb0; 0; code.len()]; let range = code.as_ptr_range(); @@ -55,125 +63,530 @@ fn analyze(code: &[u8]) -> JumpMap { } } - JumpMap(Arc::new(jumps)) + JumpTable(Arc::new(jumps)) } -/// An analyzed bytecode. -#[derive(Clone)] -pub struct BytecodeLocked { - bytecode: Bytes, - original_len: usize, - jump_map: JumpMap, +pub fn validate_raw_eof(bytecode: Bytes) -> Result { + let eof = Eof::decode(bytecode)?; + validate_eof(&eof)?; + Ok(eof) } -impl fmt::Debug for BytecodeLocked { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("BytecodeLocked") - .field("bytecode", &self.bytecode) - .field("original_len", &self.original_len) - .field( - "jump_map", - &crate::primitives::hex::encode(self.jump_map.as_slice()), - ) - .finish() +/// Validate Eof structures. +pub fn validate_eof(eof: &Eof) -> Result<(), EofError> { + // clone is cheap as it is Bytes and a header. + let mut queue = vec![eof.clone()]; + + while let Some(eof) = queue.pop() { + // iterate over types + validate_eof_codes(&eof)?; + // iterate over containers, convert them to Eof and add to analyze_eof + for container in eof.body.container_section { + queue.push(Eof::decode(container)?); + } } + + // Eof is valid + Ok(()) } -impl Default for BytecodeLocked { - #[inline] - fn default() -> Self { - Bytecode::default() - .try_into() - .expect("Bytecode default is analysed code") +/// Validate EOF +pub fn validate_eof_codes(eof: &Eof) -> Result<(), EofValidationError> { + let mut queued_codes = vec![false; eof.body.code_section.len()]; + if eof.body.code_section.len() != eof.body.types_section.len() { + return Err(EofValidationError::InvalidTypesSection); + } + + if eof.body.code_section.is_empty() { + // no code sections. This should be already checked in decode. + return Err(EofValidationError::NoCodeSections); + } + // first section is default one. + queued_codes[0] = true; + + // the first code section must have a type signature + // (0, 0x80, max_stack_height) (0 inputs non-returning function) + let first_types = &eof.body.types_section[0]; + if first_types.inputs != 0 || first_types.outputs != EOF_NON_RETURNING_FUNCTION { + return Err(EofValidationError::InvalidTypesSection); + } + + // start validation from code section 0. + let mut queue = vec![0]; + while let Some(index) = queue.pop() { + let code = &eof.body.code_section[index]; + let accessed_codes = validate_eof_code( + code, + eof.header.data_size as usize, + index, + eof.body.container_section.len(), + &eof.body.types_section, + )?; + + // queue accessed codes. + accessed_codes.into_iter().for_each(|i| { + if !queued_codes[i] { + queued_codes[i] = true; + queue.push(i); + } + }); } + // iterate over accessed codes and check if all are accessed. + if queued_codes.into_iter().any(|x| !x) { + return Err(EofValidationError::CodeSectionNotAccessed); + } + + Ok(()) } -impl TryFrom for BytecodeLocked { - type Error = (); - - #[inline] - fn try_from(bytecode: Bytecode) -> Result { - if let BytecodeState::Analysed { len, jump_map } = bytecode.state { - Ok(BytecodeLocked { - bytecode: bytecode.bytecode, - original_len: len, - jump_map, - }) - } else { - Err(()) - } +/// EOF Error. +#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] +pub enum EofError { + Decode(EofDecodeError), + Validation(EofValidationError), +} + +impl From for EofError { + fn from(err: EofDecodeError) -> Self { + EofError::Decode(err) } } -impl BytecodeLocked { - /// Returns a raw pointer to the underlying byte slice. - #[inline] - pub fn as_ptr(&self) -> *const u8 { - self.bytecode.as_ptr() +impl From for EofError { + fn from(err: EofValidationError) -> Self { + EofError::Validation(err) } +} + +#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] +pub enum EofValidationError { + FalsePossitive, + /// Opcode is not known. It is not defined in the opcode table. + UnknownOpcode, + /// Opcode is disabled in EOF. For example JUMP, JUMPI, etc. + OpcodeDisabled, + /// Every instruction inside bytecode should be forward accessed. + /// Forward access can be a jump or sequential opcode. + /// In case after terminal opcode there should be a forward jump. + InstructionNotForwardAccessed, + /// Bytecode is too small and is missing immediate bytes for instruction. + MissingImmediateBytes, + /// Similar to [`EofValidationError::MissingImmediateBytes`] but for special case of RJUMPV immediate bytes. + MissingRJUMPVImmediateBytes, + /// Invalid jump into immediate bytes. + JumpToImmediateBytes, + /// Invalid jump into immediate bytes. + BackwardJumpToImmediateBytes, + /// MaxIndex in RJUMPV can't be zero. Zero max index makes it RJUMPI. + RJUMPVZeroMaxIndex, + /// Jump with zero offset would make a jump to next opcode, it does not make sense. + JumpZeroOffset, + /// EOFCREATE points to container out of bounds. + EOFCREATEInvalidIndex, + /// CALLF section out of bounds. + CodeSectionOutOfBounds, + /// CALLF to non returning function is not allowed. + CALLFNonReturningFunction, + /// CALLF stack overflow. + StackOverflow, + /// JUMPF needs to have enough outputs. + JUMPFEnoughOutputs, + /// JUMPF Stack + JUMPFStackHigherThanOutputs, + /// DATA load out of bounds. + DataLoadOutOfBounds, + /// RETF biggest stack num more then outputs. + RETFBiggestStackNumMoreThenOutputs, + /// Stack requirement is more than smallest stack items. + StackUnderflow, + /// Smallest stack items is more than types output. + TypesStackUnderflow, + /// Jump out of bounds. + JumpUnderflow, + /// Jump to out of bounds. + JumpOverflow, + /// Backward jump should have same smallest and biggest stack items. + BackwardJumpBiggestNumMismatch, + /// Backward jump should have same smallest and biggest stack items. + BackwardJumpSmallestNumMismatch, + /// Last instruction should be terminating. + LastInstructionNotTerminating, + /// Code section not accessed. + CodeSectionNotAccessed, + /// Types section invalid + InvalidTypesSection, + /// First types section is invalid. + /// It should have inputs 0 and outputs 0x80. + InvalidFirstTypesSection, + /// Max stack element mismatch. + MaxStackMismatch, + /// No code sections present + NoCodeSections, +} + +/// Validates that: +/// * All instructions are valid. +/// * It ends with a terminating instruction or RJUMP. +/// * All instructions are accessed by forward jumps or . +/// +/// Validate stack requirements and if all codes sections are used. +/// +/// TODO mark accessed Types/Codes +/// +/// Preconditions: +/// * Jump destinations are valid. +/// * All instructions are valid and well formed. +/// * All instruction is accessed by forward jumps. +/// * Bytecode is valid and ends with terminating instruction. +/// +/// Preconditions are checked in `validate_eof_bytecode`. +pub fn validate_eof_code( + code: &[u8], + data_size: usize, + this_types_index: usize, + num_of_containers: usize, + types: &[TypesSection], +) -> Result, EofValidationError> { + let mut accessed_codes = HashSet::::new(); + let this_types = &types[this_types_index]; - /// Returns the length of the bytecode. - #[inline] - pub fn len(&self) -> usize { - self.original_len + #[derive(Debug, Copy, Clone)] + struct InstructionInfo { + /// Is immediate byte, jumps can't happen on this part of code. + is_immediate: bool, + /// Have forward jump to this opcode. Used to check if opcode + /// after termination is accessed. + is_jumpdest: bool, + /// Smallest number of stack items accessed by jumps or sequential opcodes. + smallest: i32, + /// Biggest number of stack items accessed by jumps or sequential opcodes. + biggest: i32, } - /// Returns whether the bytecode is empty. - #[inline] - pub fn is_empty(&self) -> bool { - self.original_len == 0 + impl InstructionInfo { + #[inline] + fn mark_as_immediate(&mut self) -> Result<(), EofValidationError> { + if self.is_jumpdest { + // Jump to immediate bytes. + return Err(EofValidationError::JumpToImmediateBytes); + } + self.is_immediate = true; + Ok(()) + } } - /// Calculate hash of the bytecode. - #[inline] - pub fn hash_slow(&self) -> B256 { - if self.is_empty() { - KECCAK_EMPTY - } else { - keccak256(self.original_bytecode_slice()) + impl Default for InstructionInfo { + fn default() -> Self { + Self { + is_immediate: false, + is_jumpdest: false, + smallest: i32::MAX, + biggest: i32::MIN, + } } } - #[inline] - pub fn unlock(self) -> Bytecode { - Bytecode { - bytecode: self.bytecode, - state: BytecodeState::Analysed { - len: self.original_len, - jump_map: self.jump_map, - }, + // all bytes that are intermediate. + let mut jumps = vec![InstructionInfo::default(); code.len()]; + let mut is_after_termination = false; + + let mut next_smallest = this_types.inputs as i32; + let mut next_biggest = this_types.inputs as i32; + + let mut i = 0; + // We can check validity and jump destinations in one pass. + while i < code.len() { + let op = code[i]; + let opcode = &OPCODE_INFO_JUMPTABLE[op as usize]; + + let Some(opcode) = opcode else { + // err unknown opcode. + return Err(EofValidationError::UnknownOpcode); + }; + + if !opcode.is_eof { + // Opcode is disabled in EOF + return Err(EofValidationError::OpcodeDisabled); + } + + let this_instruction = &mut jumps[i]; + + // update biggest/smallest values for next instruction only if it is not after termination. + if !is_after_termination { + this_instruction.smallest = core::cmp::min(this_instruction.smallest, next_smallest); + this_instruction.biggest = core::cmp::max(this_instruction.biggest, next_biggest); + } + + let this_instruction = *this_instruction; + + // Opcodes after termination should be accessed by forward jumps. + if is_after_termination && !this_instruction.is_jumpdest { + // opcode after termination was not accessed. + return Err(EofValidationError::InstructionNotForwardAccessed); + } + is_after_termination = opcode.is_terminating_opcode; + + // mark immediate as non-jumpable. RJUMPV is special case covered later. + if opcode.immediate_size != 0 { + // check if the opcode immediate are within the bounds of the code + if i + opcode.immediate_size as usize >= code.len() { + // Malfunctional code + return Err(EofValidationError::MissingImmediateBytes); + } + + // mark immediate bytes as non-jumpable. + for imm in 1..opcode.immediate_size as usize + 1 { + // SAFETY: immediate size is checked above. + jumps[i + imm].mark_as_immediate()?; + } + } + // IO diff used to generate next instruction smallest/biggest value. + let mut stack_io_diff = opcode.io_diff() as i32; + // how many stack items are required for this opcode. + let mut stack_requirement = opcode.inputs as i32; + // additional immediate bytes for RJUMPV, it has dynamic vtable. + let mut rjumpv_additional_immediates = 0; + // If opcodes is RJUMP, RJUMPI or RJUMPV then this will have absolute jumpdest. + let mut absolute_jumpdest = vec![]; + match op { + opcode::RJUMP | opcode::RJUMPI => { + let offset = unsafe { read_i16(code.as_ptr().add(i + 1)) } as isize; + absolute_jumpdest = vec![offset + 3 + i as isize]; + // RJUMP is considered a terminating opcode. + } + opcode::RJUMPV => { + // code length for RJUMPV is checked with immediate size. + let max_index = code[i + 1] as usize; + let len = max_index + 1; + // and max_index+1 is to get size of vtable as index starts from 0. + rjumpv_additional_immediates = len * 2; + + // +1 is for max_index byte + if i + 1 + rjumpv_additional_immediates >= code.len() { + // Malfunctional code RJUMPV vtable is not complete + return Err(EofValidationError::MissingRJUMPVImmediateBytes); + } + + // Mark vtable as immediate, max_index was already marked. + for imm in 0..rjumpv_additional_immediates { + // SAFETY: immediate size is checked above. + jumps[i + 2 + imm].mark_as_immediate()?; + } + + let mut jumps = Vec::with_capacity(len); + for vtablei in 0..len { + let offset = + unsafe { read_i16(code.as_ptr().add(i + 2 + 2 * vtablei)) } as isize; + jumps.push(offset + i as isize + 2 + rjumpv_additional_immediates as isize); + } + absolute_jumpdest = jumps + } + opcode::CALLF => { + let section_i = unsafe { read_u16(code.as_ptr().add(i + 1)) } as usize; + let Some(target_types) = types.get(section_i) else { + // code section out of bounds. + return Err(EofValidationError::CodeSectionOutOfBounds); + }; + + if target_types.outputs == EOF_NON_RETURNING_FUNCTION { + // callf to non returning function is not allowed + return Err(EofValidationError::CALLFNonReturningFunction); + } + // stack input for this opcode is the input of the called code. + stack_requirement = target_types.inputs as i32; + // stack diff depends on input/output of the called code. + stack_io_diff = target_types.io_diff(); + // mark called code as accessed. + accessed_codes.insert(section_i); + + // we decrement by `types.inputs` as they are considered as send + // to the called code and included in types.max_stack_size. + if this_instruction.biggest - stack_requirement + target_types.max_stack_size as i32 + > STACK_LIMIT as i32 + { + // if stack max items + called code max stack size + return Err(EofValidationError::StackOverflow); + } + } + opcode::JUMPF => { + let target_index = unsafe { read_u16(code.as_ptr().add(i + 1)) } as usize; + // targeted code needs to have zero outputs (be non returning). + let Some(target_types) = types.get(target_index) else { + // code section out of bounds. + return Err(EofValidationError::CodeSectionOutOfBounds); + }; + + // we decrement types.inputs as they are considered send to the called code. + // and included in types.max_stack_size. + if this_instruction.biggest - target_types.inputs as i32 + + target_types.max_stack_size as i32 + > STACK_LIMIT as i32 + { + // stack overflow + return Err(EofValidationError::StackOverflow); + } + accessed_codes.insert(target_index); + + if target_types.outputs == EOF_NON_RETURNING_FUNCTION { + // if it is not returning + stack_requirement = target_types.inputs as i32; + } else { + // check if target code produces enough outputs. + if this_types.outputs < target_types.outputs { + return Err(EofValidationError::JUMPFEnoughOutputs); + } + + stack_requirement = this_types.outputs as i32 + target_types.inputs as i32 + - target_types.outputs as i32; + + // Stack requirement needs to more than this instruction biggest stack number. + if this_instruction.biggest > stack_requirement { + return Err(EofValidationError::JUMPFStackHigherThanOutputs); + } + + // if this instruction max + target_types max is more then stack limit. + if this_instruction.biggest + stack_requirement > STACK_LIMIT as i32 { + return Err(EofValidationError::StackOverflow); + } + } + } + opcode::EOFCREATE => { + let index = code[i + 1] as usize; + if index >= num_of_containers { + // code section out of bounds. + return Err(EofValidationError::EOFCREATEInvalidIndex); + } + } + opcode::DATALOADN => { + let index = unsafe { read_u16(code.as_ptr().add(i + 1)) } as isize; + if data_size < 32 || index > data_size as isize - 32 { + // data load out of bounds. + return Err(EofValidationError::DataLoadOutOfBounds); + } + } + opcode::RETF => { + stack_requirement = this_types.outputs as i32; + if this_instruction.biggest > stack_requirement { + return Err(EofValidationError::RETFBiggestStackNumMoreThenOutputs); + } + } + opcode::DUPN => { + stack_requirement = code[i + 1] as i32 + 1; + } + opcode::SWAPN => { + stack_requirement = code[i + 1] as i32 + 2; + } + opcode::EXCHANGE => { + let imm = code[i + 1]; + let n = (imm >> 4) + 1; + let m = (imm & 0x0F) + 1; + stack_requirement = n as i32 + m as i32 + 1; + } + _ => {} + } + // check if stack requirement is more than smallest stack items. + if stack_requirement > this_instruction.smallest { + // opcode requirement is more than smallest stack items. + return Err(EofValidationError::StackUnderflow); + } + + next_smallest = this_instruction.smallest + stack_io_diff; + next_biggest = this_instruction.biggest + stack_io_diff; + + // check if jumpdest are correct and mark forward jumps. + for absolute_jump in absolute_jumpdest { + if absolute_jump < 0 { + // jump out of bounds. + return Err(EofValidationError::JumpUnderflow); + } + if absolute_jump >= code.len() as isize { + // jump to out of bounds + return Err(EofValidationError::JumpOverflow); + } + // fine to cast as bounds are checked. + let absolute_jump = absolute_jump as usize; + + let target_jump = &mut jumps[absolute_jump]; + if target_jump.is_immediate { + // Jump target is immediate byte. + return Err(EofValidationError::BackwardJumpToImmediateBytes); + } + + // needed to mark forward jumps. It does not do anything for backward jumps. + target_jump.is_jumpdest = true; + + if absolute_jump <= i { + // backward jumps should have same smallest and biggest stack items. + if target_jump.biggest != next_biggest { + // wrong jumpdest. + return Err(EofValidationError::BackwardJumpBiggestNumMismatch); + } + if target_jump.smallest != next_smallest { + // wrong jumpdest. + return Err(EofValidationError::BackwardJumpSmallestNumMismatch); + } + } else { + // forward jumps can make min even smallest size + // while biggest num is needed to check stack overflow + target_jump.smallest = core::cmp::min(target_jump.smallest, next_smallest); + target_jump.biggest = core::cmp::max(target_jump.biggest, next_biggest); + } } + + // additional immediate are from RJUMPV vtable. + i += 1 + opcode.immediate_size as usize + rjumpv_additional_immediates; } - /// Returns a reference to the bytecode. - /// Note that this is the analyzed bytecode, which contains extra padding. - #[inline] - pub fn bytecode(&self) -> &Bytes { - &self.bytecode + // last opcode should be terminating + if !is_after_termination { + // wrong termination. + return Err(EofValidationError::LastInstructionNotTerminating); + } + // TODO integrate max so we dont need to iterate again + let mut max_stack_requirement = 0; + for opcode in jumps { + max_stack_requirement = core::cmp::max(opcode.biggest, max_stack_requirement); } - /// Returns the `Bytes` of the original bytecode by slicing the analyzed bytecode. - #[inline] - pub fn original_bytecode(&self) -> Bytes { - self.bytecode.slice(..self.original_len) + if max_stack_requirement != types[this_types_index].max_stack_size as i32 { + // stack overflow + return Err(EofValidationError::MaxStackMismatch); } - /// Returns the original bytecode as a byte slice. - #[inline] - pub fn original_bytecode_slice(&self) -> &[u8] { - match self.bytecode.get(..self.original_len) { - Some(slice) => slice, - None => debug_unreachable!( - "original_bytecode_slice OOB: {} > {}", - self.original_len, - self.bytecode.len() - ), - } + Ok(accessed_codes) +} + +#[cfg(test)] +mod test { + use super::*; + use revm_primitives::hex; + + #[test] + fn test1() { + // result:Result { result: false, exception: Some("EOF_ConflictingStackHeight") } + let err = + validate_raw_eof(hex!("ef0001010004020001000704000000008000016000e200fffc00").into()); + assert!(err.is_err(), "{err:#?}"); + } + + #[test] + fn test2() { + // result:Result { result: false, exception: Some("EOF_InvalidNumberOfOutputs") } + let err = + validate_raw_eof(hex!("ef000101000c02000300040004000204000000008000020002000100010001e30001005fe500025fe4").into()); + assert!(err.is_ok(), "{err:#?}"); } - /// Returns a reference to the jump map. - #[inline] - pub fn jump_map(&self) -> &JumpMap { - &self.jump_map + #[test] + fn test3() { + // result:Result { result: false, exception: Some("EOF_InvalidNumberOfOutputs") } + let err = + validate_raw_eof(hex!("ef000101000c02000300040008000304000000008000020002000503010003e30001005f5f5f5f5fe500025050e4").into()); + assert_eq!( + err, + Err(EofError::Validation( + EofValidationError::JUMPFStackHigherThanOutputs + )) + ); } } diff --git a/crates/interpreter/src/interpreter/contract.rs b/crates/interpreter/src/interpreter/contract.rs index a5896cc8..5959c7cf 100644 --- a/crates/interpreter/src/interpreter/contract.rs +++ b/crates/interpreter/src/interpreter/contract.rs @@ -1,6 +1,8 @@ -use super::analysis::{to_analysed, BytecodeLocked}; -use crate::primitives::{Address, Bytecode, Bytes, Env, TransactTo, B256, U256}; -use crate::CallContext; +use super::analysis::to_analysed; +use crate::{ + primitives::{Address, Bytecode, Bytes, Env, TransactTo, B256, U256}, + CallInputs, +}; /// EVM contract information. #[derive(Clone, Debug, Default)] @@ -9,15 +11,15 @@ pub struct Contract { pub input: Bytes, /// Bytecode contains contract code, size of original code, analysis with gas block and jump table. /// Note that current code is extended with push padding and STOP at end. - pub bytecode: BytecodeLocked, - /// Bytecode hash. - pub hash: B256, - /// Contract address - pub address: Address, + pub bytecode: Bytecode, + /// Bytecode hash for legacy. For EOF this would be None. + pub hash: Option, + /// Target address of the account. Storage of this address is going to be modified. + pub target_address: Address, /// Caller of the EVM. pub caller: Address, - /// Value send to contract. - pub value: U256, + /// Value send to contract from transaction or from CALL opcodes. + pub call_value: U256, } impl Contract { @@ -26,29 +28,29 @@ impl Contract { pub fn new( input: Bytes, bytecode: Bytecode, - hash: B256, - address: Address, + hash: Option, + target_address: Address, caller: Address, - value: U256, + call_value: U256, ) -> Self { - let bytecode = to_analysed(bytecode).try_into().expect("it is analyzed"); + let bytecode = to_analysed(bytecode); Self { input, bytecode, hash, - address, + target_address, caller, - value, + call_value, } } /// Creates a new contract from the given [`Env`]. #[inline] - pub fn new_env(env: &Env, bytecode: Bytecode, hash: B256) -> Self { + pub fn new_env(env: &Env, bytecode: Bytecode, hash: Option) -> Self { let contract_address = match env.tx.transact_to { TransactTo::Call(caller) => caller, - TransactTo::Create(..) => Address::ZERO, + TransactTo::Create => Address::ZERO, }; Self::new( env.tx.data.clone(), @@ -60,27 +62,30 @@ impl Contract { ) } - /// Creates a new contract from the given [`CallContext`]. + /// Creates a new contract from the given inputs. #[inline] pub fn new_with_context( input: Bytes, bytecode: Bytecode, - hash: B256, - call_context: &CallContext, + hash: Option, + call_context: &CallInputs, ) -> Self { Self::new( input, bytecode, hash, - call_context.address, + call_context.target_address, call_context.caller, - call_context.apparent_value, + call_context.call_value(), ) } /// Returns whether the given position is a valid jump destination. #[inline] pub fn is_valid_jump(&self, pos: usize) -> bool { - self.bytecode.jump_map().is_valid(pos) + self.bytecode + .legacy_jump_table() + .map(|i| i.is_valid(pos)) + .unwrap_or(false) } } diff --git a/crates/interpreter/src/interpreter/shared_memory.rs b/crates/interpreter/src/interpreter/shared_memory.rs index 433e24ab..3ee25bf6 100644 --- a/crates/interpreter/src/interpreter/shared_memory.rs +++ b/crates/interpreter/src/interpreter/shared_memory.rs @@ -3,7 +3,7 @@ use revm_primitives::{B256, U256}; use core::{ cmp::min, fmt, - ops::{BitAnd, Not}, + ops::{BitAnd, Not, Range}, }; use std::vec::Vec; @@ -142,13 +142,23 @@ impl SharedMemory { #[inline] #[cfg_attr(debug_assertions, track_caller)] pub fn slice(&self, offset: usize, size: usize) -> &[u8] { - let end = offset + size; + self.slice_range(offset..offset + size) + } + + #[inline] + #[cfg_attr(debug_assertions, track_caller)] + pub fn slice_range(&self, range: Range) -> &[u8] { let last_checkpoint = self.last_checkpoint; self.buffer - .get(last_checkpoint + offset..last_checkpoint + offset + size) + .get(last_checkpoint + range.start..last_checkpoint + range.end) .unwrap_or_else(|| { - debug_unreachable!("slice OOB: {offset}..{end}; len: {}", self.len()) + debug_unreachable!( + "slice OOB: {}..{}; len: {}", + range.start, + range.end, + self.len() + ) }) } @@ -259,7 +269,6 @@ impl SharedMemory { self.slice_mut(memory_offset, len).fill(0); return; } - let data_end = min(data_offset + len, data.len()); let data_len = data_end - data_offset; debug_assert!(data_offset < data.len() && data_end <= data.len()); diff --git a/crates/interpreter/src/interpreter/stack.rs b/crates/interpreter/src/interpreter/stack.rs index a15b1e9c..44dbb48a 100644 --- a/crates/interpreter/src/interpreter/stack.rs +++ b/crates/interpreter/src/interpreter/stack.rs @@ -171,6 +171,22 @@ impl Stack { (pop1, pop2, pop3, pop4) } + /// Pops 5 values from the stack. + /// + /// # Safety + /// + /// The caller is responsible for checking the length of the stack. + #[inline] + pub unsafe fn pop5_unsafe(&mut self) -> (U256, U256, U256, U256, U256) { + let pop1 = self.pop_unsafe(); + let pop2 = self.pop_unsafe(); + let pop3 = self.pop_unsafe(); + let pop4 = self.pop_unsafe(); + let pop5 = self.pop_unsafe(); + + (pop1, pop2, pop3, pop4, pop5) + } + /// Push a new value into the stack. If it will exceed the stack limit, /// returns `StackOverflow` error and leaves the stack unchanged. #[inline] @@ -207,32 +223,45 @@ impl Stack { /// Duplicates the `N`th value from the top of the stack. #[inline] - pub fn dup(&mut self) -> Result<(), InstructionResult> { + pub fn dup(&mut self, n: usize) -> Result<(), InstructionResult> { let len = self.data.len(); - if len < N { + if len < n { Err(InstructionResult::StackUnderflow) } else if len + 1 > STACK_LIMIT { Err(InstructionResult::StackOverflow) } else { // SAFETY: check for out of bounds is done above and it makes this safe to do. unsafe { - let data = self.data.as_mut_ptr(); - core::ptr::copy_nonoverlapping(data.add(len - N), data.add(len), 1); self.data.set_len(len + 1); } + self.data[len] = self.data[len - n]; Ok(()) } } /// Swaps the topmost value with the `N`th value from the top. #[inline] - pub fn swap(&mut self) -> Result<(), InstructionResult> { + pub fn swap(&mut self, n: usize) -> Result<(), InstructionResult> { + let len = self.data.len(); + if n >= len { + return Err(InstructionResult::StackUnderflow); + } + let last_index = len - 1; + self.data.swap(last_index, last_index - n); + Ok(()) + } + + /// Exchange two values on the stack. where `N` is first index and second index + /// is calculated as N+M + #[inline] + pub fn exchange(&mut self, n: usize, m: usize) -> Result<(), InstructionResult> { let len = self.data.len(); - if len <= N { + let n_m_index = n + m; + if n_m_index >= len { return Err(InstructionResult::StackUnderflow); } - let last = len - 1; - self.data.swap(last, last - N); + let last_index = len - 1; + self.data.swap(last_index - n, last_index - n_m_index); Ok(()) } diff --git a/crates/interpreter/src/interpreter_action.rs b/crates/interpreter/src/interpreter_action.rs new file mode 100644 index 00000000..a6a3aa21 --- /dev/null +++ b/crates/interpreter/src/interpreter_action.rs @@ -0,0 +1,67 @@ +mod call_inputs; +mod call_outcome; +mod create_inputs; +mod create_outcome; +mod eof_create_inputs; +mod eof_create_outcome; + +pub use call_inputs::{CallInputs, CallScheme, TransferValue}; +pub use call_outcome::CallOutcome; +pub use create_inputs::{CreateInputs, CreateScheme}; +pub use create_outcome::CreateOutcome; +pub use eof_create_inputs::EOFCreateInput; +pub use eof_create_outcome::EOFCreateOutcome; + +use crate::InterpreterResult; +use std::boxed::Box; + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub enum InterpreterAction { + /// CALL, CALLCODE, DELEGATECALL, STATICCALL + /// or EOF EXT instuction called. + Call { inputs: Box }, + /// CREATE or CREATE2 instruction called. + Create { inputs: Box }, + /// EOF CREATE instruction called. + EOFCreate { inputs: Box }, + /// Interpreter finished execution. + Return { result: InterpreterResult }, + /// No action + #[default] + None, +} + +impl InterpreterAction { + /// Returns true if action is call. + pub fn is_call(&self) -> bool { + matches!(self, InterpreterAction::Call { .. }) + } + + /// Returns true if action is create. + pub fn is_create(&self) -> bool { + matches!(self, InterpreterAction::Create { .. }) + } + + /// Returns true if action is return. + pub fn is_return(&self) -> bool { + matches!(self, InterpreterAction::Return { .. }) + } + + /// Returns true if action is none. + pub fn is_none(&self) -> bool { + matches!(self, InterpreterAction::None) + } + + /// Returns true if action is some. + pub fn is_some(&self) -> bool { + !self.is_none() + } + + /// Returns result if action is return. + pub fn into_result_return(self) -> Option { + match self { + InterpreterAction::Return { result } => Some(result), + _ => None, + } + } +} diff --git a/crates/interpreter/src/interpreter_action/call_inputs.rs b/crates/interpreter/src/interpreter_action/call_inputs.rs new file mode 100644 index 00000000..5f9cb32a --- /dev/null +++ b/crates/interpreter/src/interpreter_action/call_inputs.rs @@ -0,0 +1,99 @@ +use crate::primitives::{Address, Bytes, TransactTo, TxEnv, U256}; +use core::ops::Range; +use std::boxed::Box; + +/// Inputs for a call. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CallInputs { + /// The call data of the call. + pub input: Bytes, + /// The return memory offset where the output of the call is written. + /// For EOF this range is invalid as EOF does write output to memory. + pub return_memory_offset: Range, + /// The gas limit of the call. + pub gas_limit: u64, + /// The account address of bytecode that is going to be executed. + pub bytecode_address: Address, + /// Target address, this account storage is going to be modified. + pub target_address: Address, + /// This caller is invoking the call. + pub caller: Address, + /// Value that is transferred in Ether. + /// + /// If enum is [`TransferValue::Value`] balance is transferer from `caller` to the `target_address`. + /// + /// If enum is [`TransferValue::ApparentValue`] balance transfer is **not** + /// done and apparent value is used by CALLVALUE opcode. Used by delegate call. + pub value: TransferValue, + /// The scheme used for the call. Call, callcode, delegatecall or staticcall. + pub scheme: CallScheme, + /// Whether this is a static call. + pub is_static: bool, + /// Call is initiated from EOF bytecode. + pub is_eof: bool, +} + +impl CallInputs { + /// Creates new call inputs. + pub fn new(tx_env: &TxEnv, gas_limit: u64) -> Option { + let TransactTo::Call(target_address) = tx_env.transact_to else { + return None; + }; + + Some(CallInputs { + input: tx_env.data.clone(), + gas_limit, + target_address, + bytecode_address: target_address, + caller: tx_env.caller, + value: TransferValue::Value(tx_env.value), + scheme: CallScheme::Call, + is_static: false, + is_eof: false, + return_memory_offset: 0..0, + }) + } + + /// Returns boxed call inputs. + pub fn new_boxed(tx_env: &TxEnv, gas_limit: u64) -> Option> { + Self::new(tx_env, gas_limit).map(Box::new) + } + + /// Return call value + pub fn call_value(&self) -> U256 { + let (TransferValue::Value(value) | TransferValue::ApparentValue(value)) = self.value; + value + } +} + +/// Call schemes. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum CallScheme { + /// `CALL`. + Call, + /// `CALLCODE` + CallCode, + /// `DELEGATECALL` + DelegateCall, + /// `STATICCALL` + StaticCall, +} + +/// Transfered value from caller to callee. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum TransferValue { + /// Transfer value from caller to callee. + Value(U256), + /// For delegate call, the value is not transferred but + /// apparent value is used for CALLVALUE opcode + ApparentValue(U256), +} + +impl Default for TransferValue { + fn default() -> Self { + TransferValue::Value(U256::ZERO) + } +} diff --git a/crates/interpreter/src/call_outcome.rs b/crates/interpreter/src/interpreter_action/call_outcome.rs similarity index 100% rename from crates/interpreter/src/call_outcome.rs rename to crates/interpreter/src/interpreter_action/call_outcome.rs diff --git a/crates/interpreter/src/interpreter_action/create_inputs.rs b/crates/interpreter/src/interpreter_action/create_inputs.rs new file mode 100644 index 00000000..6db95183 --- /dev/null +++ b/crates/interpreter/src/interpreter_action/create_inputs.rs @@ -0,0 +1,51 @@ +pub use crate::primitives::CreateScheme; +use crate::primitives::{Address, Bytes, TransactTo, TxEnv, U256}; +use std::boxed::Box; + +/// Inputs for a create call. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CreateInputs { + /// Caller address of the EVM. + pub caller: Address, + /// The create scheme. + pub scheme: CreateScheme, + /// The value to transfer. + pub value: U256, + /// The init code of the contract. + pub init_code: Bytes, + /// The gas limit of the call. + pub gas_limit: u64, +} + +impl CreateInputs { + /// Creates new create inputs. + pub fn new(tx_env: &TxEnv, gas_limit: u64) -> Option { + let TransactTo::Create = tx_env.transact_to else { + return None; + }; + + Some(CreateInputs { + caller: tx_env.caller, + scheme: CreateScheme::Create, + value: tx_env.value, + init_code: tx_env.data.clone(), + gas_limit, + }) + } + + /// Returns boxed create inputs. + pub fn new_boxed(tx_env: &TxEnv, gas_limit: u64) -> Option> { + Self::new(tx_env, gas_limit).map(Box::new) + } + + /// Returns the address that this create call will create. + pub fn created_address(&self, nonce: u64) -> Address { + match self.scheme { + CreateScheme::Create => self.caller.create(nonce), + CreateScheme::Create2 { salt } => self + .caller + .create2_from_code(salt.to_be_bytes(), &self.init_code), + } + } +} diff --git a/crates/interpreter/src/create_outcome.rs b/crates/interpreter/src/interpreter_action/create_outcome.rs similarity index 100% rename from crates/interpreter/src/create_outcome.rs rename to crates/interpreter/src/interpreter_action/create_outcome.rs diff --git a/crates/interpreter/src/interpreter_action/eof_create_inputs.rs b/crates/interpreter/src/interpreter_action/eof_create_inputs.rs new file mode 100644 index 00000000..a5ce043c --- /dev/null +++ b/crates/interpreter/src/interpreter_action/eof_create_inputs.rs @@ -0,0 +1,41 @@ +use crate::primitives::{Address, Eof, U256}; +use core::ops::Range; + +/// Inputs for EOF create call. +#[derive(Debug, Default, Clone, PartialEq, Eq)] +pub struct EOFCreateInput { + /// Caller of Eof Craate + pub caller: Address, + /// New contract address. + pub created_address: Address, + /// Values of ether transfered + pub value: U256, + /// Init eof code that is going to be executed. + pub eof_init_code: Eof, + /// Gas limit for the create call. + pub gas_limit: u64, + /// Return memory range. If EOF creation Reverts it can return the + /// the memory range. + pub return_memory_range: Range, +} + +impl EOFCreateInput { + /// Returns a new instance of EOFCreateInput. + pub fn new( + caller: Address, + created_address: Address, + value: U256, + eof_init_code: Eof, + gas_limit: u64, + return_memory_range: Range, + ) -> EOFCreateInput { + EOFCreateInput { + caller, + created_address, + value, + eof_init_code, + gas_limit, + return_memory_range, + } + } +} diff --git a/crates/interpreter/src/interpreter_action/eof_create_outcome.rs b/crates/interpreter/src/interpreter_action/eof_create_outcome.rs new file mode 100644 index 00000000..031e1180 --- /dev/null +++ b/crates/interpreter/src/interpreter_action/eof_create_outcome.rs @@ -0,0 +1,87 @@ +use core::ops::Range; + +use crate::{Gas, InstructionResult, InterpreterResult}; +use revm_primitives::{Address, Bytes}; + +/// Represents the outcome of a create operation in an interpreter. +/// +/// This struct holds the result of the operation along with an optional address. +/// It provides methods to determine the next action based on the result of the operation. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct EOFCreateOutcome { + /// The result of the interpreter operation. + pub result: InterpreterResult, + /// An optional address associated with the create operation. + pub address: Address, + /// Return memory range. If EOF creation Reverts it can return bytes from the memory. + pub return_memory_range: Range, +} + +impl EOFCreateOutcome { + /// Constructs a new [`EOFCreateOutcome`]. + /// + /// # Arguments + /// + /// * `result` - An `InterpreterResult` representing the result of the interpreter operation. + /// * `address` - An optional `Address` associated with the create operation. + /// * `return_memory_range` - The memory range that Revert bytes are going to be written. + /// + /// # Returns + /// + /// A new [`EOFCreateOutcome`] instance. + pub fn new( + result: InterpreterResult, + address: Address, + return_memory_range: Range, + ) -> Self { + Self { + result, + address, + return_memory_range, + } + } + + /// Retrieves a reference to the [`InstructionResult`] from the [`InterpreterResult`]. + /// + /// This method provides access to the `InstructionResult` which represents the + /// outcome of the instruction execution. It encapsulates the result information + /// such as whether the instruction was executed successfully, resulted in a revert, + /// or encountered a fatal error. + /// + /// # Returns + /// + /// A reference to the `InstructionResult`. + pub fn instruction_result(&self) -> &InstructionResult { + &self.result.result + } + + /// Retrieves a reference to the output bytes from the `InterpreterResult`. + /// + /// This method returns the output of the interpreted operation. The output is + /// typically used when the operation successfully completes and returns data. + /// + /// # Returns + /// + /// A reference to the output `Bytes`. + pub fn output(&self) -> &Bytes { + &self.result.output + } + + /// Retrieves a reference to the `Gas` details from the `InterpreterResult`. + /// + /// This method provides access to the gas details of the operation, which includes + /// information about gas used, remaining, and refunded. It is essential for + /// understanding the gas consumption of the operation. + /// + /// # Returns + /// + /// A reference to the `Gas` details. + pub fn gas(&self) -> &Gas { + &self.result.gas + } + + /// Returns the memory range that Revert bytes are going to be written. + pub fn return_range(&self) -> Range { + self.return_memory_range.clone() + } +} diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index c70c25cd..7d749fb9 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -12,27 +12,36 @@ extern crate alloc as std; #[macro_use] mod macros; -mod call_outcome; -mod create_outcome; +// silence lint +#[cfg(test)] +use serde_json as _; + +#[cfg(test)] +use walkdir as _; + +mod function_stack; pub mod gas; mod host; -mod inner_models; mod instruction_result; pub mod instructions; pub mod interpreter; +pub mod interpreter_action; +pub mod opcode; // Reexport primary types. -pub use call_outcome::CallOutcome; -pub use create_outcome::CreateOutcome; +pub use function_stack::{FunctionReturnFrame, FunctionStack}; pub use gas::Gas; -pub use host::{DummyHost, Host, SStoreResult}; -pub use inner_models::*; +pub use host::{DummyHost, Host, LoadAccountResult, SStoreResult, SelfDestructResult}; pub use instruction_result::*; -pub use instructions::{opcode, Instruction, OpCode, OPCODE_JUMPMAP}; pub use interpreter::{ - analysis, next_multiple_of_32, BytecodeLocked, Contract, Interpreter, InterpreterAction, - InterpreterResult, SharedMemory, Stack, EMPTY_SHARED_MEMORY, STACK_LIMIT, + analysis, next_multiple_of_32, Contract, Interpreter, InterpreterResult, SharedMemory, Stack, + EMPTY_SHARED_MEMORY, STACK_LIMIT, +}; +pub use interpreter_action::{ + CallInputs, CallOutcome, CallScheme, CreateInputs, CreateOutcome, CreateScheme, EOFCreateInput, + EOFCreateOutcome, InterpreterAction, TransferValue, }; +pub use opcode::{Instruction, OpCode, OPCODE_INFO_JUMPTABLE}; pub use primitives::{MAX_CODE_SIZE, MAX_INITCODE_SIZE}; #[doc(hidden)] diff --git a/crates/interpreter/src/opcode.rs b/crates/interpreter/src/opcode.rs new file mode 100644 index 00000000..401c7c37 --- /dev/null +++ b/crates/interpreter/src/opcode.rs @@ -0,0 +1,745 @@ +//! EVM opcode definitions and utilities. + +pub mod eof_printer; + +use crate::{instructions::*, primitives::Spec, Host, Interpreter}; +use core::fmt; +use std::boxed::Box; + +/// EVM opcode function signature. +pub type Instruction = fn(&mut Interpreter, &mut H); + +/// Instruction table is list of instruction function pointers mapped to +/// 256 EVM opcodes. +pub type InstructionTable = [Instruction; 256]; + +/// EVM opcode function signature. +pub type BoxedInstruction<'a, H> = Box; + +/// A table of instructions. +pub type BoxedInstructionTable<'a, H> = [BoxedInstruction<'a, H>; 256]; + +/// Instruction set that contains plain instruction table that contains simple `fn` function pointer. +/// and Boxed `Fn` variant that contains `Box` function pointer that can be used with closured. +/// +/// Note that `Plain` variant gives us 10-20% faster Interpreter execution. +/// +/// Boxed variant can be used to wrap plain function pointer with closure. +pub enum InstructionTables<'a, H> { + Plain(InstructionTable), + Boxed(BoxedInstructionTable<'a, H>), +} + +impl InstructionTables<'_, H> { + /// Creates a plain instruction table for the given spec. + #[inline] + pub const fn new_plain() -> Self { + Self::Plain(make_instruction_table::()) + } +} + +impl<'a, H: Host + 'a> InstructionTables<'a, H> { + /// Inserts a boxed instruction into the table with the specified index. + /// + /// This will convert the table into the [BoxedInstructionTable] variant if it is currently a + /// plain instruction table, before inserting the instruction. + #[inline] + pub fn insert_boxed(&mut self, opcode: u8, instruction: BoxedInstruction<'a, H>) { + // first convert the table to boxed variant + self.convert_boxed(); + + // now we can insert the instruction + match self { + Self::Plain(_) => { + unreachable!("we already converted the table to boxed variant"); + } + Self::Boxed(table) => { + table[opcode as usize] = Box::new(instruction); + } + } + } + + /// Inserts the instruction into the table with the specified index. + #[inline] + pub fn insert(&mut self, opcode: u8, instruction: Instruction) { + match self { + Self::Plain(table) => { + table[opcode as usize] = instruction; + } + Self::Boxed(table) => { + table[opcode as usize] = Box::new(instruction); + } + } + } + + /// Converts the current instruction table to a boxed variant. If the table is already boxed, + /// this is a no-op. + #[inline] + pub fn convert_boxed(&mut self) { + match self { + Self::Plain(table) => { + *self = Self::Boxed(core::array::from_fn(|i| { + let instruction: BoxedInstruction<'a, H> = Box::new(table[i]); + instruction + })); + } + Self::Boxed(_) => {} + }; + } +} + +/// Make instruction table. +#[inline] +pub const fn make_instruction_table() -> InstructionTable { + // Force const-eval of the table creation, making this function trivial. + // TODO: Replace this with a `const {}` block once it is stable. + struct ConstTable { + _host: core::marker::PhantomData, + _spec: core::marker::PhantomData, + } + impl ConstTable { + const NEW: InstructionTable = { + let mut tables: InstructionTable = [control::unknown; 256]; + let mut i = 0; + while i < 256 { + tables[i] = instruction::(i as u8); + i += 1; + } + tables + }; + } + ConstTable::::NEW +} + +/// Make boxed instruction table that calls `outer` closure for every instruction. +#[inline] +pub fn make_boxed_instruction_table<'a, H, SPEC, FN>( + table: InstructionTable, + mut outer: FN, +) -> BoxedInstructionTable<'a, H> +where + H: Host, + SPEC: Spec + 'a, + FN: FnMut(Instruction) -> BoxedInstruction<'a, H>, +{ + core::array::from_fn(|i| outer(table[i])) +} + +/// An EVM opcode. +/// +/// This is always a valid opcode, as declared in the [`opcode`][self] module or the +/// [`OPCODE_INFO_JUMPTABLE`] constant. +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(transparent)] +pub struct OpCode(u8); + +impl fmt::Display for OpCode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let n = self.get(); + if let Some(val) = OPCODE_INFO_JUMPTABLE[n as usize] { + f.write_str(val.name) + } else { + write!(f, "UNKNOWN(0x{n:02X})") + } + } +} + +impl OpCode { + /// Instantiate a new opcode from a u8. + #[inline] + pub const fn new(opcode: u8) -> Option { + match OPCODE_INFO_JUMPTABLE[opcode as usize] { + Some(_) => Some(Self(opcode)), + None => None, + } + } + + /// Returns true if the opcode is a jump destination. + #[inline] + pub const fn is_jumpdest(&self) -> bool { + self.0 == JUMPDEST + } + + /// Takes a u8 and returns true if it is a jump destination. + #[inline] + pub const fn is_jumpdest_by_op(opcode: u8) -> bool { + if let Some(opcode) = Self::new(opcode) { + opcode.is_jumpdest() + } else { + false + } + } + + /// Returns true if the opcode is a legacy jump instruction. + #[inline] + pub const fn is_jump(self) -> bool { + self.0 == JUMP + } + + /// Takes a u8 and returns true if it is a jump instruction. + #[inline] + pub const fn is_jump_by_op(opcode: u8) -> bool { + if let Some(opcode) = Self::new(opcode) { + opcode.is_jump() + } else { + false + } + } + + /// Returns true if the opcode is a push instruction. + #[inline] + pub const fn is_push(self) -> bool { + self.0 >= PUSH1 && self.0 <= PUSH32 + } + + /// Takes a u8 and returns true if it is a push instruction. + #[inline] + pub fn is_push_by_op(opcode: u8) -> bool { + if let Some(opcode) = Self::new(opcode) { + opcode.is_push() + } else { + false + } + } + + /// Instantiate a new opcode from a u8 without checking if it is valid. + /// + /// # Safety + /// + /// All code using `Opcode` values assume that they are valid opcodes, so providing an invalid + /// opcode may cause undefined behavior. + #[inline] + pub unsafe fn new_unchecked(opcode: u8) -> Self { + Self(opcode) + } + + /// Returns the opcode as a string. + #[inline] + pub const fn as_str(self) -> &'static str { + self.info().name + } + + /// Returns the opcode name. + #[inline] + pub const fn name_by_op(opcode: u8) -> &'static str { + if let Some(opcode) = Self::new(opcode) { + opcode.as_str() + } else { + "Unknown" + } + } + + /// Returns inputs for the given opcode. + pub const fn inputs(&self) -> u8 { + self.info().inputs + } + + /// Returns outputs for the given opcode. + pub const fn outputs(&self) -> u8 { + self.info().outputs + } + + /// Returns a difference between input and output. + pub const fn io_diff(&self) -> i16 { + self.info().io_diff() + } + + pub const fn info_by_op(opcode: u8) -> Option { + if let Some(opcode) = Self::new(opcode) { + Some(opcode.info()) + } else { + None + } + } + + #[inline] + pub const fn info(&self) -> OpCodeInfo { + if let Some(t) = OPCODE_INFO_JUMPTABLE[self.0 as usize] { + t + } else { + panic!("unreachable, all opcodes are defined") + } + } + + /// Returns a tuple of input and output. + /// Can be slightly faster that calling `inputs` and `outputs` separately. + pub const fn input_output(&self) -> (u8, u8) { + let info = self.info(); + (info.inputs, info.outputs) + } + + /// Returns the opcode as a u8. + #[inline] + pub const fn get(self) -> u8 { + self.0 + } +} + +/// Information about opcode, such as name, and stack inputs and outputs. +#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct OpCodeInfo { + pub name: &'static str, + pub inputs: u8, + pub outputs: u8, + // TODO make this a bitfield + pub is_eof: bool, + // If the opcode is return from execution. aka STOP,RETURN, .. + pub is_terminating_opcode: bool, + /// Size of opcode with its intermediate bytes. + /// + /// RJUMPV is special case where the bytes len is depending on bytecode value, + /// for RJUMV size will be set to one byte while minimum is two. + pub immediate_size: u8, +} + +impl OpCodeInfo { + pub const fn new(name: &'static str) -> Self { + Self { + name, + inputs: 0, + outputs: 0, + is_eof: true, + is_terminating_opcode: false, + immediate_size: 0, + } + } + + pub const fn io_diff(&self) -> i16 { + self.outputs as i16 - self.inputs as i16 + } +} + +pub const NOP: u8 = JUMPDEST; + +macro_rules! opcodes { + ($($val:literal => $name:ident => $f:expr => $($modifier:ident $(< $($modifier_num:literal),* >)?),*);* $(;)?) => { + // Constants for each opcode. This also takes care of duplicate names. + $( + #[doc = concat!("The `", stringify!($val), "` (\"", stringify!($name),"\") opcode.")] + pub const $name: u8 = $val; + )* + impl OpCode {$( + #[doc = concat!("The `", stringify!($val), "` (\"", stringify!($name),"\") opcode.")] + pub const $name: Self = Self($val); + )*} + + /// Maps each opcode to its name. + pub const OPCODE_INFO_JUMPTABLE: [Option; 256] = { + let mut map = [None; 256]; + let mut prev: u8 = 0; + $( + let val: u8 = $val; + assert!(val == 0 || val > prev, "opcodes must be sorted in ascending order"); + prev = val; + let opcode = OpCodeInfo::new(stringify!($name)); + $( let opcode = $modifier$(::< $( $modifier_num ),+ >)? (opcode);)* + map[$val] = Some(opcode); + )* + let _ = prev; + map + }; + + /// Returns the instruction function for the given opcode and spec. + pub const fn instruction(opcode: u8) -> Instruction { + match opcode { + $($name => $f,)* + _ => control::unknown, + } + } + }; +} + +pub const fn not_eof(mut opcode: OpCodeInfo) -> OpCodeInfo { + opcode.is_eof = false; + opcode +} + +/// Immediate bytes after opcode. +pub const fn imm_size(mut opcode: OpCodeInfo) -> OpCodeInfo { + opcode.immediate_size = N; + opcode +} + +pub const fn terminating(mut opcode: OpCodeInfo) -> OpCodeInfo { + opcode.is_terminating_opcode = true; + opcode +} + +pub const fn stack_io(mut opcode: OpCodeInfo) -> OpCodeInfo { + opcode.inputs = I; + opcode.outputs = O; + opcode +} + +// When adding new opcodes: +// 1. add the opcode to the list below; make sure it's sorted by opcode value +// 2. add its gas info in the `opcode_gas_info` function below +// 3. implement the opcode in the corresponding module; +// the function signature must be the exact same as the others +opcodes! { + 0x00 => STOP => control::stop => stack_io<0,0>, terminating; + + 0x01 => ADD => arithmetic::wrapping_add => stack_io<2, 1>; + 0x02 => MUL => arithmetic::wrapping_mul => stack_io<2, 1>; + 0x03 => SUB => arithmetic::wrapping_sub => stack_io<2, 1>; + 0x04 => DIV => arithmetic::div => stack_io<2, 1>; + 0x05 => SDIV => arithmetic::sdiv => stack_io<2, 1>; + 0x06 => MOD => arithmetic::rem => stack_io<2, 1>; + 0x07 => SMOD => arithmetic::smod => stack_io<2, 1>; + 0x08 => ADDMOD => arithmetic::addmod => stack_io<3, 1>; + 0x09 => MULMOD => arithmetic::mulmod => stack_io<3, 1>; + 0x0A => EXP => arithmetic::exp:: => stack_io<2, 1>; + 0x0B => SIGNEXTEND => arithmetic::signextend => stack_io<2, 1>; + // 0x0C + // 0x0D + // 0x0E + // 0x0F + 0x10 => LT => bitwise::lt => stack_io<2, 1>; + 0x11 => GT => bitwise::gt => stack_io<2, 1>; + 0x12 => SLT => bitwise::slt => stack_io<2, 1>; + 0x13 => SGT => bitwise::sgt => stack_io<2, 1>; + 0x14 => EQ => bitwise::eq => stack_io<2, 1>; + 0x15 => ISZERO => bitwise::iszero => stack_io<1, 1>; + 0x16 => AND => bitwise::bitand => stack_io<2, 1>; + 0x17 => OR => bitwise::bitor => stack_io<2, 1>; + 0x18 => XOR => bitwise::bitxor => stack_io<2, 1>; + 0x19 => NOT => bitwise::not => stack_io<1, 1>; + 0x1A => BYTE => bitwise::byte => stack_io<2, 1>; + 0x1B => SHL => bitwise::shl:: => stack_io<2, 1>; + 0x1C => SHR => bitwise::shr:: => stack_io<2, 1>; + 0x1D => SAR => bitwise::sar:: => stack_io<2, 1>; + // 0x1E + // 0x1F + 0x20 => KECCAK256 => system::keccak256 => stack_io<2, 1>; + // 0x21 + // 0x22 + // 0x23 + // 0x24 + // 0x25 + // 0x26 + // 0x27 + // 0x28 + // 0x29 + // 0x2A + // 0x2B + // 0x2C + // 0x2D + // 0x2E + // 0x2F + 0x30 => ADDRESS => system::address => stack_io<0, 1>; + 0x31 => BALANCE => host::balance:: => stack_io<1, 1>; + 0x32 => ORIGIN => host_env::origin => stack_io<0, 1>; + 0x33 => CALLER => system::caller => stack_io<0, 1>; + 0x34 => CALLVALUE => system::callvalue => stack_io<0, 1>; + 0x35 => CALLDATALOAD => system::calldataload => stack_io<1, 1>; + 0x36 => CALLDATASIZE => system::calldatasize => stack_io<0, 1>; + 0x37 => CALLDATACOPY => system::calldatacopy => stack_io<3, 1>; + 0x38 => CODESIZE => system::codesize => stack_io<0, 1>, not_eof; + 0x39 => CODECOPY => system::codecopy => stack_io<3, 0>, not_eof; + + 0x3A => GASPRICE => host_env::gasprice => stack_io<0, 1>; + 0x3B => EXTCODESIZE => host::extcodesize:: => stack_io<1, 1>, not_eof; + 0x3C => EXTCODECOPY => host::extcodecopy:: => stack_io<4, 0>, not_eof; + 0x3D => RETURNDATASIZE => system::returndatasize:: => stack_io<0, 1>; + 0x3E => RETURNDATACOPY => system::returndatacopy:: => stack_io<3, 0>; + 0x3F => EXTCODEHASH => host::extcodehash:: => stack_io<1, 1>, not_eof; + 0x40 => BLOCKHASH => host::blockhash => stack_io<1, 1>; + 0x41 => COINBASE => host_env::coinbase => stack_io<0, 1>; + 0x42 => TIMESTAMP => host_env::timestamp => stack_io<0, 1>; + 0x43 => NUMBER => host_env::block_number => stack_io<0, 1>; + 0x44 => DIFFICULTY => host_env::difficulty:: => stack_io<0, 1>; + 0x45 => GASLIMIT => host_env::gaslimit => stack_io<0, 1>; + 0x46 => CHAINID => host_env::chainid:: => stack_io<0, 1>; + 0x47 => SELFBALANCE => host::selfbalance:: => stack_io<0, 1>; + 0x48 => BASEFEE => host_env::basefee:: => stack_io<0, 1>; + 0x49 => BLOBHASH => host_env::blob_hash:: => stack_io<1, 1>; + 0x4A => BLOBBASEFEE => host_env::blob_basefee:: => stack_io<0, 1>; + // 0x4B + // 0x4C + // 0x4D + // 0x4E + // 0x4F + 0x50 => POP => stack::pop => stack_io<1, 0>; + 0x51 => MLOAD => memory::mload => stack_io<1, 1>; + 0x52 => MSTORE => memory::mstore => stack_io<2, 0>; + 0x53 => MSTORE8 => memory::mstore8 => stack_io<2, 0>; + 0x54 => SLOAD => host::sload:: => stack_io<1, 1>; + 0x55 => SSTORE => host::sstore:: => stack_io<2, 0>; + 0x56 => JUMP => control::jump => stack_io<1, 0>, not_eof; + 0x57 => JUMPI => control::jumpi => stack_io<2, 0>, not_eof; + 0x58 => PC => control::pc => stack_io<0, 1>, not_eof; + 0x59 => MSIZE => memory::msize => stack_io<0, 1>; + 0x5A => GAS => system::gas => stack_io<0, 1>, not_eof; + 0x5B => JUMPDEST => control::jumpdest_or_nop => stack_io<0, 0>; + 0x5C => TLOAD => host::tload:: => stack_io<1, 1>; + 0x5D => TSTORE => host::tstore:: => stack_io<2, 0>; + 0x5E => MCOPY => memory::mcopy:: => stack_io<3, 0>; + + 0x5F => PUSH0 => stack::push0:: => stack_io<0, 1>; + 0x60 => PUSH1 => stack::push::<1, H> => stack_io<0, 1>, imm_size<1>; + 0x61 => PUSH2 => stack::push::<2, H> => stack_io<0, 1>, imm_size<2>; + 0x62 => PUSH3 => stack::push::<3, H> => stack_io<0, 1>, imm_size<3>; + 0x63 => PUSH4 => stack::push::<4, H> => stack_io<0, 1>, imm_size<4>; + 0x64 => PUSH5 => stack::push::<5, H> => stack_io<0, 1>, imm_size<5>; + 0x65 => PUSH6 => stack::push::<6, H> => stack_io<0, 1>, imm_size<6>; + 0x66 => PUSH7 => stack::push::<7, H> => stack_io<0, 1>, imm_size<7>; + 0x67 => PUSH8 => stack::push::<8, H> => stack_io<0, 1>, imm_size<8>; + 0x68 => PUSH9 => stack::push::<9, H> => stack_io<0, 1>, imm_size<9>; + 0x69 => PUSH10 => stack::push::<10, H> => stack_io<0, 1>, imm_size<10>; + 0x6A => PUSH11 => stack::push::<11, H> => stack_io<0, 1>, imm_size<11>; + 0x6B => PUSH12 => stack::push::<12, H> => stack_io<0, 1>, imm_size<12>; + 0x6C => PUSH13 => stack::push::<13, H> => stack_io<0, 1>, imm_size<13>; + 0x6D => PUSH14 => stack::push::<14, H> => stack_io<0, 1>, imm_size<14>; + 0x6E => PUSH15 => stack::push::<15, H> => stack_io<0, 1>, imm_size<15>; + 0x6F => PUSH16 => stack::push::<16, H> => stack_io<0, 1>, imm_size<16>; + 0x70 => PUSH17 => stack::push::<17, H> => stack_io<0, 1>, imm_size<17>; + 0x71 => PUSH18 => stack::push::<18, H> => stack_io<0, 1>, imm_size<18>; + 0x72 => PUSH19 => stack::push::<19, H> => stack_io<0, 1>, imm_size<19>; + 0x73 => PUSH20 => stack::push::<20, H> => stack_io<0, 1>, imm_size<20>; + 0x74 => PUSH21 => stack::push::<21, H> => stack_io<0, 1>, imm_size<21>; + 0x75 => PUSH22 => stack::push::<22, H> => stack_io<0, 1>, imm_size<22>; + 0x76 => PUSH23 => stack::push::<23, H> => stack_io<0, 1>, imm_size<23>; + 0x77 => PUSH24 => stack::push::<24, H> => stack_io<0, 1>, imm_size<24>; + 0x78 => PUSH25 => stack::push::<25, H> => stack_io<0, 1>, imm_size<25>; + 0x79 => PUSH26 => stack::push::<26, H> => stack_io<0, 1>, imm_size<26>; + 0x7A => PUSH27 => stack::push::<27, H> => stack_io<0, 1>, imm_size<27>; + 0x7B => PUSH28 => stack::push::<28, H> => stack_io<0, 1>, imm_size<28>; + 0x7C => PUSH29 => stack::push::<29, H> => stack_io<0, 1>, imm_size<29>; + 0x7D => PUSH30 => stack::push::<30, H> => stack_io<0, 1>, imm_size<30>; + 0x7E => PUSH31 => stack::push::<31, H> => stack_io<0, 1>, imm_size<31>; + 0x7F => PUSH32 => stack::push::<32, H> => stack_io<0, 1>, imm_size<32>; + + 0x80 => DUP1 => stack::dup::<1, H> => stack_io<1, 2>; + 0x81 => DUP2 => stack::dup::<2, H> => stack_io<2, 3>; + 0x82 => DUP3 => stack::dup::<3, H> => stack_io<3, 4>; + 0x83 => DUP4 => stack::dup::<4, H> => stack_io<4, 5>; + 0x84 => DUP5 => stack::dup::<5, H> => stack_io<5, 6>; + 0x85 => DUP6 => stack::dup::<6, H> => stack_io<6, 7>; + 0x86 => DUP7 => stack::dup::<7, H> => stack_io<7, 8>; + 0x87 => DUP8 => stack::dup::<8, H> => stack_io<8, 9>; + 0x88 => DUP9 => stack::dup::<9, H> => stack_io<9, 10>; + 0x89 => DUP10 => stack::dup::<10, H> => stack_io<10, 11>; + 0x8A => DUP11 => stack::dup::<11, H> => stack_io<11, 12>; + 0x8B => DUP12 => stack::dup::<12, H> => stack_io<12, 13>; + 0x8C => DUP13 => stack::dup::<13, H> => stack_io<13, 14>; + 0x8D => DUP14 => stack::dup::<14, H> => stack_io<14, 15>; + 0x8E => DUP15 => stack::dup::<15, H> => stack_io<15, 16>; + 0x8F => DUP16 => stack::dup::<16, H> => stack_io<16, 17>; + + 0x90 => SWAP1 => stack::swap::<1, H> => stack_io<2, 2>; + 0x91 => SWAP2 => stack::swap::<2, H> => stack_io<3, 3>; + 0x92 => SWAP3 => stack::swap::<3, H> => stack_io<4, 4>; + 0x93 => SWAP4 => stack::swap::<4, H> => stack_io<5, 5>; + 0x94 => SWAP5 => stack::swap::<5, H> => stack_io<6, 6>; + 0x95 => SWAP6 => stack::swap::<6, H> => stack_io<7, 7>; + 0x96 => SWAP7 => stack::swap::<7, H> => stack_io<8, 8>; + 0x97 => SWAP8 => stack::swap::<8, H> => stack_io<9, 9>; + 0x98 => SWAP9 => stack::swap::<9, H> => stack_io<10, 10>; + 0x99 => SWAP10 => stack::swap::<10, H> => stack_io<11, 11>; + 0x9A => SWAP11 => stack::swap::<11, H> => stack_io<12, 12>; + 0x9B => SWAP12 => stack::swap::<12, H> => stack_io<13, 13>; + 0x9C => SWAP13 => stack::swap::<13, H> => stack_io<14, 14>; + 0x9D => SWAP14 => stack::swap::<14, H> => stack_io<15, 15>; + 0x9E => SWAP15 => stack::swap::<15, H> => stack_io<16, 16>; + 0x9F => SWAP16 => stack::swap::<16, H> => stack_io<17, 17>; + + 0xA0 => LOG0 => host::log::<0, H> => stack_io<2, 0>; + 0xA1 => LOG1 => host::log::<1, H> => stack_io<3, 0>; + 0xA2 => LOG2 => host::log::<2, H> => stack_io<4, 0>; + 0xA3 => LOG3 => host::log::<3, H> => stack_io<5, 0>; + 0xA4 => LOG4 => host::log::<4, H> => stack_io<6, 0>; + // 0xA5 + // 0xA6 + // 0xA7 + // 0xA8 + // 0xA9 + // 0xAA + // 0xAB + // 0xAC + // 0xAD + // 0xAE + // 0xAF + // 0xB0 + // 0xB1 + // 0xB2 + // 0xB3 + // 0xB4 + // 0xB5 + // 0xB6 + // 0xB7 + // 0xB8 + // 0xB9 + // 0xBA + // 0xBB + // 0xBC + // 0xBD + // 0xBE + // 0xBF + // 0xC0 + // 0xC1 + // 0xC2 + // 0xC3 + // 0xC4 + // 0xC5 + // 0xC6 + // 0xC7 + // 0xC8 + // 0xC9 + // 0xCA + // 0xCB + // 0xCC + // 0xCD + // 0xCE + // 0xCF + 0xD0 => DATALOAD => data::data_load => stack_io<1, 1>; + 0xD1 => DATALOADN => data::data_loadn => stack_io<0, 1>, imm_size<2>; + 0xD2 => DATASIZE => data::data_size => stack_io<0, 1>; + 0xD3 => DATACOPY => data::data_copy => stack_io<3, 0>; + // 0xD4 + // 0xD5 + // 0xD6 + // 0xD7 + // 0xD8 + // 0xD9 + // 0xDA + // 0xDB + // 0xDC + // 0xDD + // 0xDE + // 0xDF + 0xE0 => RJUMP => control::rjump => stack_io<0, 0>, imm_size<2>, terminating; + 0xE1 => RJUMPI => control::rjumpi => stack_io<1, 0>, imm_size<2>; + 0xE2 => RJUMPV => control::rjumpv => stack_io<1, 0>, imm_size<1>; + 0xE3 => CALLF => control::callf => stack_io<0, 0>, imm_size<2>; + 0xE4 => RETF => control::retf => stack_io<0, 0>, terminating; + 0xE5 => JUMPF => control::jumpf => stack_io<0, 0>, imm_size<2>, terminating; + 0xE6 => DUPN => stack::dupn => stack_io<0, 1>, imm_size<1>; + 0xE7 => SWAPN => stack::swapn => stack_io<0, 0>, imm_size<1>; + 0xE8 => EXCHANGE => stack::exchange => stack_io<0, 0>, imm_size<1>; + // 0xE9 + // 0xEA + // 0xEB + 0xEC => EOFCREATE => contract::eofcreate:: => stack_io<4, 1>, imm_size<1>; + 0xED => TXCREATE => contract::txcreate:: => stack_io<5, 1>; + 0xEE => RETURNCONTRACT => contract::return_contract:: => stack_io<2, 0>, imm_size<1>, terminating; + // 0xEF + 0xF0 => CREATE => contract::create:: => stack_io<4, 1>, not_eof; + 0xF1 => CALL => contract::call:: => stack_io<7, 1>, not_eof; + 0xF2 => CALLCODE => contract::call_code:: => stack_io<7, 1>, not_eof; + 0xF3 => RETURN => control::ret => stack_io<2, 0>, terminating; + 0xF4 => DELEGATECALL => contract::delegate_call:: => stack_io<6, 1>, not_eof; + 0xF5 => CREATE2 => contract::create:: => stack_io<5, 1>, not_eof; + // 0xF6 + 0xF7 => RETURNDATALOAD => system::returndataload:: => stack_io<1, 1>; + 0xF8 => EXTCALL => contract::extcall:: => stack_io<4, 1>; + 0xF9 => EXFCALL => contract::extdcall:: => stack_io<3, 1>; + 0xFA => STATICCALL => contract::static_call:: => stack_io<6, 1>, not_eof; + 0xFB => EXTSCALL => contract::extscall:: => stack_io<3, 1>; + // 0xFC + 0xFD => REVERT => control::revert:: => stack_io<2, 0>, terminating; + 0xFE => INVALID => control::invalid => stack_io<0, 0>, terminating; + 0xFF => SELFDESTRUCT => host::selfdestruct:: => stack_io<1, 0>, not_eof, terminating; +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_opcode() { + let opcode = OpCode::new(0x00).unwrap(); + assert!(!opcode.is_jumpdest()); + assert!(!opcode.is_jump()); + assert!(!opcode.is_push()); + assert_eq!(opcode.as_str(), "STOP"); + assert_eq!(opcode.get(), 0x00); + } + + const REJECTED_IN_EOF: &[u8] = &[ + 0x38, 0x39, 0x3b, 0x3c, 0x3f, 0x5a, 0xf1, 0xf2, 0xf4, 0xfa, 0xff, + ]; + + #[test] + fn test_eof_disable() { + for opcode in REJECTED_IN_EOF.iter() { + let opcode = OpCode::new(*opcode).unwrap(); + assert!(!opcode.info().is_eof, "Opcode {:?} is not EOF", opcode); + } + } + + #[test] + fn test_imm_size() { + let mut opcodes = [0u8; 256]; + // PUSH opcodes + for push in PUSH1..PUSH32 { + opcodes[push as usize] = push - PUSH1 + 1; + } + opcodes[DATALOADN as usize] = 2; + opcodes[RJUMP as usize] = 2; + opcodes[RJUMPI as usize] = 2; + opcodes[RJUMPV as usize] = 2; + opcodes[CALLF as usize] = 2; + opcodes[JUMPF as usize] = 2; + opcodes[DUPN as usize] = 1; + opcodes[SWAPN as usize] = 1; + opcodes[EXCHANGE as usize] = 1; + } + + #[test] + fn test_enabled_opcodes() { + // List obtained from https://eips.ethereum.org/EIPS/eip-3670 + let opcodes = [ + 0x10..=0x1d, + 0x20..=0x20, + 0x30..=0x3f, + 0x40..=0x48, + 0x50..=0x5b, + 0x54..=0x5f, + 0x60..=0x6f, + 0x70..=0x7f, + 0x80..=0x8f, + 0x90..=0x9f, + 0xa0..=0xa4, + 0xf0..=0xf5, + 0xfa..=0xfa, + 0xfd..=0xfd, + //0xfe, + 0xff..=0xff, + ]; + for i in opcodes { + for opcode in i { + OpCode::new(opcode).expect("Opcode should be valid and enabled"); + } + } + } + + #[test] + fn test_terminating_opcodes() { + let terminating = [ + RETF, + REVERT, + RETURN, + INVALID, + SELFDESTRUCT, + RETURNCONTRACT, + STOP, + RJUMP, + JUMPF, + ]; + let mut opcodes = [false; 256]; + for terminating in terminating.iter() { + opcodes[*terminating as usize] = true; + } + + for (i, opcode) in OPCODE_INFO_JUMPTABLE.into_iter().enumerate() { + assert_eq!( + opcode + .map(|opcode| opcode.is_terminating_opcode) + .unwrap_or_default(), + opcodes[i], + "Opcode {:?} terminating chack failed.", + opcode + ); + } + } +} diff --git a/crates/interpreter/src/opcode/eof_printer.rs b/crates/interpreter/src/opcode/eof_printer.rs new file mode 100644 index 00000000..d593d9a7 --- /dev/null +++ b/crates/interpreter/src/opcode/eof_printer.rs @@ -0,0 +1,67 @@ +#[cfg(feature = "std")] +pub fn print_eof_code(code: &[u8]) { + use super::*; + use crate::instructions::utility::read_i16; + use revm_primitives::hex; + + // We can check validity and jump destinations in one pass. + let mut i = 0; + while i < code.len() { + let op = code[i]; + let opcode = &OPCODE_INFO_JUMPTABLE[op as usize]; + + let Some(opcode) = opcode else { + println!("Unknown opcode: 0x{:02X}", op); + i += 1; + continue; + }; + + if opcode.immediate_size != 0 { + // check if the opcode immediate are within the bounds of the code + if i + opcode.immediate_size as usize >= code.len() { + println!("Malformed code: immediate out of bounds"); + break; + } + } + + print!("{}", opcode.name); + if opcode.immediate_size != 0 { + print!( + " : 0x{:}", + hex::encode(&code[i + 1..i + 1 + opcode.immediate_size as usize]) + ); + } + + let mut rjumpv_additional_immediates = 0; + if op == RJUMPV { + let max_index = code[i + 1] as usize; + let len = max_index + 1; + // and max_index+1 is to get size of vtable as index starts from 0. + rjumpv_additional_immediates = len * 2; + + // +1 is for max_index byte + if i + 1 + rjumpv_additional_immediates >= code.len() { + println!("Malformed code: immediate out of bounds"); + break; + } + + for vtablei in 0..len { + let offset = unsafe { read_i16(code.as_ptr().add(i + 2 + 2 * vtablei)) } as isize; + println!("RJUMPV[{vtablei}]: 0x{offset:04X}({offset})"); + } + } + + i += 1 + opcode.immediate_size as usize + rjumpv_additional_immediates; + } +} + +#[cfg(test)] +mod test { + use super::*; + use revm_primitives::hex; + + #[test] + fn sanity_test() { + print_eof_code(&hex!("6001e200ffff00")); + } +} diff --git a/crates/interpreter/tests/EOFTests/EIP3540/validInvalid.json b/crates/interpreter/tests/EOFTests/EIP3540/validInvalid.json new file mode 100644 index 00000000..21b5f802 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/EIP3540/validInvalid.json @@ -0,0 +1,489 @@ +{ + "validInvalid" : { + "_info" : { + "comment" : "Test various examples to see if they are valid or invalid.\nImplements\n EOF1V3540_0001 (Valid) Deployed code without data section - Data index: 0\n EOF1V3540_0002 (Valid) Deployed code with data section - Data index: 1\n EOF1V3540_0003 (Valid) No data section contents (valid according to relaxed stack validation) - Data index: 2\n EOF1V3540_0004 (Valid) Data section contents incomplete (valid according to relaxed stack validation) - Data index: 3\n EOF1I3540_0001 (Invalid) No magic - Data index: 4\n EOF1I3540_0002 (Invalid) Invalid magic - Data index: 5\n EOF1I3540_0003 - Data index: 6\n EOF1I3540_0004 - Data index: 7\n EOF1I3540_0005 (Invalid) No version - Data index: 8\n EOF1I3540_0006 (Invalid) Invalid version - Data index: 9\n EOF1I3540_0007 - Data index: 10\n EOF1I3540_0008 - Data index: 11\n EOF1I3540_0009 (Invalid) No header - Data index: 12\n EOF1I3540_0010 (Invalid) No type section size - Data index: 13\n EOF1I3540_0011 (Invalid) Type section size incomplete - Data index: 14\n EOF1I3540_0012 (Invalid) Empty code section with non-empty data section - Data index: 15\n EOF1I3540_0013 (Invalid) No total of code sections - Data index: 16\n EOF1I3540_0014 (Invalid) Total of code sections incomplete - Data index: 17\n EOF1I3540_0015 (Invalid) No code section size - Data index: 18\n EOF1I3540_0016 (Invalid) Code section size incomplete - Data index: 19\n EOF1I3540_0017 (Invalid) No data section after code section size - Data index: 20\n EOF1I3540_0018 (Invalid) No data size - Data index: 21\n EOF1I3540_0019 (Invalid) Data size incomplete - Data index: 22\n EOF1I3540_0020 (Invalid) No section terminator after data section size - Data index: 23\n EOF1I3540_0021 (Invalid) No type section contents - Data index: 24\n EOF1I3540_0022 (Invalid) Type section contents (no outputs and max stack) - Data index: 25\n EOF1I3540_0023 (Invalid) Type section contents (no max stack) - Data index: 26\n EOF1I3540_0024 (Invalid) Type section contents (max stack incomplete) - Data index: 27\n EOF1I3540_0025 (Invalid) No code section contents - Data index: 28\n EOF1I3540_0026 (Invalid) Code section contents incomplete - Data index: 29\n EOF1I3540_0027 (Invalid) Trailing bytes after code section - Data index: 30\n EOF1I3540_0028 (Invalid) Empty code section - Data index: 31\n EOF1I3540_0029 (Invalid) Empty code section with non-empty data section - Data index: 32\n EOF1I3540_0030 (Invalid) Code section preceding type section - Data index: 33\n EOF1I3540_0031 (Invalid) Data section preceding type section - Data index: 34\n EOF1I3540_0032 (Invalid) Data section preceding code section - Data index: 35\n EOF1I3540_0033 (Invalid) Data section without code section - Data index: 36\n EOF1I3540_0034 (Invalid) No data section - Data index: 37\n EOF1I3540_0035 (Invalid) Trailing bytes after data section - Data index: 38\n EOF1I3540_0036 (Invalid) Multiple data sections - Data index: 39\n EOF1I3540_0037 (Invalid) Multiple code and data sections - Data index: 40\n EOF1I3540_0038 (Invalid) Unknown section IDs (at the beginning) - Data index: 41\n EOF1I3540_0039 - Data index: 42\n EOF1I3540_0040 - Data index: 43\n EOF1I3540_0041 (Invalid) Unknown section IDs (after types section) - Data index: 44\n EOF1I3540_0042 - Data index: 45\n EOF1I3540_0043 - Data index: 46\n EOF1I3540_0044 (Invalid) Unknown section IDs (after code section) - Data index: 47\n EOF1I3540_0045 - Data index: 48\n EOF1I3540_0046 - Data index: 49\n EOF1I3540_0047 (Invalid) Unknown section IDs (after data section) - Data index: 50\n EOF1I3540_0048 - Data index: 51\n EOF1I3540_0049 - Data index: 52\n", + "filling-rpc-server" : "evmone-t8n 0.12.0-dev+commit.14ba7529", + "filling-tool-version" : "retesteth-0.3.2-cancun+commit.9d793abd.Linux.g++", + "generatedTestHash" : "70f1c847a164c49063ecd1387e723bcecfdad88b8f833bc5be85c24c98c35b44", + "lllcversion" : "Version: 0.5.14-develop.2022.4.6+commit.401d5358.Linux.g++", + "solidity" : "Version: 0.8.18-develop.2023.1.16+commit.469d6d4d.Linux.g++", + "source" : "src/EOFTestsFiller/EIP3540/validInvalidFiller.yml", + "sourceHash" : "4625c63a66a8d034619df01985568a2e17850ed4100d04ab877c769ca9105f60" + }, + "vectors" : { + "validInvalid_0" : { + "code" : "0xef00010100040200010004040000000080000160005000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_1" : { + "code" : "0xef00010100040200010004040004000080000160005000aabbccdd", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_10" : { + "code" : "0xef000201000402000100010400000000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_UnknownVersion", + "result" : false + } + } + }, + "validInvalid_11" : { + "code" : "0xef00ff01000402000100010400000000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_UnknownVersion", + "result" : false + } + } + }, + "validInvalid_12" : { + "code" : "0xef0001", + "results" : { + "Prague" : { + "exception" : "EOF_SectionHeadersNotTerminated", + "result" : false + } + } + }, + "validInvalid_13" : { + "code" : "0xef000101", + "results" : { + "Prague" : { + "exception" : "EOF_SectionHeadersNotTerminated", + "result" : false + } + } + }, + "validInvalid_14" : { + "code" : "0xef00010100", + "results" : { + "Prague" : { + "exception" : "EOF_IncompleteSectionSize", + "result" : false + } + } + }, + "validInvalid_15" : { + "code" : "0xef000101000402000100000400020000000000aabb", + "results" : { + "Prague" : { + "exception" : "EOF_ZeroSectionSize", + "result" : false + } + } + }, + "validInvalid_16" : { + "code" : "0xef000101000402", + "results" : { + "Prague" : { + "exception" : "EOF_IncompleteSectionNumber", + "result" : false + } + } + }, + "validInvalid_17" : { + "code" : "0xef00010100040200", + "results" : { + "Prague" : { + "exception" : "EOF_IncompleteSectionNumber", + "result" : false + } + } + }, + "validInvalid_18" : { + "code" : "0xef0001010004020001", + "results" : { + "Prague" : { + "exception" : "EOF_SectionHeadersNotTerminated", + "result" : false + } + } + }, + "validInvalid_19" : { + "code" : "0xef000101000402000100", + "results" : { + "Prague" : { + "exception" : "EOF_IncompleteSectionSize", + "result" : false + } + } + }, + "validInvalid_2" : { + "code" : "0xef000101000402000100010400020000800000fe", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_20" : { + "code" : "0xef00010100040200010001", + "results" : { + "Prague" : { + "exception" : "EOF_SectionHeadersNotTerminated", + "result" : false + } + } + }, + "validInvalid_21" : { + "code" : "0xef0001010004020001000104", + "results" : { + "Prague" : { + "exception" : "EOF_SectionHeadersNotTerminated", + "result" : false + } + } + }, + "validInvalid_22" : { + "code" : "0xef000101000402000100010400", + "results" : { + "Prague" : { + "exception" : "EOF_IncompleteSectionSize", + "result" : false + } + } + }, + "validInvalid_23" : { + "code" : "0xef00010100040200010001040002", + "results" : { + "Prague" : { + "exception" : "EOF_SectionHeadersNotTerminated", + "result" : false + } + } + }, + "validInvalid_24" : { + "code" : "0xef0001010004020001000104000200", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidSectionBodiesSize", + "result" : false + } + } + }, + "validInvalid_25" : { + "code" : "0xef000101000402000100010400020000", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidSectionBodiesSize", + "result" : false + } + } + }, + "validInvalid_26" : { + "code" : "0xef00010100040200010001040002000000", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidSectionBodiesSize", + "result" : false + } + } + }, + "validInvalid_27" : { + "code" : "0xef0001010004020001000104000200000000", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidSectionBodiesSize", + "result" : false + } + } + }, + "validInvalid_28" : { + "code" : "0xef000101000402000100010400020000000000", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidSectionBodiesSize", + "result" : false + } + } + }, + "validInvalid_29" : { + "code" : "0xef0001010004020001002904000000000000027f", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidSectionBodiesSize", + "result" : false + } + } + }, + "validInvalid_3" : { + "code" : "0xef000101000402000100010400020000800000feaa", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_30" : { + "code" : "0xef000101000402000100010400000000000000feaabbcc", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidSectionBodiesSize", + "result" : false + } + } + }, + "validInvalid_31" : { + "code" : "0xef000101000402000100000400000000000000", + "results" : { + "Prague" : { + "exception" : "EOF_ZeroSectionSize", + "result" : false + } + } + }, + "validInvalid_32" : { + "code" : "0xef000101000402000100000400020000000000aabb", + "results" : { + "Prague" : { + "exception" : "EOF_ZeroSectionSize", + "result" : false + } + } + }, + "validInvalid_33" : { + "code" : "0xef000102000100010100040400020000000000feaabb", + "results" : { + "Prague" : { + "exception" : "EOF_TypeSectionMissing", + "result" : false + } + } + }, + "validInvalid_34" : { + "code" : "0xef000104000201000402000100010000000000feaabb", + "results" : { + "Prague" : { + "exception" : "EOF_TypeSectionMissing", + "result" : false + } + } + }, + "validInvalid_35" : { + "code" : "0xef000101000404000202000100010000000000feaabb", + "results" : { + "Prague" : { + "exception" : "EOF_CodeSectionMissing", + "result" : false + } + } + }, + "validInvalid_36" : { + "code" : "0xef00010100040400020000000000aabb", + "results" : { + "Prague" : { + "exception" : "EOF_CodeSectionMissing", + "result" : false + } + } + }, + "validInvalid_37" : { + "code" : "0xef000101000402000100010000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_DataSectionMissing", + "result" : false + } + } + }, + "validInvalid_38" : { + "code" : "0xef000101000402000100010400020000000000feaabbccdd", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidSectionBodiesSize", + "result" : false + } + } + }, + "validInvalid_39" : { + "code" : "0xef000101000402000100010400020400020000000000feaabbaabb", + "results" : { + "Prague" : { + "exception" : "EOF_HeaderTerminatorMissing", + "result" : false + } + } + }, + "validInvalid_4" : { + "code" : "0xef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidPrefix", + "result" : false + } + } + }, + "validInvalid_40" : { + "code" : "0xef000101000802000200010001040002040002000000000000000000fefeaabbaabb", + "results" : { + "Prague" : { + "exception" : "EOF_HeaderTerminatorMissing", + "result" : false + } + } + }, + "validInvalid_41" : { + "code" : "0xef000105000101000402000100010400000000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_TypeSectionMissing", + "result" : false + } + } + }, + "validInvalid_42" : { + "code" : "0xef000106000101000402000100010400000000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_TypeSectionMissing", + "result" : false + } + } + }, + "validInvalid_43" : { + "code" : "0xef0001ff000101000402000100010400000000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_TypeSectionMissing", + "result" : false + } + } + }, + "validInvalid_44" : { + "code" : "0xef000101000405000102000100010400000000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_CodeSectionMissing", + "result" : false + } + } + }, + "validInvalid_45" : { + "code" : "0xef000101000406000102000100010400000000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_CodeSectionMissing", + "result" : false + } + } + }, + "validInvalid_46" : { + "code" : "0xef0001010004ff000102000100010400000000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_CodeSectionMissing", + "result" : false + } + } + }, + "validInvalid_47" : { + "code" : "0xef000101000402000100010500010400000000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_DataSectionMissing", + "result" : false + } + } + }, + "validInvalid_48" : { + "code" : "0xef000101000402000100010600010400000000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_DataSectionMissing", + "result" : false + } + } + }, + "validInvalid_49" : { + "code" : "0xef00010100040200010001ff00010400000000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_DataSectionMissing", + "result" : false + } + } + }, + "validInvalid_5" : { + "code" : "0xef010101000402000100010400000000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidPrefix", + "result" : false + } + } + }, + "validInvalid_50" : { + "code" : "0xef000101000402000100010400000500010000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_HeaderTerminatorMissing", + "result" : false + } + } + }, + "validInvalid_51" : { + "code" : "0xef000101000402000100010400000600010000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_HeaderTerminatorMissing", + "result" : false + } + } + }, + "validInvalid_52" : { + "code" : "0xef00010100040200010001040000ff00010000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_HeaderTerminatorMissing", + "result" : false + } + } + }, + "validInvalid_6" : { + "code" : "0xef020101000402000100010400000000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidPrefix", + "result" : false + } + } + }, + "validInvalid_7" : { + "code" : "0xefff0101000402000100010400000000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidPrefix", + "result" : false + } + } + }, + "validInvalid_8" : { + "code" : "0xef00", + "results" : { + "Prague" : { + "exception" : "EOF_UnknownVersion", + "result" : false + } + } + }, + "validInvalid_9" : { + "code" : "0xef000001000402000100010400000000000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_UnknownVersion", + "result" : false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/EIP3670/validInvalid.json b/crates/interpreter/tests/EOFTests/EIP3670/validInvalid.json new file mode 100644 index 00000000..aa316140 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/EIP3670/validInvalid.json @@ -0,0 +1,2568 @@ +{ + "validInvalid" : { + "_info" : { + "comment" : "Test valid and invalid EOF code\n Implements\n EOFV3670_0001 (Valid) Code containing the STOP opcode - Data Section 0\n EOFV3670_0002 (Valid) Code containing the ADD opcode - Data Section 1\n EOFV3670_0003 (Valid) Code containing the MUL opcode - Data Section 2\n EOFV3670_0004 (Valid) Code containing the SUB opcode - Data Section 3\n EOFV3670_0005 (Valid) Code containing the DIV opcode - Data Section 4\n EOFV3670_0006 (Valid) Code containing the SDIV opcode - Data Section 5\n EOFV3670_0007 (Valid) Code containing the MOD opcode - Data Section 6\n EOFV3670_0008 (Valid) Code containing the SMOD opcode - Data Section 7\n EOFV3670_0009 (Valid) Code containing the ADDMOD opcode - Data Section 8\n EOFV3670_0010 (Valid) Code containing the MULMOD opcode - Data Section 9\n EOFV3670_0011 (Valid) Code containing the EXP opcode - Data Section 10\n EOFV3670_0012 (Valid) Code containing the SIGNEXTEND opcode - Data Section 11\n EOFV3670_0013 (Valid) Code containing the LT opcode - Data Section 12\n EOFV3670_0014 (Valid) Code containing the GT opcode - Data Section 13\n EOFV3670_0015 (Valid) Code containing the SLT opcode - Data Section 14\n EOFV3670_0016 (Valid) Code containing the SGT opcode - Data Section 15\n EOFV3670_0017 (Valid) Code containing the EQ opcode - Data Section 16\n EOFV3670_0018 (Valid) Code containing the ISZERO opcode - Data Section 17\n EOFV3670_0019 (Valid) Code containing the AND opcode - Data Section 18\n EOFV3670_0020 (Valid) Code containing the OR opcode - Data Section 19\n EOFV3670_0021 (Valid) Code containing the XOR opcode - Data Section 20\n EOFV3670_0022 (Valid) Code containing the NOT opcode - Data Section 21\n EOFV3670_0023 (Valid) Code containing the BYTE opcode - Data Section 22\n EOFV3670_0024 (Valid) Code containing the SHL opcode - Data Section 23\n EOFV3670_0025 (Valid) Code containing the SHR opcode - Data Section 24\n EOFV3670_0026 (Valid) Code containing the SAR opcode - Data Section 25\n EOFV3670_0027 (Valid) Code containing the SHA3 opcode - Data Section 26\n EOFV3670_0028 (Valid) Code containing the ADDRESS opcode - Data Section 27\n EOFV3670_0029 (Valid) Code containing the BALANCE opcode - Data Section 28\n EOFV3670_0030 (Valid) Code containing the ORIGIN opcode - Data Section 29\n EOFV3670_0031 (Valid) Code containing the CALLER opcode - Data Section 30\n EOFV3670_0032 (Valid) Code containing the CALLVALUE opcode - Data Section 31\n EOFV3670_0033 (Valid) Code containing the CALLDATALOAD opcode - Data Section 32\n EOFV3670_0034 (Valid) Code containing the CALLDATASIZE opcode - Data Section 33\n EOFV3670_0035 (Valid) Code containing the CALLDATACOPY opcode - Data Section 34\n EOFV3670_0036 (Valid) Code containing the CODESIZE opcode - Data Section 35\n EOFV3670_0037 (Valid) Code containing the CODECOPY opcode - Data Section 36\n EOFV3670_0038 (Valid) Code containing the GASPRICE opcode - Data Section 37\n EOFV3670_0039 (Valid) Code containing the EXTCODESIZE opcode - Data Section 38\n EOFV3670_0040 (Valid) Code containing the EXTCODECOPY opcode - Data Section 39\n EOFV3670_0041 (Valid) Code containing the RETURNDATASIZE opcode - Data Section 40\n EOFV3670_0042 (Valid) Code containing the RETURNDATACOPY opcode - Data Section 41\n EOFV3670_0043 (Valid) Code containing the EXTCODEHASH opcode - Data Section 42\n EOFV3670_0044 (Valid) Code containing the BLOCKHASH opcode - Data Section 43\n EOFV3670_0045 (Valid) Code containing the COINBASE opcode - Data Section 44\n EOFV3670_0046 (Valid) Code containing the TIMESTAMP opcode - Data Section 45\n EOFV3670_0047 (Valid) Code containing the NUMBER opcode - Data Section 46\n EOFV3670_0048 (Valid) Code containing the DIFFICULTY opcode - Data Section 47\n EOFV3670_0049 (Valid) Code containing the GASLIMIT opcode - Data Section 48\n EOFV3670_0050 (Valid) Code containing the CHAINID opcode - Data Section 49\n EOFV3670_0051 (Valid) Code containing the SELFBALANCE opcode - Data Section 50\n EOFV3670_0052 (Valid) Code containing the BASEFEE opcode - Data Section 51\n EOFV3670_0053 (Valid) Code containing the BLOBHASH opcode - Data Section 52\n EOFV3670_0054 (Valid) Code containing the BLOBBASEFEE opcode - Data Section 53\n EOFV3670_0055 (Valid) Code containing the POP opcode - Data Section 54\n EOFV3670_0056 (Valid) Code containing the MLOAD opcode - Data Section 55\n EOFV3670_0057 (Valid) Code containing the MSTORE8 opcode - Data Section 56\n EOFV3670_0058 (Valid) Code containing the SLOAD opcode - Data Section 57\n EOFV3670_0059 (Valid) Code containing the SSTORE opcode - Data Section 58\n EOFV3670_0060 (Valid) Code containing the MSIZE opcode - Data Section 59\n EOFV3670_0061 (Valid) Code containing the GAS opcode - Data Section 60\n EOFV3670_0062 (Valid) Code containing the NOP opcode - Data Section 61\n EOFV3670_0063 (Valid) Code containing the MCOPY opcode - Data Section 62\n EOFV3670_0064 (Valid) Code containing the PUSH0 opcode - Data Section 63\n EOFV3670_0065 (Valid) Code containing the PUSH1 opcode - Data Section 64\n EOFV3670_0066 (Valid) Code containing the PUSH2 opcode - Data Section 65\n EOFV3670_0067 (Valid) Code containing the PUSH3 opcode - Data Section 66\n EOFV3670_0068 (Valid) Code containing the PUSH4 opcode - Data Section 67\n EOFV3670_0069 (Valid) Code containing the PUSH5 opcode - Data Section 68\n EOFV3670_0070 (Valid) Code containing the PUSH6 opcode - Data Section 69\n EOFV3670_0071 (Valid) Code containing the PUSH7 opcode - Data Section 70\n EOFV3670_0072 (Valid) Code containing the PUSH8 opcode - Data Section 71\n EOFV3670_0073 (Valid) Code containing the PUSH9 opcode - Data Section 72\n EOFV3670_0074 (Valid) Code containing the PUSH10 opcode - Data Section 73\n EOFV3670_0075 (Valid) Code containing the PUSH11 opcode - Data Section 74\n EOFV3670_0076 (Valid) Code containing the PUSH12 opcode - Data Section 75\n EOFV3670_0077 (Valid) Code containing the PUSH13 opcode - Data Section 76\n EOFV3670_0078 (Valid) Code containing the PUSH14 opcode - Data Section 77\n EOFV3670_0079 (Valid) Code containing the PUSH15 opcode - Data Section 78\n EOFV3670_0080 (Valid) Code containing the PUSH16 opcode - Data Section 79\n EOFV3670_0081 (Valid) Code containing the PUSH17 opcode - Data Section 80\n EOFV3670_0082 (Valid) Code containing the PUSH18 opcode - Data Section 81\n EOFV3670_0083 (Valid) Code containing the PUSH19 opcode - Data Section 82\n EOFV3670_0084 (Valid) Code containing the PUSH20 opcode - Data Section 83\n EOFV3670_0085 (Valid) Code containing the PUSH21 opcode - Data Section 84\n EOFV3670_0086 (Valid) Code containing the PUSH22 opcode - Data Section 85\n EOFV3670_0087 (Valid) Code containing the PUSH23 opcode - Data Section 86\n EOFV3670_0088 (Valid) Code containing the PUSH24 opcode - Data Section 87\n EOFV3670_0089 (Valid) Code containing the PUSH25 opcode - Data Section 88\n EOFV3670_0090 (Valid) Code containing the PUSH26 opcode - Data Section 89\n EOFV3670_0091 (Valid) Code containing the PUSH27 opcode - Data Section 90\n EOFV3670_0092 (Valid) Code containing the PUSH28 opcode - Data Section 91\n EOFV3670_0093 (Valid) Code containing the PUSH29 opcode - Data Section 92\n EOFV3670_0094 (Valid) Code containing the PUSH30 opcode - Data Section 93\n EOFV3670_0095 (Valid) Code containing the PUSH31 opcode - Data Section 94\n EOFV3670_0096 (Valid) Code containing the PUSH32 opcode - Data Section 95\n EOFV3670_0097 (Valid) Code containing the DUP1 opcode - Data Section 96\n EOFV3670_0098 (Valid) Code containing the DUP2 opcode - Data Section 97\n EOFV3670_0099 (Valid) Code containing the DUP3 opcode - Data Section 98\n EOFV3670_0100 (Valid) Code containing the DUP4 opcode - Data Section 99\n EOFV3670_0101 (Valid) Code containing the DUP5 opcode - Data Section 100\n EOFV3670_0102 (Valid) Code containing the DUP6 opcode - Data Section 101\n EOFV3670_0103 (Valid) Code containing the DUP7 opcode - Data Section 102\n EOFV3670_0104 (Valid) Code containing the DUP8 opcode - Data Section 103\n EOFV3670_0105 (Valid) Code containing the DUP9 opcode - Data Section 104\n EOFV3670_0106 (Valid) Code containing the DUP10 opcode - Data Section 105\n EOFV3670_0107 (Valid) Code containing the DUP11 opcode - Data Section 106\n EOFV3670_0108 (Valid) Code containing the DUP12 opcode - Data Section 107\n EOFV3670_0109 (Valid) Code containing the DUP13 opcode - Data Section 108\n EOFV3670_0110 (Valid) Code containing the DUP14 opcode - Data Section 109\n EOFV3670_0111 (Valid) Code containing the DUP15 opcode - Data Section 110\n EOFV3670_0112 (Valid) Code containing the DUP16 opcode - Data Section 111\n EOFV3670_0113 (Valid) Code containing the SWAP1 opcode - Data Section 112\n EOFV3670_0114 (Valid) Code containing the SWAP2 opcode - Data Section 113\n EOFV3670_0115 (Valid) Code containing the SWAP3 opcode - Data Section 114\n EOFV3670_0116 (Valid) Code containing the SWAP4 opcode - Data Section 115\n EOFV3670_0117 (Valid) Code containing the SWAP5 opcode - Data Section 116\n EOFV3670_0118 (Valid) Code containing the SWAP6 opcode - Data Section 117\n EOFV3670_0119 (Valid) Code containing the SWAP7 opcode - Data Section 118\n EOFV3670_0120 (Valid) Code containing the SWAP8 opcode - Data Section 119\n EOFV3670_0121 (Valid) Code containing the SWAP9 opcode - Data Section 120\n EOFV3670_0122 (Valid) Code containing the SWAP10 opcode - Data Section 121\n EOFV3670_0123 (Valid) Code containing the SWAP11 opcode - Data Section 122\n EOFV3670_0124 (Valid) Code containing the SWAP12 opcode - Data Section 123\n EOFV3670_0125 (Valid) Code containing the SWAP13 opcode - Data Section 124\n EOFV3670_0126 (Valid) Code containing the SWAP14 opcode - Data Section 125\n EOFV3670_0127 (Valid) Code containing the SWAP15 opcode - Data Section 126\n EOFV3670_0128 (Valid) Code containing the SWAP16 opcode - Data Section 127\n EOFV3670_0129 (Valid) Code containing the LOG0 opcode - Data Section 128\n EOFV3670_0130 (Valid) Code containing the LOG1 opcode - Data Section 129\n EOFV3670_0131 (Valid) Code containing the LOG2 opcode - Data Section 130\n EOFV3670_0132 (Valid) Code containing the LOG3 opcode - Data Section 131\n EOFV3670_0133 (Valid) Code containing the LOG4 opcode - Data Section 132\n EOFV3670_0134 (Valid) Code containing the CALL opcode - Data Section 133\n EOFV3670_0135 (Valid) Code containing the RETURN opcode - Data Section 134\n EOFV3670_0136 (Valid) Code containing the DELEGATECALL opcode - Data Section 135\n EOFV3670_0137 (Valid) Code containing the STATICCALL opcode - Data Section 136\n EOFV3670_0138 (Valid) Code containing the REVERT opcode - Data Section 137\n EOFV3670_0139 (Valid) Code containing the INVALID opcode - Data Section 138\n EOFI3670_0140 (Invalid) Code containing undefined instruction 0x0c - Data Section 139\n EOFI3670_0141 (Invalid) Code containing undefined instruction 0x0d - Data Section 140\n EOFI3670_0142 (Invalid) Code containing undefined instruction 0x0e - Data Section 141\n EOFI3670_0143 (Invalid) Code containing undefined instruction 0x0f - Data Section 142\n EOFI3670_0144 (Invalid) Code containing undefined instruction 0x1e - Data Section 143\n EOFI3670_0145 (Invalid) Code containing undefined instruction 0x1f - Data Section 144\n EOFI3670_0146 (Invalid) Code containing undefined instruction 0x21 - Data Section 145\n EOFI3670_0147 (Invalid) Code containing undefined instruction 0x22 - Data Section 146\n EOFI3670_0148 (Invalid) Code containing undefined instruction 0x23 - Data Section 147\n EOFI3670_0149 (Invalid) Code containing undefined instruction 0x24 - Data Section 148\n EOFI3670_0150 (Invalid) Code containing undefined instruction 0x25 - Data Section 149\n EOFI3670_0151 (Invalid) Code containing undefined instruction 0x26 - Data Section 150\n EOFI3670_0152 (Invalid) Code containing undefined instruction 0x27 - Data Section 151\n EOFI3670_0153 (Invalid) Code containing undefined instruction 0x28 - Data Section 152\n EOFI3670_0154 (Invalid) Code containing undefined instruction 0x29 - Data Section 153\n EOFI3670_0155 (Invalid) Code containing undefined instruction 0x2a - Data Section 154\n EOFI3670_0156 (Invalid) Code containing undefined instruction 0x2b - Data Section 155\n EOFI3670_0157 (Invalid) Code containing undefined instruction 0x2c - Data Section 156\n EOFI3670_0158 (Invalid) Code containing undefined instruction 0x2d - Data Section 157\n EOFI3670_0159 (Invalid) Code containing undefined instruction 0x2e - Data Section 158\n EOFI3670_0160 (Invalid) Code containing undefined instruction 0x2f - Data Section 159\n EOFI3670_0161 (Invalid) Code containing undefined instruction 0x4b - Data Section 160\n EOFI3670_0162 (Invalid) Code containing undefined instruction 0x4c - Data Section 161\n EOFI3670_0163 (Invalid) Code containing undefined instruction 0x4d - Data Section 162\n EOFI3670_0164 (Invalid) Code containing undefined instruction 0x4e - Data Section 163\n EOFI3670_0165 (Invalid) Code containing undefined instruction 0x4f - Data Section 164\n EOFI3670_0166 (Invalid) Code containing undefined instruction 0x56 - Data Section 165\n EOFI3670_0167 (Invalid) Code containing undefined instruction 0x57 - Data Section 166\n EOFI3670_0168 (Invalid) Code containing undefined instruction 0x58 - Data Section 167\n EOFI3670_0169 (Invalid) Code containing undefined instruction 0xa5 - Data Section 168\n EOFI3670_0170 (Invalid) Code containing undefined instruction 0xa6 - Data Section 169\n EOFI3670_0171 (Invalid) Code containing undefined instruction 0xa7 - Data Section 170\n EOFI3670_0172 (Invalid) Code containing undefined instruction 0xa8 - Data Section 171\n EOFI3670_0173 (Invalid) Code containing undefined instruction 0xa9 - Data Section 172\n EOFI3670_0174 (Invalid) Code containing undefined instruction 0xaa - Data Section 173\n EOFI3670_0175 (Invalid) Code containing undefined instruction 0xab - Data Section 174\n EOFI3670_0176 (Invalid) Code containing undefined instruction 0xac - Data Section 175\n EOFI3670_0177 (Invalid) Code containing undefined instruction 0xad - Data Section 176\n EOFI3670_0178 (Invalid) Code containing undefined instruction 0xae - Data Section 177\n EOFI3670_0179 (Invalid) Code containing undefined instruction 0xaf - Data Section 178\n EOFI3670_0180 (Invalid) Code containing undefined instruction 0xb2 - Data Section 179\n EOFI3670_0181 (Invalid) Code containing undefined instruction 0xb3 - Data Section 180\n EOFI3670_0182 (Invalid) Code containing undefined instruction 0xb4 - Data Section 181\n EOFI3670_0183 (Invalid) Code containing undefined instruction 0xb5 - Data Section 182\n EOFI3670_0184 (Invalid) Code containing undefined instruction 0xb6 - Data Section 183\n EOFI3670_0185 (Invalid) Code containing undefined instruction 0xb7 - Data Section 184\n EOFI3670_0186 (Invalid) Code containing undefined instruction 0xb8 - Data Section 185\n EOFI3670_0187 (Invalid) Code containing undefined instruction 0xb9 - Data Section 186\n EOFI3670_0188 (Invalid) Code containing undefined instruction 0xba - Data Section 187\n EOFI3670_0189 (Invalid) Code containing undefined instruction 0xbb - Data Section 188\n EOFI3670_0190 (Invalid) Code containing undefined instruction 0xbc - Data Section 189\n EOFI3670_0191 (Invalid) Code containing undefined instruction 0xbd - Data Section 190\n EOFI3670_0192 (Invalid) Code containing undefined instruction 0xbe - Data Section 191\n EOFI3670_0193 (Invalid) Code containing undefined instruction 0xbf - Data Section 192\n EOFI3670_0194 (Invalid) Code containing undefined instruction 0xc0 - Data Section 193\n EOFI3670_0195 (Invalid) Code containing undefined instruction 0xc1 - Data Section 194\n EOFI3670_0196 (Invalid) Code containing undefined instruction 0xc2 - Data Section 195\n EOFI3670_0197 (Invalid) Code containing undefined instruction 0xc3 - Data Section 196\n EOFI3670_0198 (Invalid) Code containing undefined instruction 0xc4 - Data Section 197\n EOFI3670_0199 (Invalid) Code containing undefined instruction 0xc5 - Data Section 198\n EOFI3670_0200 (Invalid) Code containing undefined instruction 0xc6 - Data Section 199\n EOFI3670_0201 (Invalid) Code containing undefined instruction 0xc7 - Data Section 200\n EOFI3670_0202 (Invalid) Code containing undefined instruction 0xc8 - Data Section 201\n EOFI3670_0203 (Invalid) Code containing undefined instruction 0xc9 - Data Section 202\n EOFI3670_0204 (Invalid) Code containing undefined instruction 0xca - Data Section 203\n EOFI3670_0205 (Invalid) Code containing undefined instruction 0xcb - Data Section 204\n EOFI3670_0206 (Invalid) Code containing undefined instruction 0xcc - Data Section 205\n EOFI3670_0207 (Invalid) Code containing undefined instruction 0xcd - Data Section 206\n EOFI3670_0208 (Invalid) Code containing undefined instruction 0xce - Data Section 207\n EOFI3670_0209 (Invalid) Code containing undefined instruction 0xcf - Data Section 208\n EOFI3670_0210 (Invalid) Code containing undefined instruction 0xd4 - Data Section 209\n EOFI3670_0211 (Invalid) Code containing undefined instruction 0xd5 - Data Section 210\n EOFI3670_0212 (Invalid) Code containing undefined instruction 0xd6 - Data Section 211\n EOFI3670_0213 (Invalid) Code containing undefined instruction 0xd7 - Data Section 212\n EOFI3670_0214 (Invalid) Code containing undefined instruction 0xd8 - Data Section 213\n EOFI3670_0215 (Invalid) Code containing undefined instruction 0xd9 - Data Section 214\n EOFI3670_0216 (Invalid) Code containing undefined instruction 0xda - Data Section 215\n EOFI3670_0217 (Invalid) Code containing undefined instruction 0xdb - Data Section 216\n EOFI3670_0218 (Invalid) Code containing undefined instruction 0xdc - Data Section 217\n EOFI3670_0219 (Invalid) Code containing undefined instruction 0xdd - Data Section 218\n EOFI3670_0220 (Invalid) Code containing undefined instruction 0xde - Data Section 219\n EOFI3670_0221 (Invalid) Code containing undefined instruction 0xdf - Data Section 220\n EOFI3670_0222 (Invalid) Code containing undefined instruction 0xe8 - Data Section 221\n EOFI3670_0223 (Invalid) Code containing undefined instruction 0xe9 - Data Section 222\n EOFI3670_0224 (Invalid) Code containing undefined instruction 0xea - Data Section 223\n EOFI3670_0225 (Invalid) Code containing undefined instruction 0xeb - Data Section 224\n EOFI3670_0226 (Invalid) Code containing undefined instruction 0xef - Data Section 225\n EOFI3670_0227 (Invalid) Code containing undefined instruction 0xf0 - Data Section 226\n EOFI3670_0228 (Invalid) Code containing undefined instruction 0xf2 - Data Section 227\n EOFI3670_0229 (Invalid) Code containing undefined instruction 0xf5 - Data Section 228\n EOFI3670_0230 (Invalid) Code containing undefined instruction 0xf6 - Data Section 229\n EOFI3670_0231 (Invalid) Code containing undefined instruction 0xf8 - Data Section 230\n EOFI3670_0232 (Invalid) Code containing undefined instruction 0xf9 - Data Section 231\n EOFI3670_0233 (Invalid) Code containing undefined instruction 0xfb - Data Section 232\n EOFI3670_0234 (Invalid) Code containing undefined instruction 0xfc - Data Section 233\n EOFI3670_0235 (Invalid) Code containing undefined instruction 0xff - Data Section 234\n EOFI3670_0236 (Invalid) Truncated PUSH1 (no immediates) - Data Section 235\n EOFI3670_0237 (Invalid) Truncated PUSH2 (no immediates) - Data Section 236\n EOFI3670_0238 (Invalid) Truncated PUSH2 (truncated immediates) - Data Section 237\n EOFI3670_0239 (Invalid) Truncated PUSH3 (no immediates) - Data Section 238\n EOFI3670_0240 (Invalid) Truncated PUSH3 (truncated immediates) - Data Section 239\n EOFI3670_0241 (Invalid) Truncated PUSH4 (no immediates) - Data Section 240\n EOFI3670_0242 (Invalid) Truncated PUSH4 (truncated immediates) - Data Section 241\n EOFI3670_0243 (Invalid) Truncated PUSH5 (no immediates) - Data Section 242\n EOFI3670_0244 (Invalid) Truncated PUSH5 (truncated immediates) - Data Section 243\n EOFI3670_0245 (Invalid) Truncated PUSH6 (no immediates) - Data Section 244\n EOFI3670_0246 (Invalid) Truncated PUSH6 (truncated immediates) - Data Section 245\n EOFI3670_0247 (Invalid) Truncated PUSH7 (no immediates) - Data Section 246\n EOFI3670_0248 (Invalid) Truncated PUSH7 (truncated immediates) - Data Section 247\n EOFI3670_0249 (Invalid) Truncated PUSH8 (no immediates) - Data Section 248\n EOFI3670_0250 (Invalid) Truncated PUSH8 (truncated immediates) - Data Section 249\n EOFI3670_0251 (Invalid) Truncated PUSH9 (no immediates) - Data Section 250\n EOFI3670_0252 (Invalid) Truncated PUSH9 (truncated immediates) - Data Section 251\n EOFI3670_0253 (Invalid) Truncated PUSH10 (no immediates) - Data Section 252\n EOFI3670_0254 (Invalid) Truncated PUSH10 (truncated immediates) - Data Section 253\n EOFI3670_0255 (Invalid) Truncated PUSH11 (no immediates) - Data Section 254\n EOFI3670_0256 (Invalid) Truncated PUSH11 (truncated immediates) - Data Section 255\n EOFI3670_0257 (Invalid) Truncated PUSH12 (no immediates) - Data Section 256\n EOFI3670_0258 (Invalid) Truncated PUSH12 (truncated immediates) - Data Section 257\n EOFI3670_0259 (Invalid) Truncated PUSH13 (no immediates) - Data Section 258\n EOFI3670_0260 (Invalid) Truncated PUSH13 (truncated immediates) - Data Section 259\n EOFI3670_0261 (Invalid) Truncated PUSH14 (no immediates) - Data Section 260\n EOFI3670_0262 (Invalid) Truncated PUSH14 (truncated immediates) - Data Section 261\n EOFI3670_0263 (Invalid) Truncated PUSH15 (no immediates) - Data Section 262\n EOFI3670_0264 (Invalid) Truncated PUSH15 (truncated immediates) - Data Section 263\n EOFI3670_0265 (Invalid) Truncated PUSH16 (no immediates) - Data Section 264\n EOFI3670_0266 (Invalid) Truncated PUSH16 (truncated immediates) - Data Section 265\n EOFI3670_0267 (Invalid) Truncated PUSH17 (no immediates) - Data Section 266\n EOFI3670_0268 (Invalid) Truncated PUSH17 (truncated immediates) - Data Section 267\n EOFI3670_0269 (Invalid) Truncated PUSH18 (no immediates) - Data Section 268\n EOFI3670_0270 (Invalid) Truncated PUSH18 (truncated immediates) - Data Section 269\n EOFI3670_0271 (Invalid) Truncated PUSH19 (no immediates) - Data Section 270\n EOFI3670_0272 (Invalid) Truncated PUSH19 (truncated immediates) - Data Section 271\n EOFI3670_0273 (Invalid) Truncated PUSH20 (no immediates) - Data Section 272\n EOFI3670_0274 (Invalid) Truncated PUSH20 (truncated immediates) - Data Section 273\n EOFI3670_0275 (Invalid) Truncated PUSH21 (no immediates) - Data Section 274\n EOFI3670_0276 (Invalid) Truncated PUSH21 (truncated immediates) - Data Section 275\n EOFI3670_0277 (Invalid) Truncated PUSH22 (no immediates) - Data Section 276\n EOFI3670_0278 (Invalid) Truncated PUSH22 (truncated immediates) - Data Section 277\n EOFI3670_0279 (Invalid) Truncated PUSH23 (no immediates) - Data Section 278\n EOFI3670_0280 (Invalid) Truncated PUSH23 (truncated immediates) - Data Section 279\n EOFI3670_0281 (Invalid) Truncated PUSH24 (no immediates) - Data Section 280\n EOFI3670_0282 (Invalid) Truncated PUSH24 (truncated immediates) - Data Section 281\n EOFI3670_0283 (Invalid) Truncated PUSH25 (no immediates) - Data Section 282\n EOFI3670_0284 (Invalid) Truncated PUSH25 (truncated immediates) - Data Section 283\n EOFI3670_0285 (Invalid) Truncated PUSH26 (no immediates) - Data Section 284\n EOFI3670_0286 (Invalid) Truncated PUSH26 (truncated immediates) - Data Section 285\n EOFI3670_0287 (Invalid) Truncated PUSH27 (no immediates) - Data Section 286\n EOFI3670_0288 (Invalid) Truncated PUSH27 (truncated immediates) - Data Section 287\n EOFI3670_0289 (Invalid) Truncated PUSH28 (no immediates) - Data Section 288\n EOFI3670_0290 (Invalid) Truncated PUSH28 (truncated immediates) - Data Section 289\n EOFI3670_0291 (Invalid) Truncated PUSH29 (no immediates) - Data Section 290\n EOFI3670_0292 (Invalid) Truncated PUSH29 (truncated immediates) - Data Section 291\n EOFI3670_0293 (Invalid) Truncated PUSH30 (no immediates) - Data Section 292\n EOFI3670_0294 (Invalid) Truncated PUSH30 (truncated immediates) - Data Section 293\n EOFI3670_0295 (Invalid) Truncated PUSH31 (no immediates) - Data Section 294\n EOFI3670_0296 (Invalid) Truncated PUSH31 (truncated immediates) - Data Section 295\n EOFI3670_0297 (Invalid) Truncated PUSH32 (no immediates) - Data Section 296\n EOFI3670_0298 (Invalid) Truncated PUSH32 (truncated immediates) - Data Section 297\n EOFI3670_0299 (Invalid) Containing undefined instruction (0xfb) after STOP - Data Section 298\n", + "filling-rpc-server" : "evmone-t8n 0.12.0-dev+commit.14ba7529", + "filling-tool-version" : "retesteth-0.3.2-cancun+commit.9d793abd.Linux.g++", + "generatedTestHash" : "b2305be6aaf4c98bf09b5892455f61697aff8cd555895837c8df7324ed7bf9e6", + "lllcversion" : "Version: 0.5.14-develop.2022.4.6+commit.401d5358.Linux.g++", + "solidity" : "Version: 0.8.18-develop.2023.1.16+commit.469d6d4d.Linux.g++", + "source" : "src/EOFTestsFiller/EIP3670/validInvalidFiller.yml", + "sourceHash" : "513e8e83276305366c781c549bb70abeacd865e219b9adfa7aacdc619765ea67" + }, + "vectors" : { + "validInvalid_0" : { + "code" : "0xef00010100040200010001040000000080000000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_1" : { + "code" : "0xef0001010004020001000504000000008000026001800100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_10" : { + "code" : "0xef0001010004020001000504000000008000026001800a00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_100" : { + "code" : "0xef0001010004020001000804000000008000066001808080808400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_101" : { + "code" : "0xef000101000402000100090400000000800007600180808080808500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_102" : { + "code" : "0xef0001010004020001000a040000000080000860018080808080808600", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_103" : { + "code" : "0xef0001010004020001000b04000000008000096001808080808080808700", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_104" : { + "code" : "0xef0001010004020001000c040000000080000a600180808080808080808800", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_105" : { + "code" : "0xef0001010004020001000d040000000080000b60018080808080808080808900", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_106" : { + "code" : "0xef0001010004020001000e040000000080000c6001808080808080808080808a00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_107" : { + "code" : "0xef0001010004020001000f040000000080000d600180808080808080808080808b00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_108" : { + "code" : "0xef00010100040200010010040000000080000e60018080808080808080808080808c00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_109" : { + "code" : "0xef00010100040200010011040000000080000f6001808080808080808080808080808d00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_11" : { + "code" : "0xef0001010004020001000504000000008000026001800b00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_110" : { + "code" : "0xef000101000402000100120400000000800010600180808080808080808080808080808e00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_111" : { + "code" : "0xef00010100040200010013040000000080001160018080808080808080808080808080808f00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_112" : { + "code" : "0xef0001010004020001000504000000008000026001809000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_113" : { + "code" : "0xef000101000402000100060400000000800003600180809100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_114" : { + "code" : "0xef00010100040200010007040000000080000460018080809200", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_115" : { + "code" : "0xef0001010004020001000804000000008000056001808080809300", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_116" : { + "code" : "0xef000101000402000100090400000000800006600180808080809400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_117" : { + "code" : "0xef0001010004020001000a040000000080000760018080808080809500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_118" : { + "code" : "0xef0001010004020001000b04000000008000086001808080808080809600", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_119" : { + "code" : "0xef0001010004020001000c0400000000800009600180808080808080809700", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_12" : { + "code" : "0xef0001010004020001000504000000008000026001801000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_120" : { + "code" : "0xef0001010004020001000d040000000080000a60018080808080808080809800", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_121" : { + "code" : "0xef0001010004020001000e040000000080000b6001808080808080808080809900", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_122" : { + "code" : "0xef0001010004020001000f040000000080000c600180808080808080808080809a00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_123" : { + "code" : "0xef00010100040200010010040000000080000d60018080808080808080808080809b00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_124" : { + "code" : "0xef00010100040200010011040000000080000e6001808080808080808080808080809c00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_125" : { + "code" : "0xef00010100040200010012040000000080000f600180808080808080808080808080809d00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_126" : { + "code" : "0xef00010100040200010013040000000080001060018080808080808080808080808080809e00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_127" : { + "code" : "0xef0001010004020001001404000000008000116001808080808080808080808080808080809f00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_128" : { + "code" : "0xef000101000402000100050400000000800002600180a000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_129" : { + "code" : "0xef00010100040200010006040000000080000360018080a100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_13" : { + "code" : "0xef0001010004020001000504000000008000026001801100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_130" : { + "code" : "0xef0001010004020001000704000000008000046001808080a200", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_131" : { + "code" : "0xef000101000402000100080400000000800005600180808080a300", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_132" : { + "code" : "0xef00010100040200010009040000000080000660018080808080a400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_133" : { + "code" : "0xef0001010004020001000a04000000008000076001808080808080f100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_134" : { + "code" : "0xef000101000402000100040400000000800002600180f3", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_135" : { + "code" : "0xef00010100040200010009040000000080000660018080808080f400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_136" : { + "code" : "0xef00010100040200010009040000000080000660018080808080fa00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_137" : { + "code" : "0xef000101000402000100040400000000800002600180fd", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_138" : { + "code" : "0xef000101000402000100010400000000800000fe", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_139" : { + "code" : "0xef0001010004020001000204000000008000000c00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_14" : { + "code" : "0xef0001010004020001000504000000008000026001801200", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_140" : { + "code" : "0xef0001010004020001000204000000008000000d00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_141" : { + "code" : "0xef0001010004020001000204000000008000000e00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_142" : { + "code" : "0xef0001010004020001000204000000008000000f00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_143" : { + "code" : "0xef0001010004020001000204000000008000001e00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_144" : { + "code" : "0xef0001010004020001000204000000008000001f00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_145" : { + "code" : "0xef0001010004020001000204000000008000002100", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_146" : { + "code" : "0xef0001010004020001000204000000008000002200", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_147" : { + "code" : "0xef0001010004020001000204000000008000002300", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_148" : { + "code" : "0xef0001010004020001000204000000008000002400", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_149" : { + "code" : "0xef0001010004020001000204000000008000002500", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_15" : { + "code" : "0xef0001010004020001000504000000008000026001801300", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_150" : { + "code" : "0xef0001010004020001000204000000008000002600", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_151" : { + "code" : "0xef0001010004020001000204000000008000002700", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_152" : { + "code" : "0xef0001010004020001000204000000008000002800", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_153" : { + "code" : "0xef0001010004020001000204000000008000002900", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_154" : { + "code" : "0xef0001010004020001000204000000008000002a00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_155" : { + "code" : "0xef0001010004020001000204000000008000002b00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_156" : { + "code" : "0xef0001010004020001000204000000008000002c00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_157" : { + "code" : "0xef0001010004020001000204000000008000002d00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_158" : { + "code" : "0xef0001010004020001000204000000008000002e00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_159" : { + "code" : "0xef0001010004020001000204000000008000002f00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_16" : { + "code" : "0xef0001010004020001000504000000008000026001801400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_160" : { + "code" : "0xef0001010004020001000204000000008000004b00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_161" : { + "code" : "0xef0001010004020001000204000000008000004c00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_162" : { + "code" : "0xef0001010004020001000204000000008000004d00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_163" : { + "code" : "0xef0001010004020001000204000000008000004e00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_164" : { + "code" : "0xef0001010004020001000204000000008000004f00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_165" : { + "code" : "0xef0001010004020001000204000000008000005600", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_166" : { + "code" : "0xef0001010004020001000204000000008000005700", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_167" : { + "code" : "0xef0001010004020001000204000000008000015800", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_168" : { + "code" : "0xef000101000402000100020400000000800000a500", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_169" : { + "code" : "0xef000101000402000100020400000000800000a600", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_17" : { + "code" : "0xef00010100040200010004040000000080000160011500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_170" : { + "code" : "0xef000101000402000100020400000000800000a700", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_171" : { + "code" : "0xef000101000402000100020400000000800000a800", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_172" : { + "code" : "0xef000101000402000100020400000000800000a900", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_173" : { + "code" : "0xef000101000402000100020400000000800000aa00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_174" : { + "code" : "0xef000101000402000100020400000000800000ab00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_175" : { + "code" : "0xef000101000402000100020400000000800000ac00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_176" : { + "code" : "0xef000101000402000100020400000000800000ad00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_177" : { + "code" : "0xef000101000402000100020400000000800000ae00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_178" : { + "code" : "0xef000101000402000100020400000000800000af00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_179" : { + "code" : "0xef000101000402000100020400000000800000b200", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_18" : { + "code" : "0xef0001010004020001000504000000008000026001801600", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_180" : { + "code" : "0xef000101000402000100020400000000800000b300", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_181" : { + "code" : "0xef000101000402000100020400000000800000b400", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_182" : { + "code" : "0xef000101000402000100020400000000800000b500", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_183" : { + "code" : "0xef000101000402000100020400000000800000b600", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_184" : { + "code" : "0xef000101000402000100020400000000800000b700", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_185" : { + "code" : "0xef000101000402000100020400000000800000b800", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_186" : { + "code" : "0xef000101000402000100020400000000800000b900", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_187" : { + "code" : "0xef000101000402000100020400000000800000ba00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_188" : { + "code" : "0xef000101000402000100020400000000800000bb00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_189" : { + "code" : "0xef000101000402000100020400000000800000bc00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_19" : { + "code" : "0xef0001010004020001000504000000008000026001801700", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_190" : { + "code" : "0xef000101000402000100020400000000800000bd00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_191" : { + "code" : "0xef000101000402000100020400000000800000be00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_192" : { + "code" : "0xef000101000402000100020400000000800000bf00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_193" : { + "code" : "0xef000101000402000100020400000000800000c000", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_194" : { + "code" : "0xef000101000402000100020400000000800000c100", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_195" : { + "code" : "0xef000101000402000100020400000000800000c200", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_196" : { + "code" : "0xef000101000402000100020400000000800000c300", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_197" : { + "code" : "0xef000101000402000100020400000000800000c400", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_198" : { + "code" : "0xef000101000402000100020400000000800000c500", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_199" : { + "code" : "0xef000101000402000100020400000000800000c600", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_2" : { + "code" : "0xef0001010004020001000504000000008000026001800200", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_20" : { + "code" : "0xef0001010004020001000504000000008000026001801800", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_200" : { + "code" : "0xef000101000402000100020400000000800000c700", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_201" : { + "code" : "0xef000101000402000100020400000000800000c800", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_202" : { + "code" : "0xef000101000402000100020400000000800000c900", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_203" : { + "code" : "0xef000101000402000100020400000000800000ca00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_204" : { + "code" : "0xef000101000402000100020400000000800000cb00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_205" : { + "code" : "0xef000101000402000100020400000000800000cc00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_206" : { + "code" : "0xef000101000402000100020400000000800000cd00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_207" : { + "code" : "0xef000101000402000100020400000000800000ce00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_208" : { + "code" : "0xef000101000402000100020400000000800000cf00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_209" : { + "code" : "0xef000101000402000100020400000000800000d400", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_21" : { + "code" : "0xef00010100040200010004040000000080000160011900", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_210" : { + "code" : "0xef000101000402000100020400000000800000d500", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_211" : { + "code" : "0xef000101000402000100020400000000800000d600", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_212" : { + "code" : "0xef000101000402000100020400000000800000d700", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_213" : { + "code" : "0xef000101000402000100020400000000800000d800", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_214" : { + "code" : "0xef000101000402000100020400000000800000d900", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_215" : { + "code" : "0xef000101000402000100020400000000800000da00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_216" : { + "code" : "0xef000101000402000100020400000000800000db00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_217" : { + "code" : "0xef000101000402000100020400000000800000dc00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_218" : { + "code" : "0xef000101000402000100020400000000800000dd00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_219" : { + "code" : "0xef000101000402000100020400000000800000de00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_22" : { + "code" : "0xef0001010004020001000504000000008000026001801a00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_220" : { + "code" : "0xef000101000402000100020400000000800000df00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_221" : { + "code" : "0xef000101000402000100020400000000800000e800", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_222" : { + "code" : "0xef000101000402000100020400000000800000e900", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_223" : { + "code" : "0xef000101000402000100020400000000800000ea00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_224" : { + "code" : "0xef000101000402000100020400000000800000eb00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_225" : { + "code" : "0xef000101000402000100020400000000800000ef00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_226" : { + "code" : "0xef000101000402000100020400000000800000f000", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_227" : { + "code" : "0xef000101000402000100020400000000800000f200", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_228" : { + "code" : "0xef000101000402000100020400000000800000f500", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_229" : { + "code" : "0xef000101000402000100020400000000800000f600", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_23" : { + "code" : "0xef0001010004020001000504000000008000026001801b00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_230" : { + "code" : "0xef000101000402000100020400000000800000f800", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_231" : { + "code" : "0xef000101000402000100020400000000800000f900", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_232" : { + "code" : "0xef000101000402000100020400000000800000fb00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_233" : { + "code" : "0xef000101000402000100020400000000800000fc00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_234" : { + "code" : "0xef000101000402000100020400000000800000ff00", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_235" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025560", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_236" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025561", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_237" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025561", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_238" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025562", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_239" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025562", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_24" : { + "code" : "0xef0001010004020001000504000000008000026001801c00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_240" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025563", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_241" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025563", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_242" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025564", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_243" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025564", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_244" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025565", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_245" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025565", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_246" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025566", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_247" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025566", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_248" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025567", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_249" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025567", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_25" : { + "code" : "0xef0001010004020001000504000000008000026001801d00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_250" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025568", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_251" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025568", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_252" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025569", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_253" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025569", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_254" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002556a", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_255" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002556a", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_256" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002556b", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_257" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002556b", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_258" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002556c", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_259" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002556c", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_26" : { + "code" : "0xef0001010004020001000504000000008000026001802000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_260" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002556d", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_261" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002556d", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_262" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002556e", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_263" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002556e", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_264" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002556f", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_265" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002556f", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_266" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025570", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_267" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025570", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_268" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025571", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_269" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025571", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_27" : { + "code" : "0xef0001010004020001000204000000008000013000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_270" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025572", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_271" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025572", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_272" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025573", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_273" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025573", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_274" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025574", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_275" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025574", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_276" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025575", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_277" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025575", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_278" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025576", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_279" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025576", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_28" : { + "code" : "0xef00010100040200010004040000000080000160013100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_280" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025577", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_281" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025577", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_282" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025578", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_283" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025578", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_284" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025579", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_285" : { + "code" : "0xef0001010004020001000b04000000008000026001600155600260025579", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_286" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002557a", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_287" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002557a", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_288" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002557b", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_289" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002557b", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_29" : { + "code" : "0xef0001010004020001000204000000008000013200", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_290" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002557c", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_291" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002557c", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_292" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002557d", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_293" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002557d", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_294" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002557e", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_295" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002557e", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_296" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002557f", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_297" : { + "code" : "0xef0001010004020001000b0400000000800002600160015560026002557f", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_298" : { + "code" : "0xef0001010004020001000c04000000008000026001600155600260025500fb", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_3" : { + "code" : "0xef0001010004020001000504000000008000026001800300", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_30" : { + "code" : "0xef0001010004020001000204000000008000013300", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_31" : { + "code" : "0xef0001010004020001000204000000008000013400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_32" : { + "code" : "0xef00010100040200010004040000000080000160013500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_33" : { + "code" : "0xef0001010004020001000204000000008000013600", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_34" : { + "code" : "0xef000101000402000100060400000000800003600180803700", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_35" : { + "code" : "0xef0001010004020001000204000000008000013800", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_36" : { + "code" : "0xef000101000402000100060400000000800003600180803900", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_37" : { + "code" : "0xef0001010004020001000204000000008000013a00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_38" : { + "code" : "0xef00010100040200010004040000000080000160013b00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_39" : { + "code" : "0xef00010100040200010007040000000080000460018080803c00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_4" : { + "code" : "0xef0001010004020001000504000000008000026001800400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_40" : { + "code" : "0xef0001010004020001000204000000008000013d00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_41" : { + "code" : "0xef000101000402000100060400000000800003600180803e00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_42" : { + "code" : "0xef00010100040200010004040000000080000160013f00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_43" : { + "code" : "0xef00010100040200010004040000000080000160014000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_44" : { + "code" : "0xef0001010004020001000204000000008000014100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_45" : { + "code" : "0xef0001010004020001000204000000008000014200", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_46" : { + "code" : "0xef0001010004020001000204000000008000014300", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_47" : { + "code" : "0xef0001010004020001000204000000008000014400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_48" : { + "code" : "0xef0001010004020001000204000000008000014500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_49" : { + "code" : "0xef0001010004020001000204000000008000014600", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_5" : { + "code" : "0xef0001010004020001000504000000008000026001800500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_50" : { + "code" : "0xef0001010004020001000204000000008000014700", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_51" : { + "code" : "0xef0001010004020001000204000000008000014800", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_52" : { + "code" : "0xef00010100040200010004040000000080000160014900", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_53" : { + "code" : "0xef0001010004020001000204000000008000014a00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_54" : { + "code" : "0xef00010100040200010004040000000080000160015000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_55" : { + "code" : "0xef00010100040200010004040000000080000160015100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_56" : { + "code" : "0xef0001010004020001000504000000008000026001805300", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_57" : { + "code" : "0xef00010100040200010004040000000080000160015400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_58" : { + "code" : "0xef0001010004020001000504000000008000026001805500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_59" : { + "code" : "0xef0001010004020001000204000000008000015900", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_6" : { + "code" : "0xef0001010004020001000504000000008000026001800600", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_60" : { + "code" : "0xef0001010004020001000204000000008000015a00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_61" : { + "code" : "0xef0001010004020001000204000000008000005b00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_62" : { + "code" : "0xef000101000402000100060400000000800003600180805e00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_63" : { + "code" : "0xef0001010004020001000204000000008000015f00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_64" : { + "code" : "0xef000101000402000100030400000000800001600100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_65" : { + "code" : "0xef00010100040200010004040000000080000161ffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_66" : { + "code" : "0xef00010100040200010005040000000080000162ffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_67" : { + "code" : "0xef00010100040200010006040000000080000163ffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_68" : { + "code" : "0xef00010100040200010007040000000080000164ffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_69" : { + "code" : "0xef00010100040200010008040000000080000165ffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_7" : { + "code" : "0xef0001010004020001000504000000008000026001800700", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_70" : { + "code" : "0xef00010100040200010009040000000080000166ffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_71" : { + "code" : "0xef0001010004020001000a040000000080000167ffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_72" : { + "code" : "0xef0001010004020001000b040000000080000168ffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_73" : { + "code" : "0xef0001010004020001000c040000000080000169ffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_74" : { + "code" : "0xef0001010004020001000d04000000008000016affffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_75" : { + "code" : "0xef0001010004020001000e04000000008000016bffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_76" : { + "code" : "0xef0001010004020001000f04000000008000016cffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_77" : { + "code" : "0xef0001010004020001001004000000008000016dffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_78" : { + "code" : "0xef0001010004020001001104000000008000016effffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_79" : { + "code" : "0xef0001010004020001001204000000008000016fffffffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_8" : { + "code" : "0xef000101000402000100060400000000800003600180800800", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_80" : { + "code" : "0xef00010100040200010013040000000080000170ffffffffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_81" : { + "code" : "0xef00010100040200010014040000000080000171ffffffffffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_82" : { + "code" : "0xef00010100040200010015040000000080000172ffffffffffffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_83" : { + "code" : "0xef00010100040200010016040000000080000173ffffffffffffffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_84" : { + "code" : "0xef00010100040200010017040000000080000174ffffffffffffffffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_85" : { + "code" : "0xef00010100040200010018040000000080000175ffffffffffffffffffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_86" : { + "code" : "0xef00010100040200010019040000000080000176ffffffffffffffffffffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_87" : { + "code" : "0xef0001010004020001001a040000000080000177ffffffffffffffffffffffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_88" : { + "code" : "0xef0001010004020001001b040000000080000178ffffffffffffffffffffffffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_89" : { + "code" : "0xef0001010004020001001c040000000080000179ffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_9" : { + "code" : "0xef000101000402000100060400000000800003600180800900", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_90" : { + "code" : "0xef0001010004020001001d04000000008000017affffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_91" : { + "code" : "0xef0001010004020001001e04000000008000017bffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_92" : { + "code" : "0xef0001010004020001001f04000000008000017cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_93" : { + "code" : "0xef0001010004020001002004000000008000017dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_94" : { + "code" : "0xef0001010004020001002104000000008000017effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_95" : { + "code" : "0xef0001010004020001002204000000008000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_96" : { + "code" : "0xef00010100040200010004040000000080000260018000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_97" : { + "code" : "0xef0001010004020001000504000000008000036001808100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_98" : { + "code" : "0xef000101000402000100060400000000800004600180808200", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_99" : { + "code" : "0xef00010100040200010007040000000080000560018080808300", + "results" : { + "Prague" : { + "result" : true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/EIP4200/validInvalid.json b/crates/interpreter/tests/EOFTests/EIP4200/validInvalid.json new file mode 100644 index 00000000..4d78c644 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/EIP4200/validInvalid.json @@ -0,0 +1,513 @@ +{ + "validInvalid" : { + "_info" : { + "comment" : "Test various examples to see if they are valid or invalid.\nImplements\n EOF1V4200_0001 (Valid) EOF code containing RJUMP (Positive, Negative) - Data index: 0\n EOF1V4200_0002 (Valid) EOF code containing RJUMP (Zero) - Data index: 1\n EOF1V4200_0003 (Valid) EOF with RJUMP containing the maximum offset (32767) - Data index: 2\n EOF1V4200_0004 (Valid) EOF code containing RJUMPI (Positive) - Data index: 3\n EOF1V4200_0005 (Valid) EOF code containing RJUMPI (Negative) - Data index: 4\n EOF1V4200_0006 (Valid) EOF code containing RJUMPI (Zero) - Data index: 5\n EOF1V4200_0007 (Valid) EOF with RJUMPI containing the maximum offset (32767) - Data index: 6\n EOF1V4200_0008 (Valid) EOF with RJUMPV table size 1 (Positive) - Data index: 7\n EOF1V4200_0009 (Valid) EOF with RJUMPV table size 1 (Negative) - Data index: 8\n EOF1V4200_0010 (Valid) EOF with RJUMPV table size 1 (Zero) - Data index: 9\n EOF1V4200_0011 (Valid) EOF with RJUMPV table size 3 - Data index: 10\n EOF1V4200_0012 (Valid) EOF with RJUMPV table size 256 (Target 0) - Data index: 11\n EOF1V4200_0013 (Valid) EOF with RJUMPV table size 256 (Target 100) - Data index: 12\n EOF1V4200_0014 (Valid) EOF with RJUMPV table size 256 (Target 254) - Data index: 13\n EOF1V4200_0015 (Valid) EOF with RJUMPV table size 256 (Target 256) - Data index: 14\n EOF1V4200_0016 (Valid) EOF with RJUMPV containing the maximum offset (32767) - Data index: 15\n EOF1I4200_0001 (Invalid) EOF code containing truncated RJUMP - Data index: 16\n EOF1I4200_0002 (Invalid) EOF code containing truncated RJUMP - Data index: 17\n EOF1I4200_0003 (Invalid) EOF code containing RJUMP with target outside code bounds (Jumping into header) - Data index: 18\n EOF1I4200_0004 (Invalid) EOF code containing RJUMP with target outside code bounds (Jumping before code begin) - Data index: 19\n EOF1I4200_0005 (Invalid) EOF code containing RJUMP with target outside code bounds (Jumping into data section) - Data index: 20\n EOF1I4200_0006 (Invalid) EOF code containing RJUMP with target outside code bounds (Jumping after code end) - Data index: 21\n EOF1I4200_0007 (Invalid) EOF code containing RJUMP with target outside code bounds (Jumping to code end) - Data index: 22\n EOF1I4200_0008 (Invalid) EOF code containing RJUMP with target self RJUMP immediate - Data index: 23\n EOF1I4200_0009 (Invalid) EOF code containing RJUMP with target other RJUMP immediate - Data index: 24\n EOF1I4200_0010 (Invalid) EOF code containing RJUMP with target RJUMPI immediate - Data index: 25\n EOF1I4200_0011 (Invalid) EOF code containing RJUMP with target PUSH immediate - Data index: 26\n EOF1I4200_0012 (Invalid) EOF code containing RJUMP with target RJUMPV immediate - Data index: 27\n EOF1I4200_0013 (Invalid) EOF code containing RJUMP with target CALLF immediate - Data index: 28\n EOF1I4200_0014 (Invalid) EOF code containing truncated RJUMPI - Data index: 29\n EOF1I4200_0015 (Invalid) EOF code containing truncated RJUMPI - Data index: 30\n EOF1I4200_0016 (Invalid) EOF code containing RJUMPI with target outside code bounds (Jumping into header) - Data index: 31\n EOF1I4200_0017 (Invalid) EOF code containing RJUMPI with target outside code bounds (Jumping to before code begin) - Data index: 32\n EOF1I4200_0018 (Invalid) EOF code containing RJUMPI with target outside code bounds (Jumping into data section) - Data index: 33\n EOF1I4200_0019 (Invalid) EOF code containing RJUMPI with target outside code bounds (Jumping to after code end) - Data index: 34\n EOF1I4200_0020 (Invalid) EOF code containing RJUMPI with target outside code bounds (Jumping to code end) - Data index: 35\n EOF1I4200_0021 (Invalid) EOF code containing RJUMPI with target same RJUMPI immediate - Data index: 36\n EOF1I4200_0022 (Invalid) EOF code containing RJUMPI with target other RJUMPI immediate - Data index: 37\n EOF1I4200_0023 (Invalid) EOF code containing RJUMPI with target RJUMP immediate - Data index: 38\n EOF1I4200_0024 (Invalid) EOF code containing RJUMPI with target PUSH immediate - Data index: 39\n EOF1I4200_0025 (Invalid) EOF code containing RJUMPI with target RJUMPV immediate - Data index: 40\n EOF1I4200_0026 (Invalid) EOF code containing RJUMPI with target CALLF immediate - Data index: 41\n EOF1I4200_0027 (Invalid) EOF code containing RJUMPV with max_index 0 but no immediates - Data index: 42\n EOF1I4200_0028 (Invalid) EOF code containing truncated RJUMPV - Data index: 43\n EOF1I4200_0029 (Invalid) EOF code containing truncated RJUMPV - Data index: 44\n EOF1I4200_0030 (Invalid) EOF code containing truncated RJUMPV - Data index: 45\n EOF1I4200_0031 (Invalid) EOF code containing RJUMPV with target outside code bounds (Jumping into header) - Data index: 46\n EOF1I4200_0032 (Invalid) EOF code containing RJUMPV with target outside code bounds (Jumping to before code begin) - Data index: 47\n EOF1I4200_0033 (Invalid) EOF code containing RJUMPV with target outside code bounds (Jumping into data section) - Data index: 48\n EOF1I4200_0034 (Invalid) EOF code containing RJUMPV with target outside code bounds (Jumping to after code end) - Data index: 49\n EOF1I4200_0035 (Invalid) EOF code containing RJUMPV with target outside code bounds (Jumping to code end) - Data index: 50\n EOF1I4200_0036 (Invalid) EOF code containing RJUMPV with target same RJUMPV immediate - Data index: 51\n EOF1I4200_0037 (Invalid) EOF code containing RJUMPV with target RJUMP immediate - Data index: 52\n EOF1I4200_0038 (Invalid) EOF code containing RJUMPV with target RJUMPI immediate - Data index: 53\n EOF1I4200_0039 (Invalid) EOF code containing RJUMPV with target PUSH immediate - Data index: 54\n EOF1I4200_0040 (Invalid) EOF code containing RJUMPV with target other RJUMPV immediate - Data index: 55\n EOF1I4200_0041 (Invalid) EOF code containing RJUMPV with target CALLF immediate - Data index: 56\n", + "filling-rpc-server" : "evmone-t8n 0.12.0-dev+commit.14ba7529", + "filling-tool-version" : "retesteth-0.3.2-cancun+commit.9d793abd.Linux.g++", + "generatedTestHash" : "6f6a515834f257803a49a1074b4a996638d699c74fddf6103d21e3d7f02f33c4", + "lllcversion" : "Version: 0.5.14-develop.2022.4.6+commit.401d5358.Linux.g++", + "solidity" : "Version: 0.8.18-develop.2023.1.16+commit.469d6d4d.Linux.g++", + "source" : "src/EOFTestsFiller/EIP4200/validInvalidFiller.yml", + "sourceHash" : "06fd1b57a7e0d80ade8000683de4e77b85a02306e9e4b6b66d42cc0f3b5ee2b8" + }, + "vectors" : { + "validInvalid_0" : { + "code" : "0xef0001010004020001001004000000008000025fe10003e00006600160015500e0fff7", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_1" : { + "code" : "0xef000101000402000100090400000000800002e00000600160015500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_10" : { + "code" : "0xef0001010004020001001304000000008000026000e20200030000fff65b5b00600160015500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_11" : { + "code" : "0xef0001010004020001030a04000000008000026000e2ff010000c600690073005100ff004a00ec002900cd00ba00ab00f200fb00e30046007c00c2005400f8001b00e800e7008d0076005a002e00630033009f00c9009a00660032000d00b70031005800a3005a0025005d00050017005800e9005e00d400ab00b200cd00c6009b00b400540011000e0082007400410021003d00dc0087007000e9003e00a1004100e100fc0067003e0001007e009700ea00dc006b0096008f0038005c002a00ec00b0003b00fb003200af003c005400ec001800db005c0002001a00fe004300fb00fa00aa003a00fb002900d100e60005003c007c0094007500d800be0061008900f9005c00bb00a80099000f009500b100eb00f100b3000500ef00f7000000e900a1003a00e500ca000b00cb00d000480047006400bd001f0023001e00a8001c007b006400c500140073005a00c5005e004b00790063003b0070006400240011009e000900dc00aa00d400ac00f2001b001000af003b003300cd00e30050004800470015005c00bb006f0022001900ba009b007d00f5000b00e1001a001c007f002300f8002900f800a4001b001300b500ca004e00e800980032003800e00079004d003d003400bc005f004e007700fa00cb006c000500ac00860021002b00aa001a005500a200be007000b50073003b0004005c00d30036009400b300af00e200f000e4009e004f00320015004900fd008200c500ff5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b00600160015500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_12" : { + "code" : "0xef0001010004020001030a04000000008000026064e2ff006700c600690073005100ff004a00ec002900cd00ba00ab00f200fb00e30046007c00c2005400f8001b00e800e7008d0076005a002e00630033009f00c9009a00660032000d00b70031005800a3005a0025005d00050017005800e9005e00d400ab00b200cd00c6009b00b400540011000e0082007400410021003d00dc0087007000e9003e00a1004100e100fc0067003e0001007e009700ea00dc006b0096008f0038005c002a00ec00b0003b00fb003200af003c005400ec001800db005c0002001a00fe0043010000fa00aa003a00fb002900d100e60005003c007c0094007500d800be0061008900f9005c00bb00a80099000f009500b100eb00f100b3000500ef00f7000000e900a1003a00e500ca000b00cb00d000480047006400bd001f0023001e00a8001c007b006400c500140073005a00c5005e004b00790063003b0070006400240011009e000900dc00aa00d400ac00f2001b001000af003b003300cd00e30050004800470015005c00bb006f0022001900ba009b007d00f5000b00e1001a001c007f002300f8002900f800a4001b001300b500ca004e00e800980032003800e00079004d003d003400bc005f004e007700fa00cb006c000500ac00860021002b00aa001a005500a200be007000b50073003b0004005c00d30036009400b300af00e200f000e4009e004f00320015004900fd008200c500ff5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b00600160015500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_13" : { + "code" : "0xef0001010004020001030a040000000080000260fee2ff006700c600690073005100ff004a00ec002900cd00ba00ab00f200fb00e30046007c00c2005400f8001b00e800e7008d0076005a002e00630033009f00c9009a00660032000d00b70031005800a3005a0025005d00050017005800e9005e00d400ab00b200cd00c6009b00b400540011000e0082007400410021003d00dc0087007000e9003e00a1004100e100fc0067003e0001007e009700ea00dc006b0096008f0038005c002a00ec00b0003b00fb003200af003c005400ec001800db005c0002001a00fe004300fb00fa00aa003a00fb002900d100e60005003c007c0094007500d800be0061008900f9005c00bb00a80099000f009500b100eb00f100b3000500ef00f7000000e900a1003a00e500ca000b00cb00d000480047006400bd001f0023001e00a8001c007b006400c500140073005a00c5005e004b00790063003b0070006400240011009e000900dc00aa00d400ac00f2001b001000af003b003300cd00e30050004800470015005c00bb006f0022001900ba009b007d00f5000b00e1001a001c007f002300f8002900f800a4001b001300b500ca004e00e800980032003800e00079004d003d003400bc005f004e007700fa00cb006c000500ac00860021002b00aa001a005500a200be007000b50073003b0004005c00d30036009400b300af00e200f000e4009e004f00320015004900fd0082010000c55b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b00600160015500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_14" : { + "code" : "0xef0001010004020001030a0400000000800002610100e2ff006700c600690073005100ff004a00ec002900cd00ba00ab00f200fb00e30046007c00c2005400f8001b00e800e7008d0076005a002e00630033009f00c9009a00660032000d00b70031005800a3005a0025005d00050017005800e9005e00d400ab00b200cd00c6009b00b400540011000e0082007400410021003d00dc0087007000e9003e00a1004100e100fc0067003e0001007e009700ea00dc006b0096008f0038005c002a00ec00b0003b00fb003200af003c005400ec001800db005c0002001a00fe004300fb00fa00aa003a00fb002900d100e60005003c007c0094007500d800be0061008900f9005c00bb00a80099000f009500b100eb00f100b3000500ef00f7000000e900a1003a00e500ca000b00cb00d000480047006400bd001f0023001e00a8001c007b006400c500140073005a00c5005e004b00790063003b0070006400240011009e000900dc00aa00d400ac00f2001b001000af003b003300cd00e30050004800470015005c00bb006f0022001900ba009b007d00f5000b00e1001a001c007f002300f8002900f800a4001b001300b500ca004e00e800980032003800e00079004d003d003400bc005f004e007700fa00cb006c000500ac00860021002b00aa001a005500a200be007000b50073003b0004005c00d30036009400b300af00e200f000e4009e004f00320015004900fd008200ff00c55b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600160015500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_15" : { + "code" : "0xef0001010004020001800b04000000008000026001e2007fff5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b6001600100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_16" : { + "code" : "0xef000101000402000100010400000000800000e0", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_17" : { + "code" : "0xef000101000402000100020400000000800000e000", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_18" : { + "code" : "0xef000101000402000100030400000000800000e0fffb", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_19" : { + "code" : "0xef000101000402000100030400000000800000e0ffe9", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_2" : { + "code" : "0xef0001010004020001800d04000000008000026000e10003e07fff5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600160015500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_20" : { + "code" : "0xef000101000402000100030400040000800000e00002aabbccdd", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_21" : { + "code" : "0xef000101000402000100030400000000800000e00002", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_22" : { + "code" : "0xef000101000402000100040400000000800000e0000100", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_23" : { + "code" : "0xef000101000402000100030400000000800000e0ffff", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_24" : { + "code" : "0xef000101000402000100070400000000800000e0000300e0fffc", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_25" : { + "code" : "0xef0001010004020001000a0400000000800000e00005006001e1fffa00", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_26" : { + "code" : "0xef0001010004020001000a0400000000800000e000025b600160015500", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_27" : { + "code" : "0xef0001010004020001000b0400000000800000e00005006001e200000000", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_28" : { + "code" : "0xef000101000802000200070006040000000080000000000002e00002e30001006001600155e4", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_29" : { + "code" : "0xef0001010004020001000304000000008000016000e1", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_3" : { + "code" : "0xef0001010004020001000e04000000008000026001e100035b5b00600160015500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_30" : { + "code" : "0xef0001010004020001000404000000008000016000e100", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_31" : { + "code" : "0xef0001010004020001000604000000008000016001e1fff900", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_32" : { + "code" : "0xef0001010004020001000604000000008000016001e1ffe700", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_33" : { + "code" : "0xef0001010004020001000604000400008000016001e1000200aabbccdd", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_34" : { + "code" : "0xef0001010004020001000604000000008000016001e1000200", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_35" : { + "code" : "0xef0001010004020001000604000000008000016001e1000100", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_36" : { + "code" : "0xef0001010004020001000604000000008000016001e1ffff00", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_37" : { + "code" : "0xef0001010004020001000c04000000008000016001e10005006001e1fff500", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_38" : { + "code" : "0xef0001010004020001000904000000008000016001e1000300e0fff7", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_39" : { + "code" : "0xef0001010004020001000604000000008000016001e1fffc00", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_4" : { + "code" : "0xef0001010004020001001104000000008000026001e100066001600155006001e1fff500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_40" : { + "code" : "0xef0001010004020001000d04000000008000016001e10005006001e200000000", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_41" : { + "code" : "0xef0001010008020002000900060400000000800001000000026001e10002e30001006001600155e4", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_42" : { + "code" : "0xef0001010004020001000404000000008000016001e200", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_43" : { + "code" : "0xef0001010004020001000304000000008000016001e2", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_44" : { + "code" : "0xef0001010004020001000404000000008000016001e200", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_45" : { + "code" : "0xef0001010004020001000504000000008000016001e20000", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_46" : { + "code" : "0xef0001010004020001000704000000008000016001e200fff900", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_47" : { + "code" : "0xef0001010004020001000704000000008000016001e200fff100", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_48" : { + "code" : "0xef0001010004020001000704000400008000016001e200000200aabbccdd", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_49" : { + "code" : "0xef0001010004020001000704000000008000016001e200000200", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_5" : { + "code" : "0xef0001010004020001000b04000000008000026001e10000600160015500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_50" : { + "code" : "0xef0001010004020001000704000000008000016001e200000100", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_51" : { + "code" : "0xef0001010004020001000704000000008000016001e200ffff00", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_52" : { + "code" : "0xef0001010004020001000d04000000008000016001e2000005006001e0fff700", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_53" : { + "code" : "0xef0001010004020001000d04000000008000016001e2000005006001e1fff700", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_54" : { + "code" : "0xef0001010004020001000d04000000008000016001e200000200600160015500", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_55" : { + "code" : "0xef0001010004020001000e04000000008000016001e2000005006001e200000000", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_56" : { + "code" : "0xef0001010008020002000a00060400000000800001000000026000e2000002e30001006001600155e4", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_6" : { + "code" : "0xef0001010004020001800b04000000008000026001e17fff5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600160015500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_7" : { + "code" : "0xef0001010004020001000f04000000008000026000e20000035b5b00600160015500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_8" : { + "code" : "0xef0001010004020001001204000000008000026001e100066001600155006000e200fff400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_9" : { + "code" : "0xef0001010004020001000c04000000008000026000e2000000600160015500", + "results" : { + "Prague" : { + "result" : true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/EIP4750/validInvalid.json b/crates/interpreter/tests/EOFTests/EIP4750/validInvalid.json new file mode 100644 index 00000000..0e07dd48 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/EIP4750/validInvalid.json @@ -0,0 +1,323 @@ +{ + "validInvalid" : { + "_info" : { + "comment" : "Test various examples to see if they are valid or invalid.\nImplements\n EOF1V4750_0001 (Valid) EOF code containing single type section - Data index: 0\n EOF1V4750_0002 (Valid) EOF code containing single type section and data section - Data index: 1\n EOF1V4750_0003 (Valid) EOF code containing multiple type/code sections - Data index: 2\n EOF1V4750_0004 (Valid) EOF code containing multiple type/code sections and data section - Data index: 3\n EOF1V4750_0005 (Valid) EOF code containing multiple type/code sections, no void I/O types - Data index: 4\n EOF1V4750_0006 (Valid) EOF code containing multiple type/code sections, no void I/O types, containing data section - Data index: 5\n EOF1V4750_0007 (Valid) EOF code containing the maximum number of code sections - Data index: 6\n EOF1V4750_0008 (Valid) EOF code containing the maximum number of code sections and data section - Data index: 7\n EOF1I4750_0001 (Invalid) EOF code missing mandatory type section - Data index: 8\n EOF1I4750_0002 (Invalid) EOF code containing multiple type headers - Data index: 9\n EOF1I4750_0003 (Invalid) EOF code containing type section size (Size 1) - Data index: 10\n EOF1I4750_0004 (Invalid) EOF code containing type section size (Size 8 - 1 Code section) - Data index: 11\n EOF1I4750_0005 (Invalid) EOF code containing type section size (Size 8 - 3 Code sections) - Data index: 12\n EOF1I4750_0006 (Invalid) EOF code containing invalid section type (1,0) (First section having a type different than (0,0x80)) - Data index: 13\n EOF1I4750_0007 (Invalid) EOF code containing invalid section type (0,1) (First section having a type different than (0,0x80)) - Data index: 14\n EOF1I4750_0008 (Invalid) EOF code containing invalid section type (2,3) (First section having a type different than (0,0x80)) - Data index: 15\n EOF1I4750_0009 (Invalid) EOF code containing too many code sections - Data index: 16\n EOF1I4750_0010 (Invalid) EOF code containing CALLF to a non existing code section - Data index: 17\n EOF1I4750_0011 (Invalid) EOF code containing truncated CALLF - Data index: 18\n EOF1I4750_0012 (Invalid) EOF code containing deprecated instruction (JUMP) - Data index: 19\n EOF1I4750_0013 (Invalid) EOF code containing deprecated instruction (JUMPI) - Data index: 20\n EOF1I4750_0014 (Invalid) EOF code containing deprecated instruction (PC) - Data index: 21\n EOF1I4750_0015 (Invalid) EOF code containing deprecated instruction (SELFDESTRUCT) - Data index: 22\n EOF1I4750_0016 (Invalid) EOF code containing deprecated instruction (CALLCODE) - Data index: 23\n EOF1I4750_0017 (Invalid) EOF code containing deprecated instruction (CREATE) - Data index: 24\n EOF1I4750_0018 (Invalid) EOF code containing deprecated instruction (CREATE2) - Data index: 25\n EOF1I4750_0019 (Invalid) EOF code containing call to functions without required stack specified in type section - Data index: 26\n EOF1I4750_0020 (Invalid) EOF code containing call to functions without required stack NOT specified in type section - Data index: 27\n EOF1I4750_0021 (Invalid) EOF code containing function trying to return more items than specified in type section - Data index: 28\n EOF1I4750_0022 (Invalid) EOF code containing function exceeding max stack items - Data index: 29\n EOF1I4750_0023 (Invalid) EOF code containing function which max stack height causes to exceed max stack items (stack overflow) - Data index: 30\n EOF1I4750_0024 (Invalid) EOF code containing RETF as terminating instruction in first code section (a) Marking first section as returning - Data index: 31\n EOF1I4750_0025 (Invalid) EOF code containing RETF as terminating instruction in first code section (b) Marking first section as non-returning - Data index: 32\n EOF1I4750_0026 (Invalid) EOF code containing RETF as terminating instruction in first code section, containing data section (a) Marking first section as returning - Data index: 33\n EOF1I4750_0027 (Invalid) EOF code containing RETF as terminating instruction in first code section, containing data section (b) Marking first section as non-returning - Data index: 34\n", + "filling-rpc-server" : "evmone-t8n 0.12.0-dev+commit.14ba7529", + "filling-tool-version" : "retesteth-0.3.2-cancun+commit.9d793abd.Linux.g++", + "generatedTestHash" : "c52f3b975197f1d77a471f473a590881508b5388acdbd60f6c7b5b7f8af2ffb5", + "lllcversion" : "Version: 0.5.14-develop.2022.4.6+commit.401d5358.Linux.g++", + "solidity" : "Version: 0.8.18-develop.2023.1.16+commit.469d6d4d.Linux.g++", + "source" : "src/EOFTestsFiller/EIP4750/validInvalidFiller.yml", + "sourceHash" : "40e46dcbdfd6e64cfb79154c4cf88a0fb32571e29cffb6e1bb1ef744e464744b" + }, + "vectors" : { + "validInvalid_0" : { + "code" : "0xef000101000402000100010400000000800000fe", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_1" : { + "code" : "0xef000101000402000100010400010000800000feda", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_10" : { + "code" : "0xef000101000102000100010400000000800000fe", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidSectionBodiesSize", + "result" : false + } + } + }, + "validInvalid_11" : { + "code" : "0xef000101000802000100010400000000800000fe", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidSectionBodiesSize", + "result" : false + } + } + }, + "validInvalid_12" : { + "code" : "0xef0001010008020003000100010001040000000080000000800000fefefe", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidTypeSectionSize", + "result" : false + } + } + }, + "validInvalid_13" : { + "code" : "0xef000101000402000100010400000001000000fe", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidFirstSectionType", + "result" : false + } + } + }, + "validInvalid_14" : { + "code" : "0xef000101000402000100010400000000010000fe", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidFirstSectionType", + "result" : false + } + } + }, + "validInvalid_15" : { + "code" : "0xef000101000402000100010400000002030000fe", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidFirstSectionType", + "result" : false + } + } + }, + "validInvalid_16" : { + "code" : "0xef000101100402040100040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040001040000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e3000100e30002e4e30003e4e30004e4e30005e4e30006e4e30007e4e30008e4e30009e4e3000ae4e3000be4e3000ce4e3000de4e3000ee4e3000fe4e30010e4e30011e4e30012e4e30013e4e30014e4e30015e4e30016e4e30017e4e30018e4e30019e4e3001ae4e3001be4e3001ce4e3001de4e3001ee4e3001fe4e30020e4e30021e4e30022e4e30023e4e30024e4e30025e4e30026e4e30027e4e30028e4e30029e4e3002ae4e3002be4e3002ce4e3002de4e3002ee4e3002fe4e30030e4e30031e4e30032e4e30033e4e30034e4e30035e4e30036e4e30037e4e30038e4e30039e4e3003ae4e3003be4e3003ce4e3003de4e3003ee4e3003fe4e30040e4e30041e4e30042e4e30043e4e30044e4e30045e4e30046e4e30047e4e30048e4e30049e4e3004ae4e3004be4e3004ce4e3004de4e3004ee4e3004fe4e30050e4e30051e4e30052e4e30053e4e30054e4e30055e4e30056e4e30057e4e30058e4e30059e4e3005ae4e3005be4e3005ce4e3005de4e3005ee4e3005fe4e30060e4e30061e4e30062e4e30063e4e30064e4e30065e4e30066e4e30067e4e30068e4e30069e4e3006ae4e3006be4e3006ce4e3006de4e3006ee4e3006fe4e30070e4e30071e4e30072e4e30073e4e30074e4e30075e4e30076e4e30077e4e30078e4e30079e4e3007ae4e3007be4e3007ce4e3007de4e3007ee4e3007fe4e30080e4e30081e4e30082e4e30083e4e30084e4e30085e4e30086e4e30087e4e30088e4e30089e4e3008ae4e3008be4e3008ce4e3008de4e3008ee4e3008fe4e30090e4e30091e4e30092e4e30093e4e30094e4e30095e4e30096e4e30097e4e30098e4e30099e4e3009ae4e3009be4e3009ce4e3009de4e3009ee4e3009fe4e300a0e4e300a1e4e300a2e4e300a3e4e300a4e4e300a5e4e300a6e4e300a7e4e300a8e4e300a9e4e300aae4e300abe4e300ace4e300ade4e300aee4e300afe4e300b0e4e300b1e4e300b2e4e300b3e4e300b4e4e300b5e4e300b6e4e300b7e4e300b8e4e300b9e4e300bae4e300bbe4e300bce4e300bde4e300bee4e300bfe4e300c0e4e300c1e4e300c2e4e300c3e4e300c4e4e300c5e4e300c6e4e300c7e4e300c8e4e300c9e4e300cae4e300cbe4e300cce4e300cde4e300cee4e300cfe4e300d0e4e300d1e4e300d2e4e300d3e4e300d4e4e300d5e4e300d6e4e300d7e4e300d8e4e300d9e4e300dae4e300dbe4e300dce4e300dde4e300dee4e300dfe4e300e0e4e300e1e4e300e2e4e300e3e4e300e4e4e300e5e4e300e6e4e300e7e4e300e8e4e300e9e4e300eae4e300ebe4e300ece4e300ede4e300eee4e300efe4e300f0e4e300f1e4e300f2e4e300f3e4e300f4e4e300f5e4e300f6e4e300f7e4e300f8e4e300f9e4e300fae4e300fbe4e300fce4e300fde4e300fee4e300ffe4e30100e4e30101e4e30102e4e30103e4e30104e4e30105e4e30106e4e30107e4e30108e4e30109e4e3010ae4e3010be4e3010ce4e3010de4e3010ee4e3010fe4e30110e4e30111e4e30112e4e30113e4e30114e4e30115e4e30116e4e30117e4e30118e4e30119e4e3011ae4e3011be4e3011ce4e3011de4e3011ee4e3011fe4e30120e4e30121e4e30122e4e30123e4e30124e4e30125e4e30126e4e30127e4e30128e4e30129e4e3012ae4e3012be4e3012ce4e3012de4e3012ee4e3012fe4e30130e4e30131e4e30132e4e30133e4e30134e4e30135e4e30136e4e30137e4e30138e4e30139e4e3013ae4e3013be4e3013ce4e3013de4e3013ee4e3013fe4e30140e4e30141e4e30142e4e30143e4e30144e4e30145e4e30146e4e30147e4e30148e4e30149e4e3014ae4e3014be4e3014ce4e3014de4e3014ee4e3014fe4e30150e4e30151e4e30152e4e30153e4e30154e4e30155e4e30156e4e30157e4e30158e4e30159e4e3015ae4e3015be4e3015ce4e3015de4e3015ee4e3015fe4e30160e4e30161e4e30162e4e30163e4e30164e4e30165e4e30166e4e30167e4e30168e4e30169e4e3016ae4e3016be4e3016ce4e3016de4e3016ee4e3016fe4e30170e4e30171e4e30172e4e30173e4e30174e4e30175e4e30176e4e30177e4e30178e4e30179e4e3017ae4e3017be4e3017ce4e3017de4e3017ee4e3017fe4e30180e4e30181e4e30182e4e30183e4e30184e4e30185e4e30186e4e30187e4e30188e4e30189e4e3018ae4e3018be4e3018ce4e3018de4e3018ee4e3018fe4e30190e4e30191e4e30192e4e30193e4e30194e4e30195e4e30196e4e30197e4e30198e4e30199e4e3019ae4e3019be4e3019ce4e3019de4e3019ee4e3019fe4e301a0e4e301a1e4e301a2e4e301a3e4e301a4e4e301a5e4e301a6e4e301a7e4e301a8e4e301a9e4e301aae4e301abe4e301ace4e301ade4e301aee4e301afe4e301b0e4e301b1e4e301b2e4e301b3e4e301b4e4e301b5e4e301b6e4e301b7e4e301b8e4e301b9e4e301bae4e301bbe4e301bce4e301bde4e301bee4e301bfe4e301c0e4e301c1e4e301c2e4e301c3e4e301c4e4e301c5e4e301c6e4e301c7e4e301c8e4e301c9e4e301cae4e301cbe4e301cce4e301cde4e301cee4e301cfe4e301d0e4e301d1e4e301d2e4e301d3e4e301d4e4e301d5e4e301d6e4e301d7e4e301d8e4e301d9e4e301dae4e301dbe4e301dce4e301dde4e301dee4e301dfe4e301e0e4e301e1e4e301e2e4e301e3e4e301e4e4e301e5e4e301e6e4e301e7e4e301e8e4e301e9e4e301eae4e301ebe4e301ece4e301ede4e301eee4e301efe4e301f0e4e301f1e4e301f2e4e301f3e4e301f4e4e301f5e4e301f6e4e301f7e4e301f8e4e301f9e4e301fae4e301fbe4e301fce4e301fde4e301fee4e301ffe4e30200e4e30201e4e30202e4e30203e4e30204e4e30205e4e30206e4e30207e4e30208e4e30209e4e3020ae4e3020be4e3020ce4e3020de4e3020ee4e3020fe4e30210e4e30211e4e30212e4e30213e4e30214e4e30215e4e30216e4e30217e4e30218e4e30219e4e3021ae4e3021be4e3021ce4e3021de4e3021ee4e3021fe4e30220e4e30221e4e30222e4e30223e4e30224e4e30225e4e30226e4e30227e4e30228e4e30229e4e3022ae4e3022be4e3022ce4e3022de4e3022ee4e3022fe4e30230e4e30231e4e30232e4e30233e4e30234e4e30235e4e30236e4e30237e4e30238e4e30239e4e3023ae4e3023be4e3023ce4e3023de4e3023ee4e3023fe4e30240e4e30241e4e30242e4e30243e4e30244e4e30245e4e30246e4e30247e4e30248e4e30249e4e3024ae4e3024be4e3024ce4e3024de4e3024ee4e3024fe4e30250e4e30251e4e30252e4e30253e4e30254e4e30255e4e30256e4e30257e4e30258e4e30259e4e3025ae4e3025be4e3025ce4e3025de4e3025ee4e3025fe4e30260e4e30261e4e30262e4e30263e4e30264e4e30265e4e30266e4e30267e4e30268e4e30269e4e3026ae4e3026be4e3026ce4e3026de4e3026ee4e3026fe4e30270e4e30271e4e30272e4e30273e4e30274e4e30275e4e30276e4e30277e4e30278e4e30279e4e3027ae4e3027be4e3027ce4e3027de4e3027ee4e3027fe4e30280e4e30281e4e30282e4e30283e4e30284e4e30285e4e30286e4e30287e4e30288e4e30289e4e3028ae4e3028be4e3028ce4e3028de4e3028ee4e3028fe4e30290e4e30291e4e30292e4e30293e4e30294e4e30295e4e30296e4e30297e4e30298e4e30299e4e3029ae4e3029be4e3029ce4e3029de4e3029ee4e3029fe4e302a0e4e302a1e4e302a2e4e302a3e4e302a4e4e302a5e4e302a6e4e302a7e4e302a8e4e302a9e4e302aae4e302abe4e302ace4e302ade4e302aee4e302afe4e302b0e4e302b1e4e302b2e4e302b3e4e302b4e4e302b5e4e302b6e4e302b7e4e302b8e4e302b9e4e302bae4e302bbe4e302bce4e302bde4e302bee4e302bfe4e302c0e4e302c1e4e302c2e4e302c3e4e302c4e4e302c5e4e302c6e4e302c7e4e302c8e4e302c9e4e302cae4e302cbe4e302cce4e302cde4e302cee4e302cfe4e302d0e4e302d1e4e302d2e4e302d3e4e302d4e4e302d5e4e302d6e4e302d7e4e302d8e4e302d9e4e302dae4e302dbe4e302dce4e302dde4e302dee4e302dfe4e302e0e4e302e1e4e302e2e4e302e3e4e302e4e4e302e5e4e302e6e4e302e7e4e302e8e4e302e9e4e302eae4e302ebe4e302ece4e302ede4e302eee4e302efe4e302f0e4e302f1e4e302f2e4e302f3e4e302f4e4e302f5e4e302f6e4e302f7e4e302f8e4e302f9e4e302fae4e302fbe4e302fce4e302fde4e302fee4e302ffe4e30300e4e30301e4e30302e4e30303e4e30304e4e30305e4e30306e4e30307e4e30308e4e30309e4e3030ae4e3030be4e3030ce4e3030de4e3030ee4e3030fe4e30310e4e30311e4e30312e4e30313e4e30314e4e30315e4e30316e4e30317e4e30318e4e30319e4e3031ae4e3031be4e3031ce4e3031de4e3031ee4e3031fe4e30320e4e30321e4e30322e4e30323e4e30324e4e30325e4e30326e4e30327e4e30328e4e30329e4e3032ae4e3032be4e3032ce4e3032de4e3032ee4e3032fe4e30330e4e30331e4e30332e4e30333e4e30334e4e30335e4e30336e4e30337e4e30338e4e30339e4e3033ae4e3033be4e3033ce4e3033de4e3033ee4e3033fe4e30340e4e30341e4e30342e4e30343e4e30344e4e30345e4e30346e4e30347e4e30348e4e30349e4e3034ae4e3034be4e3034ce4e3034de4e3034ee4e3034fe4e30350e4e30351e4e30352e4e30353e4e30354e4e30355e4e30356e4e30357e4e30358e4e30359e4e3035ae4e3035be4e3035ce4e3035de4e3035ee4e3035fe4e30360e4e30361e4e30362e4e30363e4e30364e4e30365e4e30366e4e30367e4e30368e4e30369e4e3036ae4e3036be4e3036ce4e3036de4e3036ee4e3036fe4e30370e4e30371e4e30372e4e30373e4e30374e4e30375e4e30376e4e30377e4e30378e4e30379e4e3037ae4e3037be4e3037ce4e3037de4e3037ee4e3037fe4e30380e4e30381e4e30382e4e30383e4e30384e4e30385e4e30386e4e30387e4e30388e4e30389e4e3038ae4e3038be4e3038ce4e3038de4e3038ee4e3038fe4e30390e4e30391e4e30392e4e30393e4e30394e4e30395e4e30396e4e30397e4e30398e4e30399e4e3039ae4e3039be4e3039ce4e3039de4e3039ee4e3039fe4e303a0e4e303a1e4e303a2e4e303a3e4e303a4e4e303a5e4e303a6e4e303a7e4e303a8e4e303a9e4e303aae4e303abe4e303ace4e303ade4e303aee4e303afe4e303b0e4e303b1e4e303b2e4e303b3e4e303b4e4e303b5e4e303b6e4e303b7e4e303b8e4e303b9e4e303bae4e303bbe4e303bce4e303bde4e303bee4e303bfe4e303c0e4e303c1e4e303c2e4e303c3e4e303c4e4e303c5e4e303c6e4e303c7e4e303c8e4e303c9e4e303cae4e303cbe4e303cce4e303cde4e303cee4e303cfe4e303d0e4e303d1e4e303d2e4e303d3e4e303d4e4e303d5e4e303d6e4e303d7e4e303d8e4e303d9e4e303dae4e303dbe4e303dce4e303dde4e303dee4e303dfe4e303e0e4e303e1e4e303e2e4e303e3e4e303e4e4e303e5e4e303e6e4e303e7e4e303e8e4e303e9e4e303eae4e303ebe4e303ece4e303ede4e303eee4e303efe4e303f0e4e303f1e4e303f2e4e303f3e4e303f4e4e303f5e4e303f6e4e303f7e4e303f8e4e303f9e4e303fae4e303fbe4e303fce4e303fde4e303fee4e303ffe4e30400e4e4", + "results" : { + "Prague" : { + "exception" : "EOF_TooManyCodeSections", + "result" : false + } + } + }, + "validInvalid_17" : { + "code" : "0xef000101000402000100040400000000800000e3000100", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidCodeSectionIndex", + "result" : false + } + } + }, + "validInvalid_18" : { + "code" : "0xef000101000402000100020400000000800000e300", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_19" : { + "code" : "0xef0001010004020001000b0400000000800001600456fe5b600160015500", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_2" : { + "code" : "0xef000101000802000200040001040000000080000000000000e3000100e4", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_20" : { + "code" : "0xef0001010004020001000d04000000008000026006600157fe5b600160015500", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_21" : { + "code" : "0xef0001010004020001000504000000008000025860015500", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_22" : { + "code" : "0xef0001010004020001000304000000008000016001ff", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_23" : { + "code" : "0xef0001010004020001000a04000000008000076001808080808080f200", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_24" : { + "code" : "0xef00010100040200010006040000000080000360018080f000", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_25" : { + "code" : "0xef0001010004020001000704000000008000046001808080f500", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_26" : { + "code" : "0xef000101000802000200040002040000000080000002010002e300010001e4", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_27" : { + "code" : "0xef00010100080200020008000204000000008000020000000060016001e300010001e4", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_28" : { + "code" : "0xef000101000802000200040003040000000080000000000001e30001006001e4", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidNumberOfOutputs", + "result" : false + } + } + }, + "validInvalid_29" : { + "code" : "0xef00010100080200020404000504000000008004020003000360018080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080e300010060028080e4", + "results" : { + "Prague" : { + "exception" : "EOF_MaxStackHeightExceeded", + "result" : false + } + } + }, + "validInvalid_3" : { + "code" : "0xef000101000802000200040001040001000080000000000000e3000100e4da", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_30" : { + "code" : "0xef00010100080200020404000804000000008003ff0000000360018080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080e300010060018080505050e4", + "results" : { + "Prague" : { + "exception" : "EOF_StackOverflow", + "result" : false + } + } + }, + "validInvalid_31" : { + "code" : "0xef000101000402000100010400000000000000e4", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidFirstSectionType", + "result" : false + } + } + }, + "validInvalid_32" : { + "code" : "0xef000101000402000100010400000000800000e4", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidNonReturningFlag", + "result" : false + } + } + }, + "validInvalid_33" : { + "code" : "0xef000101000402000100010400010000000000e4da", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidFirstSectionType", + "result" : false + } + } + }, + "validInvalid_34" : { + "code" : "0xef000101000402000100010400000000800000e4", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidNonReturningFlag", + "result" : false + } + } + }, + "validInvalid_4" : { + "code" : "0xef0001010010020004000f00020002000204000000008000030100000100010001020300035fe30001e300025fe300035050500050e430e480e4", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_5" : { + "code" : "0xef0001010010020004000f00020002000204000100008000030100000100010001020300035fe30001e300025fe300035050500050e430e480e4da", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_6" : { + "code" : "0xef000101100002040000040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400010400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e3000100e30002e4e30003e4e30004e4e30005e4e30006e4e30007e4e30008e4e30009e4e3000ae4e3000be4e3000ce4e3000de4e3000ee4e3000fe4e30010e4e30011e4e30012e4e30013e4e30014e4e30015e4e30016e4e30017e4e30018e4e30019e4e3001ae4e3001be4e3001ce4e3001de4e3001ee4e3001fe4e30020e4e30021e4e30022e4e30023e4e30024e4e30025e4e30026e4e30027e4e30028e4e30029e4e3002ae4e3002be4e3002ce4e3002de4e3002ee4e3002fe4e30030e4e30031e4e30032e4e30033e4e30034e4e30035e4e30036e4e30037e4e30038e4e30039e4e3003ae4e3003be4e3003ce4e3003de4e3003ee4e3003fe4e30040e4e30041e4e30042e4e30043e4e30044e4e30045e4e30046e4e30047e4e30048e4e30049e4e3004ae4e3004be4e3004ce4e3004de4e3004ee4e3004fe4e30050e4e30051e4e30052e4e30053e4e30054e4e30055e4e30056e4e30057e4e30058e4e30059e4e3005ae4e3005be4e3005ce4e3005de4e3005ee4e3005fe4e30060e4e30061e4e30062e4e30063e4e30064e4e30065e4e30066e4e30067e4e30068e4e30069e4e3006ae4e3006be4e3006ce4e3006de4e3006ee4e3006fe4e30070e4e30071e4e30072e4e30073e4e30074e4e30075e4e30076e4e30077e4e30078e4e30079e4e3007ae4e3007be4e3007ce4e3007de4e3007ee4e3007fe4e30080e4e30081e4e30082e4e30083e4e30084e4e30085e4e30086e4e30087e4e30088e4e30089e4e3008ae4e3008be4e3008ce4e3008de4e3008ee4e3008fe4e30090e4e30091e4e30092e4e30093e4e30094e4e30095e4e30096e4e30097e4e30098e4e30099e4e3009ae4e3009be4e3009ce4e3009de4e3009ee4e3009fe4e300a0e4e300a1e4e300a2e4e300a3e4e300a4e4e300a5e4e300a6e4e300a7e4e300a8e4e300a9e4e300aae4e300abe4e300ace4e300ade4e300aee4e300afe4e300b0e4e300b1e4e300b2e4e300b3e4e300b4e4e300b5e4e300b6e4e300b7e4e300b8e4e300b9e4e300bae4e300bbe4e300bce4e300bde4e300bee4e300bfe4e300c0e4e300c1e4e300c2e4e300c3e4e300c4e4e300c5e4e300c6e4e300c7e4e300c8e4e300c9e4e300cae4e300cbe4e300cce4e300cde4e300cee4e300cfe4e300d0e4e300d1e4e300d2e4e300d3e4e300d4e4e300d5e4e300d6e4e300d7e4e300d8e4e300d9e4e300dae4e300dbe4e300dce4e300dde4e300dee4e300dfe4e300e0e4e300e1e4e300e2e4e300e3e4e300e4e4e300e5e4e300e6e4e300e7e4e300e8e4e300e9e4e300eae4e300ebe4e300ece4e300ede4e300eee4e300efe4e300f0e4e300f1e4e300f2e4e300f3e4e300f4e4e300f5e4e300f6e4e300f7e4e300f8e4e300f9e4e300fae4e300fbe4e300fce4e300fde4e300fee4e300ffe4e30100e4e30101e4e30102e4e30103e4e30104e4e30105e4e30106e4e30107e4e30108e4e30109e4e3010ae4e3010be4e3010ce4e3010de4e3010ee4e3010fe4e30110e4e30111e4e30112e4e30113e4e30114e4e30115e4e30116e4e30117e4e30118e4e30119e4e3011ae4e3011be4e3011ce4e3011de4e3011ee4e3011fe4e30120e4e30121e4e30122e4e30123e4e30124e4e30125e4e30126e4e30127e4e30128e4e30129e4e3012ae4e3012be4e3012ce4e3012de4e3012ee4e3012fe4e30130e4e30131e4e30132e4e30133e4e30134e4e30135e4e30136e4e30137e4e30138e4e30139e4e3013ae4e3013be4e3013ce4e3013de4e3013ee4e3013fe4e30140e4e30141e4e30142e4e30143e4e30144e4e30145e4e30146e4e30147e4e30148e4e30149e4e3014ae4e3014be4e3014ce4e3014de4e3014ee4e3014fe4e30150e4e30151e4e30152e4e30153e4e30154e4e30155e4e30156e4e30157e4e30158e4e30159e4e3015ae4e3015be4e3015ce4e3015de4e3015ee4e3015fe4e30160e4e30161e4e30162e4e30163e4e30164e4e30165e4e30166e4e30167e4e30168e4e30169e4e3016ae4e3016be4e3016ce4e3016de4e3016ee4e3016fe4e30170e4e30171e4e30172e4e30173e4e30174e4e30175e4e30176e4e30177e4e30178e4e30179e4e3017ae4e3017be4e3017ce4e3017de4e3017ee4e3017fe4e30180e4e30181e4e30182e4e30183e4e30184e4e30185e4e30186e4e30187e4e30188e4e30189e4e3018ae4e3018be4e3018ce4e3018de4e3018ee4e3018fe4e30190e4e30191e4e30192e4e30193e4e30194e4e30195e4e30196e4e30197e4e30198e4e30199e4e3019ae4e3019be4e3019ce4e3019de4e3019ee4e3019fe4e301a0e4e301a1e4e301a2e4e301a3e4e301a4e4e301a5e4e301a6e4e301a7e4e301a8e4e301a9e4e301aae4e301abe4e301ace4e301ade4e301aee4e301afe4e301b0e4e301b1e4e301b2e4e301b3e4e301b4e4e301b5e4e301b6e4e301b7e4e301b8e4e301b9e4e301bae4e301bbe4e301bce4e301bde4e301bee4e301bfe4e301c0e4e301c1e4e301c2e4e301c3e4e301c4e4e301c5e4e301c6e4e301c7e4e301c8e4e301c9e4e301cae4e301cbe4e301cce4e301cde4e301cee4e301cfe4e301d0e4e301d1e4e301d2e4e301d3e4e301d4e4e301d5e4e301d6e4e301d7e4e301d8e4e301d9e4e301dae4e301dbe4e301dce4e301dde4e301dee4e301dfe4e301e0e4e301e1e4e301e2e4e301e3e4e301e4e4e301e5e4e301e6e4e301e7e4e301e8e4e301e9e4e301eae4e301ebe4e301ece4e301ede4e301eee4e301efe4e301f0e4e301f1e4e301f2e4e301f3e4e301f4e4e301f5e4e301f6e4e301f7e4e301f8e4e301f9e4e301fae4e301fbe4e301fce4e301fde4e301fee4e301ffe4e30200e4e30201e4e30202e4e30203e4e30204e4e30205e4e30206e4e30207e4e30208e4e30209e4e3020ae4e3020be4e3020ce4e3020de4e3020ee4e3020fe4e30210e4e30211e4e30212e4e30213e4e30214e4e30215e4e30216e4e30217e4e30218e4e30219e4e3021ae4e3021be4e3021ce4e3021de4e3021ee4e3021fe4e30220e4e30221e4e30222e4e30223e4e30224e4e30225e4e30226e4e30227e4e30228e4e30229e4e3022ae4e3022be4e3022ce4e3022de4e3022ee4e3022fe4e30230e4e30231e4e30232e4e30233e4e30234e4e30235e4e30236e4e30237e4e30238e4e30239e4e3023ae4e3023be4e3023ce4e3023de4e3023ee4e3023fe4e30240e4e30241e4e30242e4e30243e4e30244e4e30245e4e30246e4e30247e4e30248e4e30249e4e3024ae4e3024be4e3024ce4e3024de4e3024ee4e3024fe4e30250e4e30251e4e30252e4e30253e4e30254e4e30255e4e30256e4e30257e4e30258e4e30259e4e3025ae4e3025be4e3025ce4e3025de4e3025ee4e3025fe4e30260e4e30261e4e30262e4e30263e4e30264e4e30265e4e30266e4e30267e4e30268e4e30269e4e3026ae4e3026be4e3026ce4e3026de4e3026ee4e3026fe4e30270e4e30271e4e30272e4e30273e4e30274e4e30275e4e30276e4e30277e4e30278e4e30279e4e3027ae4e3027be4e3027ce4e3027de4e3027ee4e3027fe4e30280e4e30281e4e30282e4e30283e4e30284e4e30285e4e30286e4e30287e4e30288e4e30289e4e3028ae4e3028be4e3028ce4e3028de4e3028ee4e3028fe4e30290e4e30291e4e30292e4e30293e4e30294e4e30295e4e30296e4e30297e4e30298e4e30299e4e3029ae4e3029be4e3029ce4e3029de4e3029ee4e3029fe4e302a0e4e302a1e4e302a2e4e302a3e4e302a4e4e302a5e4e302a6e4e302a7e4e302a8e4e302a9e4e302aae4e302abe4e302ace4e302ade4e302aee4e302afe4e302b0e4e302b1e4e302b2e4e302b3e4e302b4e4e302b5e4e302b6e4e302b7e4e302b8e4e302b9e4e302bae4e302bbe4e302bce4e302bde4e302bee4e302bfe4e302c0e4e302c1e4e302c2e4e302c3e4e302c4e4e302c5e4e302c6e4e302c7e4e302c8e4e302c9e4e302cae4e302cbe4e302cce4e302cde4e302cee4e302cfe4e302d0e4e302d1e4e302d2e4e302d3e4e302d4e4e302d5e4e302d6e4e302d7e4e302d8e4e302d9e4e302dae4e302dbe4e302dce4e302dde4e302dee4e302dfe4e302e0e4e302e1e4e302e2e4e302e3e4e302e4e4e302e5e4e302e6e4e302e7e4e302e8e4e302e9e4e302eae4e302ebe4e302ece4e302ede4e302eee4e302efe4e302f0e4e302f1e4e302f2e4e302f3e4e302f4e4e302f5e4e302f6e4e302f7e4e302f8e4e302f9e4e302fae4e302fbe4e302fce4e302fde4e302fee4e302ffe4e30300e4e30301e4e30302e4e30303e4e30304e4e30305e4e30306e4e30307e4e30308e4e30309e4e3030ae4e3030be4e3030ce4e3030de4e3030ee4e3030fe4e30310e4e30311e4e30312e4e30313e4e30314e4e30315e4e30316e4e30317e4e30318e4e30319e4e3031ae4e3031be4e3031ce4e3031de4e3031ee4e3031fe4e30320e4e30321e4e30322e4e30323e4e30324e4e30325e4e30326e4e30327e4e30328e4e30329e4e3032ae4e3032be4e3032ce4e3032de4e3032ee4e3032fe4e30330e4e30331e4e30332e4e30333e4e30334e4e30335e4e30336e4e30337e4e30338e4e30339e4e3033ae4e3033be4e3033ce4e3033de4e3033ee4e3033fe4e30340e4e30341e4e30342e4e30343e4e30344e4e30345e4e30346e4e30347e4e30348e4e30349e4e3034ae4e3034be4e3034ce4e3034de4e3034ee4e3034fe4e30350e4e30351e4e30352e4e30353e4e30354e4e30355e4e30356e4e30357e4e30358e4e30359e4e3035ae4e3035be4e3035ce4e3035de4e3035ee4e3035fe4e30360e4e30361e4e30362e4e30363e4e30364e4e30365e4e30366e4e30367e4e30368e4e30369e4e3036ae4e3036be4e3036ce4e3036de4e3036ee4e3036fe4e30370e4e30371e4e30372e4e30373e4e30374e4e30375e4e30376e4e30377e4e30378e4e30379e4e3037ae4e3037be4e3037ce4e3037de4e3037ee4e3037fe4e30380e4e30381e4e30382e4e30383e4e30384e4e30385e4e30386e4e30387e4e30388e4e30389e4e3038ae4e3038be4e3038ce4e3038de4e3038ee4e3038fe4e30390e4e30391e4e30392e4e30393e4e30394e4e30395e4e30396e4e30397e4e30398e4e30399e4e3039ae4e3039be4e3039ce4e3039de4e3039ee4e3039fe4e303a0e4e303a1e4e303a2e4e303a3e4e303a4e4e303a5e4e303a6e4e303a7e4e303a8e4e303a9e4e303aae4e303abe4e303ace4e303ade4e303aee4e303afe4e303b0e4e303b1e4e303b2e4e303b3e4e303b4e4e303b5e4e303b6e4e303b7e4e303b8e4e303b9e4e303bae4e303bbe4e303bce4e303bde4e303bee4e303bfe4e303c0e4e303c1e4e303c2e4e303c3e4e303c4e4e303c5e4e303c6e4e303c7e4e303c8e4e303c9e4e303cae4e303cbe4e303cce4e303cde4e303cee4e303cfe4e303d0e4e303d1e4e303d2e4e303d3e4e303d4e4e303d5e4e303d6e4e303d7e4e303d8e4e303d9e4e303dae4e303dbe4e303dce4e303dde4e303dee4e303dfe4e303e0e4e303e1e4e303e2e4e303e3e4e303e4e4e303e5e4e303e6e4e303e7e4e303e8e4e303e9e4e303eae4e303ebe4e303ece4e303ede4e303eee4e303efe4e303f0e4e303f1e4e303f2e4e303f3e4e303f4e4e303f5e4e303f6e4e303f7e4e303f8e4e303f9e4e303fae4e303fbe4e303fce4e303fde4e303fee4e303ffe4e4", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_7" : { + "code" : "0xef000101100002040000040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400040004000400010400010000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e3000100e30002e4e30003e4e30004e4e30005e4e30006e4e30007e4e30008e4e30009e4e3000ae4e3000be4e3000ce4e3000de4e3000ee4e3000fe4e30010e4e30011e4e30012e4e30013e4e30014e4e30015e4e30016e4e30017e4e30018e4e30019e4e3001ae4e3001be4e3001ce4e3001de4e3001ee4e3001fe4e30020e4e30021e4e30022e4e30023e4e30024e4e30025e4e30026e4e30027e4e30028e4e30029e4e3002ae4e3002be4e3002ce4e3002de4e3002ee4e3002fe4e30030e4e30031e4e30032e4e30033e4e30034e4e30035e4e30036e4e30037e4e30038e4e30039e4e3003ae4e3003be4e3003ce4e3003de4e3003ee4e3003fe4e30040e4e30041e4e30042e4e30043e4e30044e4e30045e4e30046e4e30047e4e30048e4e30049e4e3004ae4e3004be4e3004ce4e3004de4e3004ee4e3004fe4e30050e4e30051e4e30052e4e30053e4e30054e4e30055e4e30056e4e30057e4e30058e4e30059e4e3005ae4e3005be4e3005ce4e3005de4e3005ee4e3005fe4e30060e4e30061e4e30062e4e30063e4e30064e4e30065e4e30066e4e30067e4e30068e4e30069e4e3006ae4e3006be4e3006ce4e3006de4e3006ee4e3006fe4e30070e4e30071e4e30072e4e30073e4e30074e4e30075e4e30076e4e30077e4e30078e4e30079e4e3007ae4e3007be4e3007ce4e3007de4e3007ee4e3007fe4e30080e4e30081e4e30082e4e30083e4e30084e4e30085e4e30086e4e30087e4e30088e4e30089e4e3008ae4e3008be4e3008ce4e3008de4e3008ee4e3008fe4e30090e4e30091e4e30092e4e30093e4e30094e4e30095e4e30096e4e30097e4e30098e4e30099e4e3009ae4e3009be4e3009ce4e3009de4e3009ee4e3009fe4e300a0e4e300a1e4e300a2e4e300a3e4e300a4e4e300a5e4e300a6e4e300a7e4e300a8e4e300a9e4e300aae4e300abe4e300ace4e300ade4e300aee4e300afe4e300b0e4e300b1e4e300b2e4e300b3e4e300b4e4e300b5e4e300b6e4e300b7e4e300b8e4e300b9e4e300bae4e300bbe4e300bce4e300bde4e300bee4e300bfe4e300c0e4e300c1e4e300c2e4e300c3e4e300c4e4e300c5e4e300c6e4e300c7e4e300c8e4e300c9e4e300cae4e300cbe4e300cce4e300cde4e300cee4e300cfe4e300d0e4e300d1e4e300d2e4e300d3e4e300d4e4e300d5e4e300d6e4e300d7e4e300d8e4e300d9e4e300dae4e300dbe4e300dce4e300dde4e300dee4e300dfe4e300e0e4e300e1e4e300e2e4e300e3e4e300e4e4e300e5e4e300e6e4e300e7e4e300e8e4e300e9e4e300eae4e300ebe4e300ece4e300ede4e300eee4e300efe4e300f0e4e300f1e4e300f2e4e300f3e4e300f4e4e300f5e4e300f6e4e300f7e4e300f8e4e300f9e4e300fae4e300fbe4e300fce4e300fde4e300fee4e300ffe4e30100e4e30101e4e30102e4e30103e4e30104e4e30105e4e30106e4e30107e4e30108e4e30109e4e3010ae4e3010be4e3010ce4e3010de4e3010ee4e3010fe4e30110e4e30111e4e30112e4e30113e4e30114e4e30115e4e30116e4e30117e4e30118e4e30119e4e3011ae4e3011be4e3011ce4e3011de4e3011ee4e3011fe4e30120e4e30121e4e30122e4e30123e4e30124e4e30125e4e30126e4e30127e4e30128e4e30129e4e3012ae4e3012be4e3012ce4e3012de4e3012ee4e3012fe4e30130e4e30131e4e30132e4e30133e4e30134e4e30135e4e30136e4e30137e4e30138e4e30139e4e3013ae4e3013be4e3013ce4e3013de4e3013ee4e3013fe4e30140e4e30141e4e30142e4e30143e4e30144e4e30145e4e30146e4e30147e4e30148e4e30149e4e3014ae4e3014be4e3014ce4e3014de4e3014ee4e3014fe4e30150e4e30151e4e30152e4e30153e4e30154e4e30155e4e30156e4e30157e4e30158e4e30159e4e3015ae4e3015be4e3015ce4e3015de4e3015ee4e3015fe4e30160e4e30161e4e30162e4e30163e4e30164e4e30165e4e30166e4e30167e4e30168e4e30169e4e3016ae4e3016be4e3016ce4e3016de4e3016ee4e3016fe4e30170e4e30171e4e30172e4e30173e4e30174e4e30175e4e30176e4e30177e4e30178e4e30179e4e3017ae4e3017be4e3017ce4e3017de4e3017ee4e3017fe4e30180e4e30181e4e30182e4e30183e4e30184e4e30185e4e30186e4e30187e4e30188e4e30189e4e3018ae4e3018be4e3018ce4e3018de4e3018ee4e3018fe4e30190e4e30191e4e30192e4e30193e4e30194e4e30195e4e30196e4e30197e4e30198e4e30199e4e3019ae4e3019be4e3019ce4e3019de4e3019ee4e3019fe4e301a0e4e301a1e4e301a2e4e301a3e4e301a4e4e301a5e4e301a6e4e301a7e4e301a8e4e301a9e4e301aae4e301abe4e301ace4e301ade4e301aee4e301afe4e301b0e4e301b1e4e301b2e4e301b3e4e301b4e4e301b5e4e301b6e4e301b7e4e301b8e4e301b9e4e301bae4e301bbe4e301bce4e301bde4e301bee4e301bfe4e301c0e4e301c1e4e301c2e4e301c3e4e301c4e4e301c5e4e301c6e4e301c7e4e301c8e4e301c9e4e301cae4e301cbe4e301cce4e301cde4e301cee4e301cfe4e301d0e4e301d1e4e301d2e4e301d3e4e301d4e4e301d5e4e301d6e4e301d7e4e301d8e4e301d9e4e301dae4e301dbe4e301dce4e301dde4e301dee4e301dfe4e301e0e4e301e1e4e301e2e4e301e3e4e301e4e4e301e5e4e301e6e4e301e7e4e301e8e4e301e9e4e301eae4e301ebe4e301ece4e301ede4e301eee4e301efe4e301f0e4e301f1e4e301f2e4e301f3e4e301f4e4e301f5e4e301f6e4e301f7e4e301f8e4e301f9e4e301fae4e301fbe4e301fce4e301fde4e301fee4e301ffe4e30200e4e30201e4e30202e4e30203e4e30204e4e30205e4e30206e4e30207e4e30208e4e30209e4e3020ae4e3020be4e3020ce4e3020de4e3020ee4e3020fe4e30210e4e30211e4e30212e4e30213e4e30214e4e30215e4e30216e4e30217e4e30218e4e30219e4e3021ae4e3021be4e3021ce4e3021de4e3021ee4e3021fe4e30220e4e30221e4e30222e4e30223e4e30224e4e30225e4e30226e4e30227e4e30228e4e30229e4e3022ae4e3022be4e3022ce4e3022de4e3022ee4e3022fe4e30230e4e30231e4e30232e4e30233e4e30234e4e30235e4e30236e4e30237e4e30238e4e30239e4e3023ae4e3023be4e3023ce4e3023de4e3023ee4e3023fe4e30240e4e30241e4e30242e4e30243e4e30244e4e30245e4e30246e4e30247e4e30248e4e30249e4e3024ae4e3024be4e3024ce4e3024de4e3024ee4e3024fe4e30250e4e30251e4e30252e4e30253e4e30254e4e30255e4e30256e4e30257e4e30258e4e30259e4e3025ae4e3025be4e3025ce4e3025de4e3025ee4e3025fe4e30260e4e30261e4e30262e4e30263e4e30264e4e30265e4e30266e4e30267e4e30268e4e30269e4e3026ae4e3026be4e3026ce4e3026de4e3026ee4e3026fe4e30270e4e30271e4e30272e4e30273e4e30274e4e30275e4e30276e4e30277e4e30278e4e30279e4e3027ae4e3027be4e3027ce4e3027de4e3027ee4e3027fe4e30280e4e30281e4e30282e4e30283e4e30284e4e30285e4e30286e4e30287e4e30288e4e30289e4e3028ae4e3028be4e3028ce4e3028de4e3028ee4e3028fe4e30290e4e30291e4e30292e4e30293e4e30294e4e30295e4e30296e4e30297e4e30298e4e30299e4e3029ae4e3029be4e3029ce4e3029de4e3029ee4e3029fe4e302a0e4e302a1e4e302a2e4e302a3e4e302a4e4e302a5e4e302a6e4e302a7e4e302a8e4e302a9e4e302aae4e302abe4e302ace4e302ade4e302aee4e302afe4e302b0e4e302b1e4e302b2e4e302b3e4e302b4e4e302b5e4e302b6e4e302b7e4e302b8e4e302b9e4e302bae4e302bbe4e302bce4e302bde4e302bee4e302bfe4e302c0e4e302c1e4e302c2e4e302c3e4e302c4e4e302c5e4e302c6e4e302c7e4e302c8e4e302c9e4e302cae4e302cbe4e302cce4e302cde4e302cee4e302cfe4e302d0e4e302d1e4e302d2e4e302d3e4e302d4e4e302d5e4e302d6e4e302d7e4e302d8e4e302d9e4e302dae4e302dbe4e302dce4e302dde4e302dee4e302dfe4e302e0e4e302e1e4e302e2e4e302e3e4e302e4e4e302e5e4e302e6e4e302e7e4e302e8e4e302e9e4e302eae4e302ebe4e302ece4e302ede4e302eee4e302efe4e302f0e4e302f1e4e302f2e4e302f3e4e302f4e4e302f5e4e302f6e4e302f7e4e302f8e4e302f9e4e302fae4e302fbe4e302fce4e302fde4e302fee4e302ffe4e30300e4e30301e4e30302e4e30303e4e30304e4e30305e4e30306e4e30307e4e30308e4e30309e4e3030ae4e3030be4e3030ce4e3030de4e3030ee4e3030fe4e30310e4e30311e4e30312e4e30313e4e30314e4e30315e4e30316e4e30317e4e30318e4e30319e4e3031ae4e3031be4e3031ce4e3031de4e3031ee4e3031fe4e30320e4e30321e4e30322e4e30323e4e30324e4e30325e4e30326e4e30327e4e30328e4e30329e4e3032ae4e3032be4e3032ce4e3032de4e3032ee4e3032fe4e30330e4e30331e4e30332e4e30333e4e30334e4e30335e4e30336e4e30337e4e30338e4e30339e4e3033ae4e3033be4e3033ce4e3033de4e3033ee4e3033fe4e30340e4e30341e4e30342e4e30343e4e30344e4e30345e4e30346e4e30347e4e30348e4e30349e4e3034ae4e3034be4e3034ce4e3034de4e3034ee4e3034fe4e30350e4e30351e4e30352e4e30353e4e30354e4e30355e4e30356e4e30357e4e30358e4e30359e4e3035ae4e3035be4e3035ce4e3035de4e3035ee4e3035fe4e30360e4e30361e4e30362e4e30363e4e30364e4e30365e4e30366e4e30367e4e30368e4e30369e4e3036ae4e3036be4e3036ce4e3036de4e3036ee4e3036fe4e30370e4e30371e4e30372e4e30373e4e30374e4e30375e4e30376e4e30377e4e30378e4e30379e4e3037ae4e3037be4e3037ce4e3037de4e3037ee4e3037fe4e30380e4e30381e4e30382e4e30383e4e30384e4e30385e4e30386e4e30387e4e30388e4e30389e4e3038ae4e3038be4e3038ce4e3038de4e3038ee4e3038fe4e30390e4e30391e4e30392e4e30393e4e30394e4e30395e4e30396e4e30397e4e30398e4e30399e4e3039ae4e3039be4e3039ce4e3039de4e3039ee4e3039fe4e303a0e4e303a1e4e303a2e4e303a3e4e303a4e4e303a5e4e303a6e4e303a7e4e303a8e4e303a9e4e303aae4e303abe4e303ace4e303ade4e303aee4e303afe4e303b0e4e303b1e4e303b2e4e303b3e4e303b4e4e303b5e4e303b6e4e303b7e4e303b8e4e303b9e4e303bae4e303bbe4e303bce4e303bde4e303bee4e303bfe4e303c0e4e303c1e4e303c2e4e303c3e4e303c4e4e303c5e4e303c6e4e303c7e4e303c8e4e303c9e4e303cae4e303cbe4e303cce4e303cde4e303cee4e303cfe4e303d0e4e303d1e4e303d2e4e303d3e4e303d4e4e303d5e4e303d6e4e303d7e4e303d8e4e303d9e4e303dae4e303dbe4e303dce4e303dde4e303dee4e303dfe4e303e0e4e303e1e4e303e2e4e303e3e4e303e4e4e303e5e4e303e6e4e303e7e4e303e8e4e303e9e4e303eae4e303ebe4e303ece4e303ede4e303eee4e303efe4e303f0e4e303f1e4e303f2e4e303f3e4e303f4e4e303f5e4e303f6e4e303f7e4e303f8e4e303f9e4e303fae4e303fbe4e303fce4e303fde4e303fee4e303ffe4e4da", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_8" : { + "code" : "0xef000102000100010400000000800000fe", + "results" : { + "Prague" : { + "exception" : "EOF_TypeSectionMissing", + "result" : false + } + } + }, + "validInvalid_9" : { + "code" : "0xef00010100040100040400000000800000fe", + "results" : { + "Prague" : { + "exception" : "EOF_CodeSectionMissing", + "result" : false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/EIP5450/validInvalid.json b/crates/interpreter/tests/EOFTests/EIP5450/validInvalid.json new file mode 100644 index 00000000..684a03c8 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/EIP5450/validInvalid.json @@ -0,0 +1,1730 @@ +{ + "validInvalid" : { + "_info" : { + "comment" : "Test various examples to see if they are valid or invalid.\nImplements\n EOF1V5450_0001 (Valid) Code with branches having the same stack height - Data index: 0\n EOF1V5450_0002 (Valid) Jump table - Data index: 1\n EOF1V5450_0003 (Valid) Infinite loop - Data index: 2\n EOF1V5450_0004 (Valid) Infinite loop using RJUMPV - Data index: 3\n EOF1V5450_0005 (Valid) CALLF branches with the same total of outputs - Data index: 4\n EOF1V5450_0006 (Valid) CALLF inputs - Data index: 5\n EOF1V5450_0007 (Valid) Validate input for ADD opcode - Data index: 6\n EOF1V5450_0008 (Valid) Validate input for MUL opcode - Data index: 7\n EOF1V5450_0009 (Valid) Validate input for SUB opcode - Data index: 8\n EOF1V5450_0010 (Valid) Validate input for DIV opcode - Data index: 9\n EOF1V5450_0011 (Valid) Validate input for SDIV opcode - Data index: 10\n EOF1V5450_0012 (Valid) Validate input for MOD opcode - Data index: 11\n EOF1V5450_0013 (Valid) Validate input for SMOD opcode - Data index: 12\n EOF1V5450_0014 (Valid) Validate input for ADDMOD opcode - Data index: 13\n EOF1V5450_0015 (Valid) Validate input for MULMOD opcode - Data index: 14\n EOF1V5450_0016 (Valid) Validate input for EXP opcode - Data index: 15\n EOF1V5450_0017 (Valid) Validate input for SIGNEXTEND opcode - Data index: 16\n EOF1V5450_0018 (Valid) Validate input for LT opcode - Data index: 17\n EOF1V5450_0019 (Valid) Validate input for GT opcode - Data index: 18\n EOF1V5450_0020 (Valid) Validate input for SLT opcode - Data index: 19\n EOF1V5450_0021 (Valid) Validate input for SGT opcode - Data index: 20\n EOF1V5450_0022 (Valid) Validate input for EQ opcode - Data index: 21\n EOF1V5450_0023 (Valid) Validate input for ISZERO opcode - Data index: 22\n EOF1V5450_0024 (Valid) Validate input for AND opcode - Data index: 23\n EOF1V5450_0025 (Valid) Validate input for OR opcode - Data index: 24\n EOF1V5450_0026 (Valid) Validate input for XOR opcode - Data index: 25\n EOF1V5450_0027 (Valid) Validate input for NOT opcode - Data index: 26\n EOF1V5450_0028 (Valid) Validate input for BYTE opcode - Data index: 27\n EOF1V5450_0029 (Valid) Validate input for SHL opcode - Data index: 28\n EOF1V5450_0030 (Valid) Validate input for SHR opcode - Data index: 29\n EOF1V5450_0031 (Valid) Validate input for SAR opcode - Data index: 30\n EOF1V5450_0032 (Valid) Validate input for SHA3 opcode - Data index: 31\n EOF1V5450_0033 (Valid) Validate input for BALANCE opcode - Data index: 32\n EOF1V5450_0034 (Valid) Validate input for CALLDATALOAD opcode - Data index: 33\n EOF1V5450_0035 (Valid) Validate input for CALLDATACOPY opcode - Data index: 34\n EOF1V5450_0036 (Valid) Validate input for CODECOPY opcode - Data index: 35\n EOF1V5450_0037 (Valid) Validate input for EXTCODESIZE opcode - Data index: 36\n EOF1V5450_0038 (Valid) Validate input for EXTCODECOPY opcode - Data index: 37\n EOF1V5450_0039 (Valid) Validate input for RETURNDATACOPY opcode - Data index: 38\n EOF1V5450_0040 (Valid) Validate input for EXTCODEHASH opcode - Data index: 39\n EOF1V5450_0041 (Valid) Validate input for BLOCKHASH opcode - Data index: 40\n EOF1V5450_0042 (Valid) Validate input for BLOBHASH opcode - Data index: 41\n EOF1V5450_0043 (Valid) Validate input for POP opcode - Data index: 42\n EOF1V5450_0044 (Valid) Validate input for MLOAD opcode - Data index: 43\n EOF1V5450_0045 (Valid) Validate input for MSTORE opcode - Data index: 44\n EOF1V5450_0046 (Valid) Validate input for MSTORE8 opcode - Data index: 45\n EOF1V5450_0047 (Valid) Validate input for SLOAD opcode - Data index: 46\n EOF1V5450_0048 (Valid) Validate input for SSTORE opcode - Data index: 47\n EOF1V5450_0049 (Valid) Validate input for MCOPY opcode - Data index: 48\n EOF1V5450_0050 (Valid) Validate input for DUP1 opcode - Data index: 49\n EOF1V5450_0051 (Valid) Validate input for DUP2 opcode - Data index: 50\n EOF1V5450_0052 (Valid) Validate input for DUP3 opcode - Data index: 51\n EOF1V5450_0053 (Valid) Validate input for DUP4 opcode - Data index: 52\n EOF1V5450_0054 (Valid) Validate input for DUP5 opcode - Data index: 53\n EOF1V5450_0055 (Valid) Validate input for DUP6 opcode - Data index: 54\n EOF1V5450_0056 (Valid) Validate input for DUP7 opcode - Data index: 55\n EOF1V5450_0057 (Valid) Validate input for DUP8 opcode - Data index: 56\n EOF1V5450_0058 (Valid) Validate input for DUP9 opcode - Data index: 57\n EOF1V5450_0059 (Valid) Validate input for DUP10 opcode - Data index: 58\n EOF1V5450_0060 (Valid) Validate input for DUP11 opcode - Data index: 59\n EOF1V5450_0061 (Valid) Validate input for DUP12 opcode - Data index: 60\n EOF1V5450_0062 (Valid) Validate input for DUP13 opcode - Data index: 61\n EOF1V5450_0063 (Valid) Validate input for DUP14 opcode - Data index: 62\n EOF1V5450_0064 (Valid) Validate input for DUP15 opcode - Data index: 63\n EOF1V5450_0065 (Valid) Validate input for DUP16 opcode - Data index: 64\n EOF1V5450_0066 (Valid) Validate input for SWAP1 opcode - Data index: 65\n EOF1V5450_0067 (Valid) Validate input for SWAP2 opcode - Data index: 66\n EOF1V5450_0068 (Valid) Validate input for SWAP3 opcode - Data index: 67\n EOF1V5450_0069 (Valid) Validate input for SWAP4 opcode - Data index: 68\n EOF1V5450_0070 (Valid) Validate input for SWAP5 opcode - Data index: 69\n EOF1V5450_0071 (Valid) Validate input for SWAP6 opcode - Data index: 70\n EOF1V5450_0072 (Valid) Validate input for SWAP7 opcode - Data index: 71\n EOF1V5450_0073 (Valid) Validate input for SWAP8 opcode - Data index: 72\n EOF1V5450_0074 (Valid) Validate input for SWAP9 opcode - Data index: 73\n EOF1V5450_0075 (Valid) Validate input for SWAP10 opcode - Data index: 74\n EOF1V5450_0076 (Valid) Validate input for SWAP11 opcode - Data index: 75\n EOF1V5450_0077 (Valid) Validate input for SWAP12 opcode - Data index: 76\n EOF1V5450_0078 (Valid) Validate input for SWAP13 opcode - Data index: 77\n EOF1V5450_0079 (Valid) Validate input for SWAP14 opcode - Data index: 78\n EOF1V5450_0080 (Valid) Validate input for SWAP15 opcode - Data index: 79\n EOF1V5450_0081 (Valid) Validate input for SWAP16 opcode - Data index: 80\n EOF1V5450_0082 (Valid) Validate input for LOG0 opcode - Data index: 81\n EOF1V5450_0083 (Valid) Validate input for LOG1 opcode - Data index: 82\n EOF1V5450_0084 (Valid) Validate input for LOG2 opcode - Data index: 83\n EOF1V5450_0085 (Valid) Validate input for LOG3 opcode - Data index: 84\n EOF1V5450_0086 (Valid) Validate input for LOG4 opcode - Data index: 85\n EOF1V5450_0087 (Valid) Validate input for CALL opcode - Data index: 86\n EOF1V5450_0088 (Valid) Validate input for RETURN opcode - Data index: 87\n EOF1V5450_0089 (Valid) Validate input for DELEGATECALL opcode - Data index: 88\n EOF1V5450_0090 (Valid) Validate input for STATICCALL opcode - Data index: 89\n EOF1V5450_0091 (Valid) Validate input for REVERT opcode - Data index: 90\n EOF1V5450_0092 (Valid) Containing terminating opcode RETURN at the end - Data index: 91\n EOF1V5450_0093 (Valid) Containing terminating opcode REVERT at the end - Data index: 92\n EOF1V5450_0094 (Valid) Loop ending with unconditional RJUMP (a) - Data index: 93\n EOF1V5450_0095 (Valid) Loop ending with unconditional RJUMP (b) - Data index: 94\n EOF1V5450_0096 (Valid) Functions ending with RETF - Data index: 95\n EOF1V5450_0097 (Valid) Stack is not required to be empty on terminating instruction RETURN - Data index: 96\n EOF1V5450_0098 (Valid) Stack is not required to be empty on terminating instruction REVERT - Data index: 97\n EOF1V5450_0099 (Valid) RETF returning maximum number of outputs (127) - Data index: 98\n EOF1V5450_0100 (Valid) Calling function with enough stack items: Function 1 calls Function 2 with enough parameters - Data index: 99\n EOF1V5450_0101 (Valid) Stack height mismatch for different paths valid according to relaxed stack validation - Data index: 100\n EOF1V5450_0102 (Valid) Stack height mismatch for different paths valid according to relaxed stack validation - Data index: 101\n EOF1V5450_0103 (Valid) Calls returning different number of outputs valid according to relaxed stack validation - Data index: 102\n EOF1V5450_0104 (Valid) Jump table with different stack heights valid according to relaxed stack validation - Data index: 103\n EOF1I5450_0001 (Invalid) Pushing loop - Data index: 104\n EOF1I5450_0002 (Invalid) Popping loop - Data index: 105\n EOF1I5450_0003 (Invalid) Stack underflow for opcode ADD - Data index: 106\n EOF1I5450_0004 (Invalid) Stack underflow for opcode MUL - Data index: 107\n EOF1I5450_0005 (Invalid) Stack underflow for opcode SUB - Data index: 108\n EOF1I5450_0006 (Invalid) Stack underflow for opcode DIV - Data index: 109\n EOF1I5450_0007 (Invalid) Stack underflow for opcode SDIV - Data index: 110\n EOF1I5450_0008 (Invalid) Stack underflow for opcode MOD - Data index: 111\n EOF1I5450_0009 (Invalid) Stack underflow for opcode SMOD - Data index: 112\n EOF1I5450_0010 (Invalid) Stack underflow for opcode ADDMOD - Data index: 113\n EOF1I5450_0011 (Invalid) Stack underflow for opcode MULMOD - Data index: 114\n EOF1I5450_0012 (Invalid) Stack underflow for opcode EXP - Data index: 115\n EOF1I5450_0013 (Invalid) Stack underflow for opcode SIGNEXTEND - Data index: 116\n EOF1I5450_0014 (Invalid) Stack underflow for opcode LT - Data index: 117\n EOF1I5450_0015 (Invalid) Stack underflow for opcode GT - Data index: 118\n EOF1I5450_0016 (Invalid) Stack underflow for opcode SLT - Data index: 119\n EOF1I5450_0017 (Invalid) Stack underflow for opcode SGT - Data index: 120\n EOF1I5450_0018 (Invalid) Stack underflow for opcode EQ - Data index: 121\n EOF1I5450_0019 (Invalid) Stack underflow for opcode ISZERO - Data index: 122\n EOF1I5450_0020 (Invalid) Stack underflow for opcode AND - Data index: 123\n EOF1I5450_0021 (Invalid) Stack underflow for opcode OR - Data index: 124\n EOF1I5450_0022 (Invalid) Stack underflow for opcode XOR - Data index: 125\n EOF1I5450_0023 (Invalid) Stack underflow for opcode NOT - Data index: 126\n EOF1I5450_0024 (Invalid) Stack underflow for opcode BYTE - Data index: 127\n EOF1I5450_0025 (Invalid) Stack underflow for opcode SHL - Data index: 128\n EOF1I5450_0026 (Invalid) Stack underflow for opcode SHR - Data index: 129\n EOF1I5450_0027 (Invalid) Stack underflow for opcode SAR - Data index: 130\n EOF1I5450_0028 (Invalid) Stack underflow for opcode SHA3 - Data index: 131\n EOF1I5450_0029 (Invalid) Stack underflow for opcode BALANCE - Data index: 132\n EOF1I5450_0030 (Invalid) Stack underflow for opcode CALLDATALOAD - Data index: 133\n EOF1I5450_0031 (Invalid) Stack underflow for opcode CALLDATACOPY - Data index: 134\n EOF1I5450_0032 (Invalid) Stack underflow for opcode CODECOPY - Data index: 135\n EOF1I5450_0033 (Invalid) Stack underflow for opcode EXTCODESIZE - Data index: 136\n EOF1I5450_0034 (Invalid) Stack underflow for opcode EXTCODECOPY - Data index: 137\n EOF1I5450_0035 (Invalid) Stack underflow for opcode RETURNDATACOPY - Data index: 138\n EOF1I5450_0036 (Invalid) Stack underflow for opcode EXTCODEHASH - Data index: 139\n EOF1I5450_0037 (Invalid) Stack underflow for opcode BLOCKHASH - Data index: 140\n EOF1I5450_0038 (Invalid) Stack underflow for opcode BLOBHASH - Data index: 141\n EOF1I5450_0039 (Invalid) Stack underflow for opcode POP - Data index: 142\n EOF1I5450_0040 (Invalid) Stack underflow for opcode MLOAD - Data index: 143\n EOF1I5450_0041 (Invalid) Stack underflow for opcode MSTORE - Data index: 144\n EOF1I5450_0042 (Invalid) Stack underflow for opcode MSTORE8 - Data index: 145\n EOF1I5450_0043 (Invalid) Stack underflow for opcode SLOAD - Data index: 146\n EOF1I5450_0044 (Invalid) Stack underflow for opcode SSTORE - Data index: 147\n EOF1I5450_0045 (Invalid) Stack underflow for opcode MCOPY - Data index: 148\n EOF1I5450_0046 (Invalid) Stack underflow for opcode DUP1 - Data index: 149\n EOF1I5450_0047 (Invalid) Stack underflow for opcode DUP2 - Data index: 150\n EOF1I5450_0048 (Invalid) Stack underflow for opcode DUP3 - Data index: 151\n EOF1I5450_0049 (Invalid) Stack underflow for opcode DUP4 - Data index: 152\n EOF1I5450_0050 (Invalid) Stack underflow for opcode DUP5 - Data index: 153\n EOF1I5450_0051 (Invalid) Stack underflow for opcode DUP6 - Data index: 154\n EOF1I5450_0052 (Invalid) Stack underflow for opcode DUP7 - Data index: 155\n EOF1I5450_0053 (Invalid) Stack underflow for opcode DUP8 - Data index: 156\n EOF1I5450_0054 (Invalid) Stack underflow for opcode DUP9 - Data index: 157\n EOF1I5450_0055 (Invalid) Stack underflow for opcode DUP10 - Data index: 158\n EOF1I5450_0056 (Invalid) Stack underflow for opcode DUP11 - Data index: 159\n EOF1I5450_0057 (Invalid) Stack underflow for opcode DUP12 - Data index: 160\n EOF1I5450_0058 (Invalid) Stack underflow for opcode DUP13 - Data index: 161\n EOF1I5450_0059 (Invalid) Stack underflow for opcode DUP14 - Data index: 162\n EOF1I5450_0060 (Invalid) Stack underflow for opcode DUP15 - Data index: 163\n EOF1I5450_0061 (Invalid) Stack underflow for opcode DUP16 - Data index: 164\n EOF1I5450_0062 (Invalid) Stack underflow for opcode SWAP1 - Data index: 165\n EOF1I5450_0063 (Invalid) Stack underflow for opcode SWAP2 - Data index: 166\n EOF1I5450_0064 (Invalid) Stack underflow for opcode SWAP3 - Data index: 167\n EOF1I5450_0065 (Invalid) Stack underflow for opcode SWAP4 - Data index: 168\n EOF1I5450_0066 (Invalid) Stack underflow for opcode SWAP5 - Data index: 169\n EOF1I5450_0067 (Invalid) Stack underflow for opcode SWAP6 - Data index: 170\n EOF1I5450_0068 (Invalid) Stack underflow for opcode SWAP7 - Data index: 171\n EOF1I5450_0069 (Invalid) Stack underflow for opcode SWAP8 - Data index: 172\n EOF1I5450_0070 (Invalid) Stack underflow for opcode SWAP9 - Data index: 173\n EOF1I5450_0071 (Invalid) Stack underflow for opcode SWAP10 - Data index: 174\n EOF1I5450_0072 (Invalid) Stack underflow for opcode SWAP11 - Data index: 175\n EOF1I5450_0073 (Invalid) Stack underflow for opcode SWAP12 - Data index: 176\n EOF1I5450_0074 (Invalid) Stack underflow for opcode SWAP13 - Data index: 177\n EOF1I5450_0075 (Invalid) Stack underflow for opcode SWAP14 - Data index: 178\n EOF1I5450_0076 (Invalid) Stack underflow for opcode SWAP15 - Data index: 179\n EOF1I5450_0077 (Invalid) Stack underflow for opcode SWAP16 - Data index: 180\n EOF1I5450_0078 (Invalid) Stack underflow for opcode LOG0 - Data index: 181\n EOF1I5450_0079 (Invalid) Stack underflow for opcode LOG1 - Data index: 182\n EOF1I5450_0080 (Invalid) Stack underflow for opcode LOG2 - Data index: 183\n EOF1I5450_0081 (Invalid) Stack underflow for opcode LOG3 - Data index: 184\n EOF1I5450_0082 (Invalid) Stack underflow for opcode LOG4 - Data index: 185\n EOF1I5450_0083 (Invalid) Stack underflow for opcode CALL - Data index: 186\n EOF1I5450_0084 (Invalid) Stack underflow for opcode RETURN - Data index: 187\n EOF1I5450_0085 (Invalid) Stack underflow for opcode DELEGATECALL - Data index: 188\n EOF1I5450_0086 (Invalid) Stack underflow for opcode STATICCALL - Data index: 189\n EOF1I5450_0087 (Invalid) Stack underflow for opcode REVERT - Data index: 190\n EOF1I5450_0088 (Invalid) Calling function without enough stack items: Function 0 calls Function 1 without enough parameters - Data index: 191\n EOF1I5450_0089 (Invalid) Calling function without enough stack items: Function 0 calls Function 1 without enought parameters, Function 1 calls Function 2 without enough parameers - Data index: 192\n EOF1I5450_0090 (Invalid) Stack Overflow: Function pushing more than 1024 items to the stack - Data index: 193\n EOF1I5450_0091 (Invalid) Stack Overflow: Function 1 when called by Function 0 pushes more than 1024 items to the stack - Data index: 194\n EOF1I5450_0092 (Invalid) Function ending with non-terminating instruction (a) - Data index: 195\n EOF1I5450_0093 (Invalid) Function ending with non-terminating instruction (b) - Data index: 196\n EOF1I5450_0094 (Invalid) Function ending with non-terminating instruction (c) - Data index: 197\n EOF1I5450_0095 (Invalid) Function containing unreachable code after RETURN - Data index: 198\n EOF1I5450_0096 (Invalid) Function containing unreachable code after REVERT - Data index: 199\n EOF1I5450_0097 (Invalid) Unreachable code after RJUMP - Data index: 200\n EOF1I5450_0098 (Invalid) Unreachable code after infinite loop - Data index: 201\n", + "filling-rpc-server" : "evmone-t8n 0.12.0-dev+commit.14ba7529", + "filling-tool-version" : "retesteth-0.3.2-cancun+commit.9d793abd.Linux.g++", + "generatedTestHash" : "5fe8f95c5397e77caa07f7e5f6d2c78d06a72b1f77bf2af91e4a281eeb1ee612", + "lllcversion" : "Version: 0.5.14-develop.2022.4.6+commit.401d5358.Linux.g++", + "solidity" : "Version: 0.8.18-develop.2023.1.16+commit.469d6d4d.Linux.g++", + "source" : "src/EOFTestsFiller/EIP5450/validInvalidFiller.yml", + "sourceHash" : "10f981cd7e7564f42a8d3ab4dd1cf401a95e06d254c75b4903a189553c1e4ad4" + }, + "vectors" : { + "validInvalid_0" : { + "code" : "0xef0001010004020001001104000000008000026000e1000760016002e000046003600400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_1" : { + "code" : "0xef0001010004020001001b04000000008000026000e2010007000e60016002e0000b60036004e000046005600600", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_10" : { + "code" : "0xef0001010004020001000504000000008000026001800500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_100" : { + "code" : "0xef0001010004020001000a04000000008000026000e100026001600200", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_101" : { + "code" : "0xef0001010004020001000f04000000008000026000e100056001e000046002600300", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_102" : { + "code" : "0xef000101000c020003000f00030004040000000080000200010001000200026000e10006e30001e00003e30002006001e4600180e4", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_103" : { + "code" : "0xef0001010004020001001b04000000008000036000e2010005000c6001e0000d60026003e0000660036004600500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_104" : { + "code" : "0xef0001010004020001000504000000008000016000e0fffb", + "results" : { + "Prague" : { + "exception" : "EOF_ConflictingStackHeight", + "result" : false + } + } + }, + "validInvalid_105" : { + "code" : "0xef0001010004020001000804000000008000036000808050e0fffc", + "results" : { + "Prague" : { + "exception" : "EOF_ConflictingStackHeight", + "result" : false + } + } + }, + "validInvalid_106" : { + "code" : "0xef00010100040200010004040000000080000160010100", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_107" : { + "code" : "0xef00010100040200010004040000000080000160010200", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_108" : { + "code" : "0xef00010100040200010004040000000080000160010300", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_109" : { + "code" : "0xef00010100040200010004040000000080000160010400", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_11" : { + "code" : "0xef0001010004020001000504000000008000026001800600", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_110" : { + "code" : "0xef00010100040200010004040000000080000160010500", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_111" : { + "code" : "0xef00010100040200010004040000000080000160010600", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_112" : { + "code" : "0xef00010100040200010004040000000080000160010700", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_113" : { + "code" : "0xef000101000402000100060400000000800002600160010800", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_114" : { + "code" : "0xef000101000402000100060400000000800002600160010900", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_115" : { + "code" : "0xef00010100040200010004040000000080000160010a00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_116" : { + "code" : "0xef00010100040200010004040000000080000160010b00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_117" : { + "code" : "0xef00010100040200010004040000000080000160011000", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_118" : { + "code" : "0xef00010100040200010004040000000080000160011100", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_119" : { + "code" : "0xef00010100040200010004040000000080000160011200", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_12" : { + "code" : "0xef0001010004020001000504000000008000026001800700", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_120" : { + "code" : "0xef00010100040200010004040000000080000160011300", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_121" : { + "code" : "0xef00010100040200010004040000000080000160011400", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_122" : { + "code" : "0xef0001010004020001000204000000008000001500", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_123" : { + "code" : "0xef00010100040200010004040000000080000160011600", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_124" : { + "code" : "0xef00010100040200010004040000000080000160011700", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_125" : { + "code" : "0xef00010100040200010004040000000080000160011800", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_126" : { + "code" : "0xef0001010004020001000204000000008000001900", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_127" : { + "code" : "0xef00010100040200010004040000000080000160011a00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_128" : { + "code" : "0xef00010100040200010004040000000080000160011b00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_129" : { + "code" : "0xef00010100040200010004040000000080000160011c00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_13" : { + "code" : "0xef000101000402000100060400000000800003600180800800", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_130" : { + "code" : "0xef00010100040200010004040000000080000160011d00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_131" : { + "code" : "0xef00010100040200010004040000000080000160012000", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_132" : { + "code" : "0xef0001010004020001000204000000008000003100", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_133" : { + "code" : "0xef0001010004020001000204000000008000003500", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_134" : { + "code" : "0xef000101000402000100060400000000800002600160013700", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_135" : { + "code" : "0xef000101000402000100060400000000800002600160013900", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_136" : { + "code" : "0xef0001010004020001000204000000008000003b00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_137" : { + "code" : "0xef0001010004020001000804000000008000036001600160013c00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_138" : { + "code" : "0xef000101000402000100060400000000800002600160013e00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_139" : { + "code" : "0xef0001010004020001000204000000008000003f00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_14" : { + "code" : "0xef000101000402000100060400000000800003600180800900", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_140" : { + "code" : "0xef0001010004020001000204000000008000004000", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_141" : { + "code" : "0xef0001010004020001000204000000008000004900", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_142" : { + "code" : "0xef0001010004020001000204000000008000005000", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_143" : { + "code" : "0xef0001010004020001000204000000008000005100", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_144" : { + "code" : "0xef00010100040200010004040000000080000160015200", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_145" : { + "code" : "0xef00010100040200010004040000000080000160015300", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_146" : { + "code" : "0xef0001010004020001000204000000008000005400", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_147" : { + "code" : "0xef00010100040200010004040000000080000160015500", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_148" : { + "code" : "0xef000101000402000100060400000000800002600160015e00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_149" : { + "code" : "0xef0001010004020001000204000000008000018000", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_15" : { + "code" : "0xef0001010004020001000504000000008000026001800a00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_150" : { + "code" : "0xef00010100040200010004040000000080000260018100", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_151" : { + "code" : "0xef000101000402000100060400000000800003600160018200", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_152" : { + "code" : "0xef0001010004020001000804000000008000046001600160018300", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_153" : { + "code" : "0xef0001010004020001000a040000000080000560016001600160018400", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_154" : { + "code" : "0xef0001010004020001000c0400000000800006600160016001600160018500", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_155" : { + "code" : "0xef0001010004020001000e04000000008000076001600160016001600160018600", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_156" : { + "code" : "0xef00010100040200010010040000000080000860016001600160016001600160018700", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_157" : { + "code" : "0xef000101000402000100120400000000800009600160016001600160016001600160018800", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_158" : { + "code" : "0xef00010100040200010014040000000080000a6001600160016001600160016001600160018900", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_159" : { + "code" : "0xef00010100040200010016040000000080000b60016001600160016001600160016001600160018a00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_16" : { + "code" : "0xef0001010004020001000504000000008000026001800b00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_160" : { + "code" : "0xef00010100040200010018040000000080000c600160016001600160016001600160016001600160018b00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_161" : { + "code" : "0xef0001010004020001001a040000000080000d6001600160016001600160016001600160016001600160018c00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_162" : { + "code" : "0xef0001010004020001001c040000000080000e60016001600160016001600160016001600160016001600160018d00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_163" : { + "code" : "0xef0001010004020001001e040000000080000f600160016001600160016001600160016001600160016001600160018e00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_164" : { + "code" : "0xef0001010004020001002004000000008000106001600160016001600160016001600160016001600160016001600160018f00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_165" : { + "code" : "0xef00010100040200010004040000000080000160019000", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_166" : { + "code" : "0xef000101000402000100060400000000800002600160019100", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_167" : { + "code" : "0xef0001010004020001000804000000008000036001600160019200", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_168" : { + "code" : "0xef0001010004020001000a040000000080000460016001600160019300", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_169" : { + "code" : "0xef0001010004020001000c0400000000800005600160016001600160019400", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_17" : { + "code" : "0xef0001010004020001000504000000008000026001801000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_170" : { + "code" : "0xef0001010004020001000e04000000008000066001600160016001600160019500", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_171" : { + "code" : "0xef00010100040200010010040000000080000760016001600160016001600160019600", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_172" : { + "code" : "0xef000101000402000100120400000000800008600160016001600160016001600160019700", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_173" : { + "code" : "0xef0001010004020001001404000000008000096001600160016001600160016001600160019800", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_174" : { + "code" : "0xef00010100040200010016040000000080000a60016001600160016001600160016001600160019900", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_175" : { + "code" : "0xef00010100040200010018040000000080000b600160016001600160016001600160016001600160019a00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_176" : { + "code" : "0xef0001010004020001001a040000000080000c6001600160016001600160016001600160016001600160019b00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_177" : { + "code" : "0xef0001010004020001001c040000000080000d60016001600160016001600160016001600160016001600160019c00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_178" : { + "code" : "0xef0001010004020001001e040000000080000e600160016001600160016001600160016001600160016001600160019d00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_179" : { + "code" : "0xef00010100040200010020040000000080000f6001600160016001600160016001600160016001600160016001600160019e00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_18" : { + "code" : "0xef0001010004020001000504000000008000026001801100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_180" : { + "code" : "0xef00010100040200010022040000000080001060016001600160016001600160016001600160016001600160016001600160019f00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_181" : { + "code" : "0xef0001010004020001000404000000008000016001a000", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_182" : { + "code" : "0xef00010100040200010006040000000080000260016001a100", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_183" : { + "code" : "0xef000101000402000100080400000000800003600160016001a200", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_184" : { + "code" : "0xef0001010004020001000a04000000008000046001600160016001a300", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_185" : { + "code" : "0xef0001010004020001000c040000000080000560016001600160016001a400", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_186" : { + "code" : "0xef0001010004020001000e0400000000800006600160016001600160016001f100", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_187" : { + "code" : "0xef0001010004020001000304000000008000016001f3", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_188" : { + "code" : "0xef0001010004020001000c040000000080000560016001600160016001f400", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_189" : { + "code" : "0xef0001010004020001000c040000000080000560016001600160016001fa00", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_19" : { + "code" : "0xef0001010004020001000504000000008000026001801200", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_190" : { + "code" : "0xef0001010004020001000304000000008000016001fd", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_191" : { + "code" : "0xef000101000c02000300040007000304000000008000000100000302000002e3000100600080e30002e45050e4", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_192" : { + "code" : "0xef000101000c02000300040006000604000000008000000100000202800002e30001006000e30002e45050e30003e4", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_193" : { + "code" : "0xef0001010004020001080004000000008004006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000", + "results" : { + "Prague" : { + "exception" : "EOF_MaxStackHeightExceeded", + "result" : false + } + } + }, + "validInvalid_194" : { + "code" : "0xef000101000802000207fb000b040000000080040100050005600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000e3000160006000600060006000e4", + "results" : { + "Prague" : { + "exception" : "EOF_MaxStackHeightExceeded", + "result" : false + } + } + }, + "validInvalid_195" : { + "code" : "0xef0001010004020001000204000000008000016000", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidCodeTermination", + "result" : false + } + } + }, + "validInvalid_196" : { + "code" : "0xef0001010004020001000704000000008000016000e10001005b", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidCodeTermination", + "result" : false + } + } + }, + "validInvalid_197" : { + "code" : "0xef0001010004020001000b04000000008000016000e20100010002fe005b", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidCodeTermination", + "result" : false + } + } + }, + "validInvalid_198" : { + "code" : "0xef00010100040200010006040000000080000260006000f300", + "results" : { + "Prague" : { + "exception" : "EOF_UnreachableCode", + "result" : false + } + } + }, + "validInvalid_199" : { + "code" : "0xef00010100040200010006040000000080000260006000fd00", + "results" : { + "Prague" : { + "exception" : "EOF_UnreachableCode", + "result" : false + } + } + }, + "validInvalid_2" : { + "code" : "0xef000101000402000100090400000000800002600060015050e0fff7", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_20" : { + "code" : "0xef0001010004020001000504000000008000026001801300", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_200" : { + "code" : "0xef000101000402000100080400000000800001e000026000600000", + "results" : { + "Prague" : { + "exception" : "EOF_UnreachableCode", + "result" : false + } + } + }, + "validInvalid_201" : { + "code" : "0xef0001010004020001000c0400000000800001e000026000600050e0fffa00", + "results" : { + "Prague" : { + "exception" : "EOF_UnreachableCode", + "result" : false + } + } + }, + "validInvalid_21" : { + "code" : "0xef0001010004020001000504000000008000026001801400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_22" : { + "code" : "0xef00010100040200010004040000000080000160011500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_23" : { + "code" : "0xef0001010004020001000504000000008000026001801600", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_24" : { + "code" : "0xef0001010004020001000504000000008000026001801700", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_25" : { + "code" : "0xef0001010004020001000504000000008000026001801800", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_26" : { + "code" : "0xef00010100040200010004040000000080000160011900", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_27" : { + "code" : "0xef0001010004020001000504000000008000026001801a00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_28" : { + "code" : "0xef0001010004020001000504000000008000026001801b00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_29" : { + "code" : "0xef0001010004020001000504000000008000026001801c00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_3" : { + "code" : "0xef00010100040200010199040000000080000160c9e2c9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fe6800", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_30" : { + "code" : "0xef0001010004020001000504000000008000026001801d00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_31" : { + "code" : "0xef0001010004020001000504000000008000026001802000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_32" : { + "code" : "0xef00010100040200010004040000000080000160013100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_33" : { + "code" : "0xef00010100040200010004040000000080000160013500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_34" : { + "code" : "0xef000101000402000100060400000000800003600180803700", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_35" : { + "code" : "0xef000101000402000100060400000000800003600180803900", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_36" : { + "code" : "0xef00010100040200010004040000000080000160013b00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_37" : { + "code" : "0xef00010100040200010007040000000080000460018080803c00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_38" : { + "code" : "0xef000101000402000100060400000000800003600180803e00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_39" : { + "code" : "0xef00010100040200010004040000000080000160013f00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_4" : { + "code" : "0xef000101000c020003000f00020002040000000080000100010001000100016000e10006e30001e00003e300020030e438e4", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_40" : { + "code" : "0xef00010100040200010004040000000080000160014000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_41" : { + "code" : "0xef00010100040200010004040000000080000160014900", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_42" : { + "code" : "0xef00010100040200010004040000000080000160015000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_43" : { + "code" : "0xef00010100040200010004040000000080000160015100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_44" : { + "code" : "0xef0001010004020001000504000000008000026001805200", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_45" : { + "code" : "0xef0001010004020001000504000000008000026001805300", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_46" : { + "code" : "0xef00010100040200010004040000000080000160015400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_47" : { + "code" : "0xef0001010004020001000504000000008000026001805500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_48" : { + "code" : "0xef000101000402000100060400000000800003600180805e00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_49" : { + "code" : "0xef00010100040200010004040000000080000260018000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_5" : { + "code" : "0xef000101001002000400050005008100800400000000800001010000020200007f7f00007f5fe30001005fe30002e48080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080e30003e450505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050e4", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_50" : { + "code" : "0xef0001010004020001000504000000008000036001808100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_51" : { + "code" : "0xef000101000402000100060400000000800004600180808200", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_52" : { + "code" : "0xef00010100040200010007040000000080000560018080808300", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_53" : { + "code" : "0xef0001010004020001000804000000008000066001808080808400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_54" : { + "code" : "0xef000101000402000100090400000000800007600180808080808500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_55" : { + "code" : "0xef0001010004020001000a040000000080000860018080808080808600", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_56" : { + "code" : "0xef0001010004020001000b04000000008000096001808080808080808700", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_57" : { + "code" : "0xef0001010004020001000c040000000080000a600180808080808080808800", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_58" : { + "code" : "0xef0001010004020001000d040000000080000b60018080808080808080808900", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_59" : { + "code" : "0xef0001010004020001000e040000000080000c6001808080808080808080808a00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_6" : { + "code" : "0xef0001010004020001000504000000008000026001800100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_60" : { + "code" : "0xef0001010004020001000f040000000080000d600180808080808080808080808b00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_61" : { + "code" : "0xef00010100040200010010040000000080000e60018080808080808080808080808c00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_62" : { + "code" : "0xef00010100040200010011040000000080000f6001808080808080808080808080808d00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_63" : { + "code" : "0xef000101000402000100120400000000800010600180808080808080808080808080808e00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_64" : { + "code" : "0xef00010100040200010013040000000080001160018080808080808080808080808080808f00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_65" : { + "code" : "0xef0001010004020001000504000000008000026001809000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_66" : { + "code" : "0xef000101000402000100060400000000800003600180809100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_67" : { + "code" : "0xef00010100040200010007040000000080000460018080809200", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_68" : { + "code" : "0xef0001010004020001000804000000008000056001808080809300", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_69" : { + "code" : "0xef000101000402000100090400000000800006600180808080809400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_7" : { + "code" : "0xef0001010004020001000504000000008000026001800200", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_70" : { + "code" : "0xef0001010004020001000a040000000080000760018080808080809500", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_71" : { + "code" : "0xef0001010004020001000b04000000008000086001808080808080809600", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_72" : { + "code" : "0xef0001010004020001000c0400000000800009600180808080808080809700", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_73" : { + "code" : "0xef0001010004020001000d040000000080000a60018080808080808080809800", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_74" : { + "code" : "0xef0001010004020001000e040000000080000b6001808080808080808080809900", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_75" : { + "code" : "0xef0001010004020001000f040000000080000c600180808080808080808080809a00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_76" : { + "code" : "0xef00010100040200010010040000000080000d60018080808080808080808080809b00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_77" : { + "code" : "0xef00010100040200010011040000000080000e6001808080808080808080808080809c00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_78" : { + "code" : "0xef00010100040200010012040000000080000f600180808080808080808080808080809d00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_79" : { + "code" : "0xef00010100040200010013040000000080001060018080808080808080808080808080809e00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_8" : { + "code" : "0xef0001010004020001000504000000008000026001800300", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_80" : { + "code" : "0xef0001010004020001001404000000008000116001808080808080808080808080808080809f00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_81" : { + "code" : "0xef000101000402000100050400000000800002600180a000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_82" : { + "code" : "0xef00010100040200010006040000000080000360018080a100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_83" : { + "code" : "0xef0001010004020001000704000000008000046001808080a200", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_84" : { + "code" : "0xef000101000402000100080400000000800005600180808080a300", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_85" : { + "code" : "0xef00010100040200010009040000000080000660018080808080a400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_86" : { + "code" : "0xef0001010004020001000a04000000008000076001808080808080f100", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_87" : { + "code" : "0xef000101000402000100040400000000800002600180f3", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_88" : { + "code" : "0xef00010100040200010009040000000080000660018080808080f400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_89" : { + "code" : "0xef00010100040200010009040000000080000660018080808080fa00", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_9" : { + "code" : "0xef0001010004020001000504000000008000026001800400", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_90" : { + "code" : "0xef000101000402000100040400000000800002600180fd", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_91" : { + "code" : "0xef000101000402000100070400000000800002600150600080f3", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_92" : { + "code" : "0xef000101000402000100070400000000800002600150600080fd", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_93" : { + "code" : "0xef000101000402000100030400000000800000e0fffd", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_94" : { + "code" : "0xef0001010004020001000e0400000000800002600a6001900380e1000100e0fff4", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_95" : { + "code" : "0xef000101000c020003000600060006040000000080000101010002000200026000e300010050e3000250e46000610000e4", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_96" : { + "code" : "0xef000101000402000100070400000000800005600080808080f3", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_97" : { + "code" : "0xef000101000402000100070400000000800005600080808080fd", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_98" : { + "code" : "0xef000101000802000200040081040000000080007f007f007fe30001006000808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080e4", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_99" : { + "code" : "0xef000101000c020003000600060003040000000080000101000002020000026000e30001006000e30002e45050e4", + "results" : { + "Prague" : { + "result" : true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/efExample/validInvalid.json b/crates/interpreter/tests/EOFTests/efExample/validInvalid.json new file mode 100644 index 00000000..497cbd18 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/efExample/validInvalid.json @@ -0,0 +1,485 @@ +{ + "validInvalid" : { + "_info" : { + "comment" : "Test various examples to see if they are valid or invalid.\nImplements\n EOF1I0001 check that EOF1 with a bad magic number fails\n EOF1I0002 check that EOF1 with a bad version number fails\n EOF1I0003 check that EOF1 with a bad section order fails\n EOF1I0004 check that EOF1 missing a section fails\n EOF1I0005 check that EOF1 with a bad end of sections number fails\n EOF1I0006 check that EOF1 with too many or too few bytes fails\n EOF1I0007 check that EOF1 with a malformed code section fails\n EOF1I0008 check that EOF1 with an illegal opcode fails\n EOF1I0009 check that EOF1 with the wrong maxStackDepth fails\n EOF1I0010 check that return values are not allowed on section 0\n EOF1I0011 check that function calls to code sections that don't exist fail\n EOF1I0012 check that code sections that cause stack underflow fail\n EOF1I0013 check that we can't return more values than we declare\n EOF1I0014 check that code that looks deeper in the stack than the parameters fails\n EOF1I0015 check that code that uses removed opcodes fails\n EOF1I0016 check that code that uses new relative jumps to outside the section fails\n EOF1I0017 check that parameters are not allowed on section 0\n EOF1I0018 inconsistent number of code sections (between types and code)\n EOF1I0019 check that jumps into the middle on an opcode are not allowed\n EOF1I0020 check that you can't get to the same opcode with two different stack heights\n EOF1I0022 stack underflow caused by a function call\n EOF1I0023 sections with unreachable code fail\n EOF1I0024 sections that end with a non-terminator opcode fail\n EOF1I0025 data stack height of 1024 is invalid\n EOF1V0001 check that simple valid EOF1 deploys\n EOF1V0002 check that valid EOF1 with two code sections deploys\n EOF1V0003 check that valid EOF1 with four code sections deploys\n EOF1V0004 check that valid EOF1 can include 0xFE, the designated invalid opcode\n EOF1V0005 check that EOF1 with the right maxStackDepth deploys\n EOF1V0006 check that return values are allowed on code sections that aren't zero\n EOF1V0007 check that function calls to code sections that exist are allowed\n EOF1V0008 check that code that uses a new style relative jump (5C) succeeds\n EOF1V0009 check that parameters are allowed on code sections that aren't zero\n EOF1V0010 parameters are part of the max stack height\n EOF1V0011 check that code that uses a new style conditional jump (5D) succeeds\n EOF1V0012 return values on code sections affect maxStackHeight of the caller\n EOF1V0013 jump tables work\n EOF1V0014 sections that end with a legit terminating opcode are OK\n EOF1V0015 data stack height of 1023 is valid\n EOF1V0016 check that data section size can be less than the declared size\n", + "filling-rpc-server" : "evmone-t8n 0.12.0-dev+commit.14ba7529", + "filling-tool-version" : "retesteth-0.3.2-cancun+commit.9d793abd.Linux.g++", + "generatedTestHash" : "8be48064c85661c6125e29eba56ec2ea604ba480d22410eedb125978ed173d2e", + "lllcversion" : "Version: 0.5.14-develop.2022.4.6+commit.401d5358.Linux.g++", + "solidity" : "Version: 0.8.18-develop.2023.1.16+commit.469d6d4d.Linux.g++", + "source" : "src/EOFTestsFiller/efExample/validInvalidFiller.yml", + "sourceHash" : "3e743bba1e9bffbfcc2bf398913470701329e100ed6a31bc155fb323f4910c7b" + }, + "vectors" : { + "validInvalid_0" : { + "code" : "0xef000101000402000100030400010000800001305000ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_1" : { + "code" : "0xef0001010004020001000304000400008000013050000bad", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_10" : { + "code" : "0xef0001010014020005001900030003000100010400040000800001008000020080000200800000000000005f35e2030000000300060009e50001e50002e50003e30004005f5ff35f5ffdfee40bad60a7", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_11" : { + "code" : "0xef0001010004020001000d04000400008000016001e2010002000030503050000bad60a7", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_12" : { + "code" : "0xef0001010004020001000d04000400008000016001e2020002ffff30503050000bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_13" : { + "code" : "0xef0001010004020001000804000400008000016001e10001305b000bad60a7", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_14" : { + "code" : "0xef0001010004020001000a0400040000800000e00003e00002e0fffa000bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_15" : { + "code" : "0xef000101000402000100100400040000800003600060006000e10003e10002e1fffa000bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_16" : { + "code" : "0xef000101000802000100030400040000800001000000003050000bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidTypeSectionSize", + "result" : false + } + } + }, + "validInvalid_17" : { + "code" : "0xef0001010008020001000304000400008000013050000bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidTypeSectionSize", + "result" : false + } + } + }, + "validInvalid_18" : { + "code" : "0xef0001010004020001000504000100008000016003565b00ef", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_19" : { + "code" : "0xef00010100040200010007040001000080000160016003575b00ef", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_2" : { + "code" : "0xef0001010004020001000304000400008000013050000bad60a70bad", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidSectionBodiesSize", + "result" : false + } + } + }, + "validInvalid_20" : { + "code" : "0xef0001010004020001000404000100008000016001ff00ef", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_21" : { + "code" : "0xef000101000402000100040400010000800007", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidSectionBodiesSize", + "result" : false + } + } + }, + "validInvalid_22" : { + "code" : "0xef0001010004020001001004000100008000016001600260036004600560066007f200ef", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_23" : { + "code" : "0xef0001010004020001000504000100008000016003565b00ef", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_24" : { + "code" : "0xef00010100080200020006000304000400008000010101000130e3000150005030e40bad60a7", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_25" : { + "code" : "0xef000101000802000200040002040004000080000100010001e300010030e40bad60a7", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_26" : { + "code" : "0xef000101000802000200030001040004000080000100010001e30001300bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidCodeTermination", + "result" : false + } + } + }, + "validInvalid_27" : { + "code" : "0xef000101000802000200040002040004000080000101000001e300010050e40bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_28" : { + "code" : "0xef000101000c0200030028000b001f04000400008003ff000a000a00640064e30002e30002e30002e30002e30002e30002e30002e30002e30002e30002e30001e300013030300030303030303030303030e4e30001e30001e30001e30001e30001e30001e30001e30001e30001e30001e40bad60a7", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_29" : { + "code" : "0xef000101000c0200030029000b001f0400040000800400000a000a00640064e30002e30002e30002e30002e30002e30002e30002e30002e30002e30002e30001e30001303030300030303030303030303030e4e30001e30001e30001e30001e30001e30001e30001e30001e30001e30001e40bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_MaxStackHeightExceeded", + "result" : false + } + } + }, + "validInvalid_3" : { + "code" : "0xef0001010004020001000304000400008000013050000bad60a7", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_30" : { + "code" : "0xef0001010010020004000b000300030003040004000080000101010001000000010101000130e30001e30003e30002005030e43050e45030e40bad60a7", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_31" : { + "code" : "0xef00010100100200040015000500070007040004000080000100800002008000030080000130505f35e202000000030006e50001e50002e50003303050500030303050505000305030503050000bad60a7", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_32" : { + "code" : "0xef00010100100200040010000300070007040004000080000100800000008000030080000130505f35e20100000003e50001e50003e5000230303050505000305030503050000bad60a7", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_33" : { + "code" : "0xef00010100100200040015000300070007040004000080000100800000008000030080000130505f35e202000000030006e50001e50002e50003e5000f30303050505000305030503050000bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidCodeSectionIndex", + "result" : false + } + } + }, + "validInvalid_34" : { + "code" : "0xef0001010008020002000600030400040000800001028000023050e50001005050000bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_35" : { + "code" : "0xef0001010008020002000600030400040000800001000100023050e30001003030e40bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidNumberOfOutputs", + "result" : false + } + } + }, + "validInvalid_36" : { + "code" : "0xef0001010008020002000600030400040000800001010100023050e30001003091e40bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_37" : { + "code" : "0xef0001010004020001000304000400000100013050fe0bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidFirstSectionType", + "result" : false + } + } + }, + "validInvalid_38" : { + "code" : "0xef000101000802000200050003040004000080000202800002305fe500015050000bad60a7", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_39" : { + "code" : "0xef0001010004020001000304000400018000013050fe0bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidFirstSectionType", + "result" : false + } + } + }, + "validInvalid_4" : { + "code" : "0xef00010100040200010003040004000080000130ef000bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_40" : { + "code" : "0xef0001010004020001000304000400008000033050000bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidMaxStackHeight", + "result" : false + } + } + }, + "validInvalid_41" : { + "code" : "0xef00010100040200010001040004000080000530503050000bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidSectionBodiesSize", + "result" : false + } + } + }, + "validInvalid_42" : { + "code" : "0xef0001010004020001000304000400008000013050620bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_TruncatedImmediate", + "result" : false + } + } + }, + "validInvalid_43" : { + "code" : "0xef00010100040200010003040001ff00800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_HeaderTerminatorMissing", + "result" : false + } + } + }, + "validInvalid_44" : { + "code" : "0xef020101000402000100030400010000800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidMagic", + "result" : false + } + } + }, + "validInvalid_45" : { + "code" : "0xef000001000402000100030400010000800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidVersion", + "result" : false + } + } + }, + "validInvalid_46" : { + "code" : "0xef000201000402000100030400010000800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidVersion", + "result" : false + } + } + }, + "validInvalid_47" : { + "code" : "0xef000102000100030100040400010000800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_TypeSectionMissing", + "result" : false + } + } + }, + "validInvalid_48" : { + "code" : "0xef000102000100030400010100040000800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_TypeSectionMissing", + "result" : false + } + } + }, + "validInvalid_49" : { + "code" : "0xef000102000100030400010000800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_TypeSectionMissing", + "result" : false + } + } + }, + "validInvalid_5" : { + "code" : "0xef0001010004020001000304000400008000013050fe0bad60a7", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_50" : { + "code" : "0xef00010100040400010000800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_CodeSectionMissing", + "result" : false + } + } + }, + "validInvalid_51" : { + "code" : "0xef000101000402000100030000800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_DataSectionMissing", + "result" : false + } + } + }, + "validInvalid_52" : { + "code" : "0xef0001010004020001000a040016000080000338600060003938601df3ef0001010004020001000304001d0000000001385000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_53" : { + "code" : "0x610badfe", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidMagic", + "result" : false + } + } + }, + "validInvalid_6" : { + "code" : "0xef00010100040200010003040001ff00800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_HeaderTerminatorMissing", + "result" : false + } + } + }, + "validInvalid_7" : { + "code" : "0xef0001010004020001000e04000400008000015fe10003e00003e00003e0fffa000bad60a7", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_8" : { + "code" : "0xef000101000402000100050400040000800000e000015b000bad60a7", + "results" : { + "Prague" : { + "exception" : "EOF_UnreachableCode", + "result" : false + } + } + }, + "validInvalid_9" : { + "code" : "0xef0001010004020001000704000400008000016001e100015b000bad60a7", + "results" : { + "Prague" : { + "result" : true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/efExample/ymlExample.json b/crates/interpreter/tests/EOFTests/efExample/ymlExample.json new file mode 100644 index 00000000..36505b91 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/efExample/ymlExample.json @@ -0,0 +1,51 @@ +{ + "ymlExample" : { + "_info" : { + "comment" : "EOF example test", + "filling-rpc-server" : "evmone-t8n 0.12.0-dev+commit.14ba7529", + "filling-tool-version" : "retesteth-0.3.2-cancun+commit.9d793abd.Linux.g++", + "generatedTestHash" : "acafd37d166881fa1a015acb1d6ff88f0f698e14a7db9098952065aaa90e78e5", + "lllcversion" : "Version: 0.5.14-develop.2022.4.6+commit.401d5358.Linux.g++", + "solidity" : "Version: 0.8.18-develop.2023.1.16+commit.469d6d4d.Linux.g++", + "source" : "src/EOFTestsFiller/efExample/ymlExampleFiller.yml", + "sourceHash" : "3eb098795ee0f651ae94dab0674f1a6f2e9dd5d6210cf6719508d9f301b4b71d" + }, + "vectors" : { + "ymlExample_0" : { + "code" : "0x60016000f3", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidPrefix", + "result" : false + } + } + }, + "ymlExample_1" : { + "code" : "0xef0001010004020001000a040016000080000338600060003938601df3ef0001010004020001000304001d0000800001385000", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "ymlExample_2" : { + "code" : "0xefffff", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidPrefix", + "result" : false + } + } + }, + "ymlExample_3" : { + "code" : "0x610badfe", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidPrefix", + "result" : false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_callf_truncated.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_callf_truncated.json new file mode 100644 index 00000000..4a160d19 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_callf_truncated.json @@ -0,0 +1,24 @@ +{ + "EOF1_callf_truncated": { + "vectors": { + "EOF1_callf_truncated_0": { + "code": "0xef000101000402000100010400000000800000e3", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_callf_truncated_1": { + "code": "0xef000101000402000100020400000000800000e300", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_code_section_0_size.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_code_section_0_size.json new file mode 100644 index 00000000..8ca3ca3c --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_code_section_0_size.json @@ -0,0 +1,24 @@ +{ + "EOF1_code_section_0_size": { + "vectors": { + "EOF1_code_section_0_size_0": { + "code": "0xef000101000402000000", + "results": { + "Prague": { + "exception": "EOF_ZeroSectionSize", + "result": false + } + } + }, + "EOF1_code_section_0_size_1": { + "code": "0xef000101000402000004000100da", + "results": { + "Prague": { + "exception": "EOF_ZeroSectionSize", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_code_section_missing.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_code_section_missing.json new file mode 100644 index 00000000..275c6a9c --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_code_section_missing.json @@ -0,0 +1,24 @@ +{ + "EOF1_code_section_missing": { + "vectors": { + "EOF1_code_section_missing_0": { + "code": "0xef000101000400", + "results": { + "Prague": { + "exception": "EOF_CodeSectionMissing", + "result": false + } + } + }, + "EOF1_code_section_missing_1": { + "code": "0xef00010100040400010000800000da", + "results": { + "Prague": { + "exception": "EOF_CodeSectionMissing", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_code_section_offset.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_code_section_offset.json new file mode 100644 index 00000000..d150cbac --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_code_section_offset.json @@ -0,0 +1,14 @@ +{ + "EOF1_code_section_offset": { + "vectors": { + "EOF1_code_section_offset_0": { + "code": "0xef000101000802000200030001040004000080000000800000e50001fe00000000", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_data_section_0_size.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_data_section_0_size.json new file mode 100644 index 00000000..8e10968c --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_data_section_0_size.json @@ -0,0 +1,14 @@ +{ + "EOF1_data_section_0_size": { + "vectors": { + "EOF1_data_section_0_size_0": { + "code": "0xef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_data_section_before_code_section.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_data_section_before_code_section.json new file mode 100644 index 00000000..eb96abcf --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_data_section_before_code_section.json @@ -0,0 +1,15 @@ +{ + "EOF1_data_section_before_code_section": { + "vectors": { + "EOF1_data_section_before_code_section_0": { + "code": "0xef000101000403000102000100010000800000aafe", + "results": { + "Prague": { + "exception": "EOF_CodeSectionMissing", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_data_section_before_types_section.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_data_section_before_types_section.json new file mode 100644 index 00000000..8f6595f4 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_data_section_before_types_section.json @@ -0,0 +1,15 @@ +{ + "EOF1_data_section_before_types_section": { + "vectors": { + "EOF1_data_section_before_types_section_0": { + "code": "0xef0001040001010004020001000100aa00800000fe", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_dataloadn_truncated.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_dataloadn_truncated.json new file mode 100644 index 00000000..c5a12080 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_dataloadn_truncated.json @@ -0,0 +1,24 @@ +{ + "EOF1_dataloadn_truncated": { + "vectors": { + "EOF1_dataloadn_truncated_0": { + "code": "0xef000101000402000100010400000000800000d1", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_dataloadn_truncated_1": { + "code": "0xef000101000402000100020400000000800000d100", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_embedded_container.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_embedded_container.json new file mode 100644 index 00000000..37748c14 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_embedded_container.json @@ -0,0 +1,55 @@ +{ + "EOF1_embedded_container": { + "vectors": { + "EOF1_embedded_container_0": { + "code": "0xef00010100040200010006030001001404000000008000016000e0000000ef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_embedded_container_1": { + "code": "0xef00010100040200010006030001001404000200008000016000e0000000ef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_embedded_container_2": { + "code": "0xef00010100040200010006030001001404000200008000016000e0000000ef000101000402000100010400000000800000feaabb", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_embedded_container_3": { + "code": "0xef00010100040200010006030001000604000000008000016000e0000000aabbccddeeff", + "results": { + "Prague": { + "exception": "EOF_InvalidPrefix", + "result": false + } + } + }, + "EOF1_embedded_container_4": { + "code": "0xef000101000402000100060300020014001604000000008000016000e0000000ef000101000402000100010400000000800000feef0001010004020001000304000000008000025f5ff3", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_embedded_container_5": { + "code": "0xef00010100040200010006030100001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001404000000008000016000e0000000ef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_embedded_container_invalid.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_embedded_container_invalid.json new file mode 100644 index 00000000..b394324a --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_embedded_container_invalid.json @@ -0,0 +1,87 @@ +{ + "EOF1_embedded_container_invalid": { + "vectors": { + "EOF1_embedded_container_invalid_0": { + "code": "0xef0001010004020001000603", + "results": { + "Prague": { + "exception": "EOF_IncompleteSectionNumber", + "result": false + } + } + }, + "EOF1_embedded_container_invalid_1": { + "code": "0xef000101000402000100060300", + "results": { + "Prague": { + "exception": "EOF_IncompleteSectionNumber", + "result": false + } + } + }, + "EOF1_embedded_container_invalid_2": { + "code": "0xef00010100040200010006030001", + "results": { + "Prague": { + "exception": "EOF_SectionHeadersNotTerminated", + "result": false + } + } + }, + "EOF1_embedded_container_invalid_3": { + "code": "0xef0001010004020001000603000100", + "results": { + "Prague": { + "exception": "EOF_IncompleteSectionSize", + "result": false + } + } + }, + "EOF1_embedded_container_invalid_4": { + "code": "0xef000101000402000100060300010014", + "results": { + "Prague": { + "exception": "EOF_SectionHeadersNotTerminated", + "result": false + } + } + }, + "EOF1_embedded_container_invalid_5": { + "code": "0xef00010100040200010006030000040000000080000160005d000000", + "results": { + "Prague": { + "exception": "EOF_ZeroSectionSize", + "result": false + } + } + }, + "EOF1_embedded_container_invalid_6": { + "code": "0xef000101000402000100060300010000040000000080000160005d000000", + "results": { + "Prague": { + "exception": "EOF_ZeroSectionSize", + "result": false + } + } + }, + "EOF1_embedded_container_invalid_7": { + "code": "0xef000101000402000100060300010014040000000080000160005d000000", + "results": { + "Prague": { + "exception": "EOF_InvalidSectionBodiesSize", + "result": false + } + } + }, + "EOF1_embedded_container_invalid_8": { + "code": "0xef0001010004020001000603010100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001040000000080000160005d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TooManyContainerSections", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_eofcreate_invalid.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_eofcreate_invalid.json new file mode 100644 index 00000000..2940c817 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_eofcreate_invalid.json @@ -0,0 +1,51 @@ +{ + "EOF1_eofcreate_invalid": { + "vectors": { + "EOF1_eofcreate_invalid_0": { + "code": "0xef0001010004020001000903000100140400000000800004600060ff60006000ecef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_eofcreate_invalid_1": { + "code": "0xef0001010004020001000a03000100140400000000800004600060ff60006000ec00ef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "exception": "EOF_InvalidCodeTermination", + "result": false + } + } + }, + "EOF1_eofcreate_invalid_2": { + "code": "0xef0001010004020001000c03000100140400000000800004600060ff60006000ec015000ef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "exception": "EOF_InvalidContainerSectionIndex", + "result": false + } + } + }, + "EOF1_eofcreate_invalid_3": { + "code": "0xef0001010004020001000c03000100140400000000800004600060ff60006000ecff5000ef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "exception": "EOF_InvalidContainerSectionIndex", + "result": false + } + } + }, + "EOF1_eofcreate_invalid_4": { + "code": "0xef0001010004020001000c03000100160400000000800004600060ff60006000ec005000ef000101000402000100010400030000800000feaabb", + "results": { + "Prague": { + "exception": "EOF_EofCreateWithTruncatedContainer", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_eofcreate_valid.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_eofcreate_valid.json new file mode 100644 index 00000000..0d8513f6 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_eofcreate_valid.json @@ -0,0 +1,30 @@ +{ + "EOF1_eofcreate_valid": { + "vectors": { + "EOF1_eofcreate_valid_0": { + "code": "0xef0001010004020001000b0300010014040000000080000436600060ff6000ec005000ef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_eofcreate_valid_1": { + "code": "0xef0001010004020001000b03000200140014040000000080000436600060ff6000ec015000ef000101000402000100010400000000800000feef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_eofcreate_valid_2": { + "code": "0xef0001010004020001000b0301000014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014040000000080000436600060ff6000ecff5000ef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_header_not_terminated.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_header_not_terminated.json new file mode 100644 index 00000000..38c7abe2 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_header_not_terminated.json @@ -0,0 +1,78 @@ +{ + "EOF1_header_not_terminated": { + "vectors": { + "EOF1_header_not_terminated_0": { + "code": "0xef000101", + "results": { + "Prague": { + "exception": "EOF_SectionHeadersNotTerminated", + "result": false + } + } + }, + "EOF1_header_not_terminated_1": { + "code": "0xef0001010004", + "results": { + "Prague": { + "exception": "EOF_SectionHeadersNotTerminated", + "result": false + } + } + }, + "EOF1_header_not_terminated_2": { + "code": "0xef0001010004fe", + "results": { + "Prague": { + "exception": "EOF_CodeSectionMissing", + "result": false + } + } + }, + "EOF1_header_not_terminated_3": { + "code": "0xef000101000402", + "results": { + "Prague": { + "exception": "EOF_IncompleteSectionNumber", + "result": false + } + } + }, + "EOF1_header_not_terminated_4": { + "code": "0xef00010100040200", + "results": { + "Prague": { + "exception": "EOF_IncompleteSectionNumber", + "result": false + } + } + }, + "EOF1_header_not_terminated_5": { + "code": "0xef0001010004020001", + "results": { + "Prague": { + "exception": "EOF_SectionHeadersNotTerminated", + "result": false + } + } + }, + "EOF1_header_not_terminated_6": { + "code": "0xef00010100040200010001040001", + "results": { + "Prague": { + "exception": "EOF_SectionHeadersNotTerminated", + "result": false + } + } + }, + "EOF1_header_not_terminated_7": { + "code": "0xef00010100040200010001040001feaa", + "results": { + "Prague": { + "exception": "EOF_HeaderTerminatorMissing", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_incomplete_section_size.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_incomplete_section_size.json new file mode 100644 index 00000000..928b771d --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_incomplete_section_size.json @@ -0,0 +1,69 @@ +{ + "EOF1_incomplete_section_size": { + "vectors": { + "EOF1_incomplete_section_size_0": { + "code": "0xef000101", + "results": { + "Prague": { + "exception": "EOF_SectionHeadersNotTerminated", + "result": false + } + } + }, + "EOF1_incomplete_section_size_1": { + "code": "0xef00010100", + "results": { + "Prague": { + "exception": "EOF_IncompleteSectionSize", + "result": false + } + } + }, + "EOF1_incomplete_section_size_2": { + "code": "0xef00010100040200", + "results": { + "Prague": { + "exception": "EOF_IncompleteSectionNumber", + "result": false + } + } + }, + "EOF1_incomplete_section_size_3": { + "code": "0xef000101000402000100", + "results": { + "Prague": { + "exception": "EOF_IncompleteSectionSize", + "result": false + } + } + }, + "EOF1_incomplete_section_size_4": { + "code": "0xef00010100040200010001", + "results": { + "Prague": { + "exception": "EOF_SectionHeadersNotTerminated", + "result": false + } + } + }, + "EOF1_incomplete_section_size_5": { + "code": "0xef0001010004020001000104", + "results": { + "Prague": { + "exception": "EOF_SectionHeadersNotTerminated", + "result": false + } + } + }, + "EOF1_incomplete_section_size_6": { + "code": "0xef000101000402000100010400", + "results": { + "Prague": { + "exception": "EOF_IncompleteSectionSize", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_invalid_section_0_type.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_invalid_section_0_type.json new file mode 100644 index 00000000..0afe03ba --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_invalid_section_0_type.json @@ -0,0 +1,42 @@ +{ + "EOF1_invalid_section_0_type": { + "vectors": { + "EOF1_invalid_section_0_type_0": { + "code": "0xef00010100040200010001040000000000000000", + "results": { + "Prague": { + "exception": "EOF_InvalidFirstSectionType", + "result": false + } + } + }, + "EOF1_invalid_section_0_type_1": { + "code": "0xef00010100040200010003040000000001000060005c", + "results": { + "Prague": { + "exception": "EOF_InvalidFirstSectionType", + "result": false + } + } + }, + "EOF1_invalid_section_0_type_2": { + "code": "0xef000101000402000100010400000001800000fe", + "results": { + "Prague": { + "exception": "EOF_InvalidFirstSectionType", + "result": false + } + } + }, + "EOF1_invalid_section_0_type_3": { + "code": "0xef00010100040200010003040000000203000060005c", + "results": { + "Prague": { + "exception": "EOF_InvalidFirstSectionType", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_invalid_type_section_size.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_invalid_type_section_size.json new file mode 100644 index 00000000..698bf856 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_invalid_type_section_size.json @@ -0,0 +1,51 @@ +{ + "EOF1_invalid_type_section_size": { + "vectors": { + "EOF1_invalid_type_section_size_0": { + "code": "0xef000101000102000100010400000000fe", + "results": { + "Prague": { + "exception": "EOF_InvalidTypeSectionSize", + "result": false + } + } + }, + "EOF1_invalid_type_section_size_1": { + "code": "0xef00010100020200010001040000000080fe", + "results": { + "Prague": { + "exception": "EOF_InvalidTypeSectionSize", + "result": false + } + } + }, + "EOF1_invalid_type_section_size_2": { + "code": "0xef00010100080200010001040000000080000000000000fe", + "results": { + "Prague": { + "exception": "EOF_InvalidTypeSectionSize", + "result": false + } + } + }, + "EOF1_invalid_type_section_size_3": { + "code": "0xef0001010008020003000100010001040000000080000000800000fefefe", + "results": { + "Prague": { + "exception": "EOF_InvalidTypeSectionSize", + "result": false + } + } + }, + "EOF1_invalid_type_section_size_4": { + "code": "0xef00010100100200030001000100010400000000800000008000000080000000800000fefefe", + "results": { + "Prague": { + "exception": "EOF_InvalidTypeSectionSize", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_multiple_data_sections.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_multiple_data_sections.json new file mode 100644 index 00000000..17cb8a34 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_multiple_data_sections.json @@ -0,0 +1,15 @@ +{ + "EOF1_multiple_data_sections": { + "vectors": { + "EOF1_multiple_data_sections_0": { + "code": "0xef000101000402000100010400010400010000800000fedada", + "results": { + "Prague": { + "exception": "EOF_HeaderTerminatorMissing", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_multiple_type_sections.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_multiple_type_sections.json new file mode 100644 index 00000000..6a83b1a9 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_multiple_type_sections.json @@ -0,0 +1,24 @@ +{ + "EOF1_multiple_type_sections": { + "vectors": { + "EOF1_multiple_type_sections_0": { + "code": "0xef000101000401000402000200010001000080000000800000fefe", + "results": { + "Prague": { + "exception": "EOF_CodeSectionMissing", + "result": false + } + } + }, + "EOF1_multiple_type_sections_1": { + "code": "0xef0001030002010001010001040002000000fefe0000", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_no_type_section.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_no_type_section.json new file mode 100644 index 00000000..2d046aa7 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_no_type_section.json @@ -0,0 +1,24 @@ +{ + "EOF1_no_type_section": { + "vectors": { + "EOF1_no_type_section_0": { + "code": "0xef0001020001000100fe", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + }, + "EOF1_no_type_section_1": { + "code": "0xef00010200020001000100fefe", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_returncontract_invalid.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_returncontract_invalid.json new file mode 100644 index 00000000..be7ee592 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_returncontract_invalid.json @@ -0,0 +1,42 @@ +{ + "EOF1_returncontract_invalid": { + "vectors": { + "EOF1_returncontract_invalid_0": { + "code": "0xef000101000402000100050300010014040000000080000460006000eeef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_returncontract_invalid_1": { + "code": "0xef000101000402000100060300010014040000000080000460006000ee01ef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "exception": "EOF_InvalidContainerSectionIndex", + "result": false + } + } + }, + "EOF1_returncontract_invalid_2": { + "code": "0xef000101000402000100060300010014040000000080000460006000eeffef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "exception": "EOF_InvalidContainerSectionIndex", + "result": false + } + } + }, + "EOF1_returncontract_invalid_3": { + "code": "0xef000101000402000100070300010014040000000080000260006000ee0000ef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "exception": "EOF_UnreachableCode", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_returncontract_valid.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_returncontract_valid.json new file mode 100644 index 00000000..60252e7d --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_returncontract_valid.json @@ -0,0 +1,30 @@ +{ + "EOF1_returncontract_valid": { + "vectors": { + "EOF1_returncontract_valid_0": { + "code": "0xef000101000402000100060300010014040000000080000260006000ee00ef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_returncontract_valid_1": { + "code": "0xef0001010004020001000603000200140014040000000080000260006000ee01ef000101000402000100010400000000800000feef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_returncontract_valid_2": { + "code": "0xef000101000402000100060301000014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014001400140014040000000080000260006000eeffef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000feef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjump_invalid_destination.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjump_invalid_destination.json new file mode 100644 index 00000000..1ae65f3e --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjump_invalid_destination.json @@ -0,0 +1,78 @@ +{ + "EOF1_rjump_invalid_destination": { + "vectors": { + "EOF1_rjump_invalid_destination_0": { + "code": "0xef000101000402000100040400000000800000e0fffb00", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjump_invalid_destination_1": { + "code": "0xef000101000402000100040400000000800000e0fff300", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjump_invalid_destination_2": { + "code": "0xef000101000402000100040400000000800000e0000200", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjump_invalid_destination_3": { + "code": "0xef000101000402000100040400000000800000e0000100", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjump_invalid_destination_4": { + "code": "0xef000101000402000100040400000000800000e0ffff00", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjump_invalid_destination_5": { + "code": "0xef0001010004020001000604000000008000006000e0fffc00", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjump_invalid_destination_6": { + "code": "0xef0001010004020001000f03000100140400000000800004e00009600060ff60006000ec005000ef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjump_invalid_destination_7": { + "code": "0xef0001010004020001000903000100140400000000800002e0000560006000ee00ef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjump_truncated.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjump_truncated.json new file mode 100644 index 00000000..8f2d5863 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjump_truncated.json @@ -0,0 +1,24 @@ +{ + "EOF1_rjump_truncated": { + "vectors": { + "EOF1_rjump_truncated_0": { + "code": "0xef000101000402000100010400000000800000e0", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_rjump_truncated_1": { + "code": "0xef000101000402000100020400000000800000e000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjumpi_invalid_destination.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjumpi_invalid_destination.json new file mode 100644 index 00000000..b119e62e --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjumpi_invalid_destination.json @@ -0,0 +1,78 @@ +{ + "EOF1_rjumpi_invalid_destination": { + "vectors": { + "EOF1_rjumpi_invalid_destination_0": { + "code": "0xef0001010004020001000604000000008000006000e1fff900", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpi_invalid_destination_1": { + "code": "0xef0001010004020001000604000000008000006000e1fff100", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpi_invalid_destination_2": { + "code": "0xef0001010004020001000604000000008000006000e1000200", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpi_invalid_destination_3": { + "code": "0xef0001010004020001000604000000008000006000e1000100", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpi_invalid_destination_4": { + "code": "0xef0001010004020001000604000000008000006000e1ffff00", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpi_invalid_destination_5": { + "code": "0xef0001010004020001000604000000008000006000e1fffc00", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpi_invalid_destination_6": { + "code": "0xef00010100040200010011030001001404000000008000046000e10009600060ff60006000ec005000ef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpi_invalid_destination_7": { + "code": "0xef0001010004020001000b030001001404000000008000026000e1000560006000ee00ef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjumpi_truncated.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjumpi_truncated.json new file mode 100644 index 00000000..1eab63f4 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjumpi_truncated.json @@ -0,0 +1,24 @@ +{ + "EOF1_rjumpi_truncated": { + "vectors": { + "EOF1_rjumpi_truncated_0": { + "code": "0xef0001010004020001000304000000008000006000e1", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_rjumpi_truncated_1": { + "code": "0xef0001010004020001000404000000008000006000e100", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjumpv_invalid_destination.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjumpv_invalid_destination.json new file mode 100644 index 00000000..adf48163 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjumpv_invalid_destination.json @@ -0,0 +1,114 @@ +{ + "EOF1_rjumpv_invalid_destination": { + "vectors": { + "EOF1_rjumpv_invalid_destination_0": { + "code": "0xef0001010004020001000804000000008000006000e200ffe96001", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpv_invalid_destination_1": { + "code": "0xef0001010004020001000804000000008000006000e200fff86001", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpv_invalid_destination_10": { + "code": "0xef00010100040200010012030001001404000000008000046000e2000009600060ff60006000ec005000ef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpv_invalid_destination_11": { + "code": "0xef0001010004020001000c030001001404000000008000026000e200000560006000ee00ef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpv_invalid_destination_2": { + "code": "0xef0001010004020001000804000000008000006000e200ffff6001", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpv_invalid_destination_3": { + "code": "0xef0001010004020001000804000000008000006000e20000026001", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpv_invalid_destination_4": { + "code": "0xef0001010004020001000804000000008000006000e20000036001", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpv_invalid_destination_5": { + "code": "0xef0001010004020001000f04000000008000006002e20200000003ffe56001006002", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpv_invalid_destination_6": { + "code": "0xef0001010004020001000f04000000008000006002e20200000003fff46001006002", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpv_invalid_destination_7": { + "code": "0xef0001010004020001000f04000000008000006002e20200000003ffff6001006002", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpv_invalid_destination_8": { + "code": "0xef0001010004020001000f04000000008000006002e2020000000300056001006002", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + }, + "EOF1_rjumpv_invalid_destination_9": { + "code": "0xef0001010004020001000f04000000008000006002e2020000000300066001006002", + "results": { + "Prague": { + "exception": "EOF_InvalidJumpDestination", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjumpv_truncated.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjumpv_truncated.json new file mode 100644 index 00000000..17c521a9 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_rjumpv_truncated.json @@ -0,0 +1,42 @@ +{ + "EOF1_rjumpv_truncated": { + "vectors": { + "EOF1_rjumpv_truncated_0": { + "code": "0xef0001010004020001000504000000008000006000e20000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_rjumpv_truncated_1": { + "code": "0xef0001010004020001000704000000008000006000e201000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_rjumpv_truncated_2": { + "code": "0xef0001010004020001000604000000008000006002e2010000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_rjumpv_truncated_3": { + "code": "0xef0001010004020001000904000000008000006002e20200000003ff", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_section_order.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_section_order.json new file mode 100644 index 00000000..5bb7cf0c --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_section_order.json @@ -0,0 +1,94 @@ +{ + "EOF1_section_order": { + "vectors": { + "EOF1_section_order_0": { + "code": "0xef0001010004020001000604000200008000016000e0000000aabb", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_section_order_1": { + "code": "0xef000101000404000202000100060000800000aabb6000e0000000", + "results": { + "Prague": { + "exception": "EOF_CodeSectionMissing", + "result": false + } + } + }, + "EOF1_section_order_2": { + "code": "0xef00010200010006010004040002006000e000000000800000aabb", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + }, + "EOF1_section_order_3": { + "code": "0xef00010200010006040002010004006000e0000000aabb00800000", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + }, + "EOF1_section_order_4": { + "code": "0xef0001040002010004020001000600aabb008000006000e0000000", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + }, + "EOF1_section_order_5": { + "code": "0xef0001040002020001000601000400aabb6000e000000000800000", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + }, + "EOF1_section_order_6": { + "code": "0xef00010100040200010006030001001404000200008000016000e0000000ef000101000402000100010400000000800000feaabb", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_section_order_7": { + "code": "0xef00010300010014010004020001000604000200ef000101000402000100010400000000800000fe008000016000e0000000aabb", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + }, + "EOF1_section_order_8": { + "code": "0xef0001010004030001001402000100060400020000800001ef000101000402000100010400000000800000fe6000e0000000aabb", + "results": { + "Prague": { + "exception": "EOF_CodeSectionMissing", + "result": false + } + } + }, + "EOF1_section_order_9": { + "code": "0xef00010100040200010006040002030001001400008000016000e0000000aabbef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "exception": "EOF_HeaderTerminatorMissing", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_too_many_code_sections.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_too_many_code_sections.json new file mode 100644 index 00000000..8fc104ac --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_too_many_code_sections.json @@ -0,0 +1,23 @@ +{ + "EOF1_too_many_code_sections": { + "vectors": { + "invalid": { + "code": "0xef000101100202040100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001040000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000e50001e50002e50003e50004e50005e50006e50007e50008e50009e5000ae5000be5000ce5000de5000ee5000fe50010e50011e50012e50013e50014e50015e50016e50017e50018e50019e5001ae5001be5001ce5001de5001ee5001fe50020e50021e50022e50023e50024e50025e50026e50027e50028e50029e5002ae5002be5002ce5002de5002ee5002fe50030e50031e50032e50033e50034e50035e50036e50037e50038e50039e5003ae5003be5003ce5003de5003ee5003fe50040e50041e50042e50043e50044e50045e50046e50047e50048e50049e5004ae5004be5004ce5004de5004ee5004fe50050e50051e50052e50053e50054e50055e50056e50057e50058e50059e5005ae5005be5005ce5005de5005ee5005fe50060e50061e50062e50063e50064e50065e50066e50067e50068e50069e5006ae5006be5006ce5006de5006ee5006fe50070e50071e50072e50073e50074e50075e50076e50077e50078e50079e5007ae5007be5007ce5007de5007ee5007fe50080e50081e50082e50083e50084e50085e50086e50087e50088e50089e5008ae5008be5008ce5008de5008ee5008fe50090e50091e50092e50093e50094e50095e50096e50097e50098e50099e5009ae5009be5009ce5009de5009ee5009fe500a0e500a1e500a2e500a3e500a4e500a5e500a6e500a7e500a8e500a9e500aae500abe500ace500ade500aee500afe500b0e500b1e500b2e500b3e500b4e500b5e500b6e500b7e500b8e500b9e500bae500bbe500bce500bde500bee500bfe500c0e500c1e500c2e500c3e500c4e500c5e500c6e500c7e500c8e500c9e500cae500cbe500cce500cde500cee500cfe500d0e500d1e500d2e500d3e500d4e500d5e500d6e500d7e500d8e500d9e500dae500dbe500dce500dde500dee500dfe500e0e500e1e500e2e500e3e500e4e500e5e500e6e500e7e500e8e500e9e500eae500ebe500ece500ede500eee500efe500f0e500f1e500f2e500f3e500f4e500f5e500f6e500f7e500f8e500f9e500fae500fbe500fce500fde500fee500ffe50100e50101e50102e50103e50104e50105e50106e50107e50108e50109e5010ae5010be5010ce5010de5010ee5010fe50110e50111e50112e50113e50114e50115e50116e50117e50118e50119e5011ae5011be5011ce5011de5011ee5011fe50120e50121e50122e50123e50124e50125e50126e50127e50128e50129e5012ae5012be5012ce5012de5012ee5012fe50130e50131e50132e50133e50134e50135e50136e50137e50138e50139e5013ae5013be5013ce5013de5013ee5013fe50140e50141e50142e50143e50144e50145e50146e50147e50148e50149e5014ae5014be5014ce5014de5014ee5014fe50150e50151e50152e50153e50154e50155e50156e50157e50158e50159e5015ae5015be5015ce5015de5015ee5015fe50160e50161e50162e50163e50164e50165e50166e50167e50168e50169e5016ae5016be5016ce5016de5016ee5016fe50170e50171e50172e50173e50174e50175e50176e50177e50178e50179e5017ae5017be5017ce5017de5017ee5017fe50180e50181e50182e50183e50184e50185e50186e50187e50188e50189e5018ae5018be5018ce5018de5018ee5018fe50190e50191e50192e50193e50194e50195e50196e50197e50198e50199e5019ae5019be5019ce5019de5019ee5019fe501a0e501a1e501a2e501a3e501a4e501a5e501a6e501a7e501a8e501a9e501aae501abe501ace501ade501aee501afe501b0e501b1e501b2e501b3e501b4e501b5e501b6e501b7e501b8e501b9e501bae501bbe501bce501bde501bee501bfe501c0e501c1e501c2e501c3e501c4e501c5e501c6e501c7e501c8e501c9e501cae501cbe501cce501cde501cee501cfe501d0e501d1e501d2e501d3e501d4e501d5e501d6e501d7e501d8e501d9e501dae501dbe501dce501dde501dee501dfe501e0e501e1e501e2e501e3e501e4e501e5e501e6e501e7e501e8e501e9e501eae501ebe501ece501ede501eee501efe501f0e501f1e501f2e501f3e501f4e501f5e501f6e501f7e501f8e501f9e501fae501fbe501fce501fde501fee501ffe50200e50201e50202e50203e50204e50205e50206e50207e50208e50209e5020ae5020be5020ce5020de5020ee5020fe50210e50211e50212e50213e50214e50215e50216e50217e50218e50219e5021ae5021be5021ce5021de5021ee5021fe50220e50221e50222e50223e50224e50225e50226e50227e50228e50229e5022ae5022be5022ce5022de5022ee5022fe50230e50231e50232e50233e50234e50235e50236e50237e50238e50239e5023ae5023be5023ce5023de5023ee5023fe50240e50241e50242e50243e50244e50245e50246e50247e50248e50249e5024ae5024be5024ce5024de5024ee5024fe50250e50251e50252e50253e50254e50255e50256e50257e50258e50259e5025ae5025be5025ce5025de5025ee5025fe50260e50261e50262e50263e50264e50265e50266e50267e50268e50269e5026ae5026be5026ce5026de5026ee5026fe50270e50271e50272e50273e50274e50275e50276e50277e50278e50279e5027ae5027be5027ce5027de5027ee5027fe50280e50281e50282e50283e50284e50285e50286e50287e50288e50289e5028ae5028be5028ce5028de5028ee5028fe50290e50291e50292e50293e50294e50295e50296e50297e50298e50299e5029ae5029be5029ce5029de5029ee5029fe502a0e502a1e502a2e502a3e502a4e502a5e502a6e502a7e502a8e502a9e502aae502abe502ace502ade502aee502afe502b0e502b1e502b2e502b3e502b4e502b5e502b6e502b7e502b8e502b9e502bae502bbe502bce502bde502bee502bfe502c0e502c1e502c2e502c3e502c4e502c5e502c6e502c7e502c8e502c9e502cae502cbe502cce502cde502cee502cfe502d0e502d1e502d2e502d3e502d4e502d5e502d6e502d7e502d8e502d9e502dae502dbe502dce502dde502dee502dfe502e0e502e1e502e2e502e3e502e4e502e5e502e6e502e7e502e8e502e9e502eae502ebe502ece502ede502eee502efe502f0e502f1e502f2e502f3e502f4e502f5e502f6e502f7e502f8e502f9e502fae502fbe502fce502fde502fee502ffe50300e50301e50302e50303e50304e50305e50306e50307e50308e50309e5030ae5030be5030ce5030de5030ee5030fe50310e50311e50312e50313e50314e50315e50316e50317e50318e50319e5031ae5031be5031ce5031de5031ee5031fe50320e50321e50322e50323e50324e50325e50326e50327e50328e50329e5032ae5032be5032ce5032de5032ee5032fe50330e50331e50332e50333e50334e50335e50336e50337e50338e50339e5033ae5033be5033ce5033de5033ee5033fe50340e50341e50342e50343e50344e50345e50346e50347e50348e50349e5034ae5034be5034ce5034de5034ee5034fe50350e50351e50352e50353e50354e50355e50356e50357e50358e50359e5035ae5035be5035ce5035de5035ee5035fe50360e50361e50362e50363e50364e50365e50366e50367e50368e50369e5036ae5036be5036ce5036de5036ee5036fe50370e50371e50372e50373e50374e50375e50376e50377e50378e50379e5037ae5037be5037ce5037de5037ee5037fe50380e50381e50382e50383e50384e50385e50386e50387e50388e50389e5038ae5038be5038ce5038de5038ee5038fe50390e50391e50392e50393e50394e50395e50396e50397e50398e50399e5039ae5039be5039ce5039de5039ee5039fe503a0e503a1e503a2e503a3e503a4e503a5e503a6e503a7e503a8e503a9e503aae503abe503ace503ade503aee503afe503b0e503b1e503b2e503b3e503b4e503b5e503b6e503b7e503b8e503b9e503bae503bbe503bce503bde503bee503bfe503c0e503c1e503c2e503c3e503c4e503c5e503c6e503c7e503c8e503c9e503cae503cbe503cce503cde503cee503cfe503d0e503d1e503d2e503d3e503d4e503d5e503d6e503d7e503d8e503d9e503dae503dbe503dce503dde503dee503dfe503e0e503e1e503e2e503e3e503e4e503e5e503e6e503e7e503e8e503e9e503eae503ebe503ece503ede503eee503efe503f0e503f1e503f2e503f3e503f4e503f5e503f6e503f7e503f8e503f9e503fae503fbe503fce503fde503fee503ffe504005b5b00", + "results": { + "Prague": { + "exception": "EOF_TooManyCodeSections", + "result": false + } + } + }, + "valid": { + "code": "0xef000101100002040000030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030400000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000e50001e50002e50003e50004e50005e50006e50007e50008e50009e5000ae5000be5000ce5000de5000ee5000fe50010e50011e50012e50013e50014e50015e50016e50017e50018e50019e5001ae5001be5001ce5001de5001ee5001fe50020e50021e50022e50023e50024e50025e50026e50027e50028e50029e5002ae5002be5002ce5002de5002ee5002fe50030e50031e50032e50033e50034e50035e50036e50037e50038e50039e5003ae5003be5003ce5003de5003ee5003fe50040e50041e50042e50043e50044e50045e50046e50047e50048e50049e5004ae5004be5004ce5004de5004ee5004fe50050e50051e50052e50053e50054e50055e50056e50057e50058e50059e5005ae5005be5005ce5005de5005ee5005fe50060e50061e50062e50063e50064e50065e50066e50067e50068e50069e5006ae5006be5006ce5006de5006ee5006fe50070e50071e50072e50073e50074e50075e50076e50077e50078e50079e5007ae5007be5007ce5007de5007ee5007fe50080e50081e50082e50083e50084e50085e50086e50087e50088e50089e5008ae5008be5008ce5008de5008ee5008fe50090e50091e50092e50093e50094e50095e50096e50097e50098e50099e5009ae5009be5009ce5009de5009ee5009fe500a0e500a1e500a2e500a3e500a4e500a5e500a6e500a7e500a8e500a9e500aae500abe500ace500ade500aee500afe500b0e500b1e500b2e500b3e500b4e500b5e500b6e500b7e500b8e500b9e500bae500bbe500bce500bde500bee500bfe500c0e500c1e500c2e500c3e500c4e500c5e500c6e500c7e500c8e500c9e500cae500cbe500cce500cde500cee500cfe500d0e500d1e500d2e500d3e500d4e500d5e500d6e500d7e500d8e500d9e500dae500dbe500dce500dde500dee500dfe500e0e500e1e500e2e500e3e500e4e500e5e500e6e500e7e500e8e500e9e500eae500ebe500ece500ede500eee500efe500f0e500f1e500f2e500f3e500f4e500f5e500f6e500f7e500f8e500f9e500fae500fbe500fce500fde500fee500ffe50100e50101e50102e50103e50104e50105e50106e50107e50108e50109e5010ae5010be5010ce5010de5010ee5010fe50110e50111e50112e50113e50114e50115e50116e50117e50118e50119e5011ae5011be5011ce5011de5011ee5011fe50120e50121e50122e50123e50124e50125e50126e50127e50128e50129e5012ae5012be5012ce5012de5012ee5012fe50130e50131e50132e50133e50134e50135e50136e50137e50138e50139e5013ae5013be5013ce5013de5013ee5013fe50140e50141e50142e50143e50144e50145e50146e50147e50148e50149e5014ae5014be5014ce5014de5014ee5014fe50150e50151e50152e50153e50154e50155e50156e50157e50158e50159e5015ae5015be5015ce5015de5015ee5015fe50160e50161e50162e50163e50164e50165e50166e50167e50168e50169e5016ae5016be5016ce5016de5016ee5016fe50170e50171e50172e50173e50174e50175e50176e50177e50178e50179e5017ae5017be5017ce5017de5017ee5017fe50180e50181e50182e50183e50184e50185e50186e50187e50188e50189e5018ae5018be5018ce5018de5018ee5018fe50190e50191e50192e50193e50194e50195e50196e50197e50198e50199e5019ae5019be5019ce5019de5019ee5019fe501a0e501a1e501a2e501a3e501a4e501a5e501a6e501a7e501a8e501a9e501aae501abe501ace501ade501aee501afe501b0e501b1e501b2e501b3e501b4e501b5e501b6e501b7e501b8e501b9e501bae501bbe501bce501bde501bee501bfe501c0e501c1e501c2e501c3e501c4e501c5e501c6e501c7e501c8e501c9e501cae501cbe501cce501cde501cee501cfe501d0e501d1e501d2e501d3e501d4e501d5e501d6e501d7e501d8e501d9e501dae501dbe501dce501dde501dee501dfe501e0e501e1e501e2e501e3e501e4e501e5e501e6e501e7e501e8e501e9e501eae501ebe501ece501ede501eee501efe501f0e501f1e501f2e501f3e501f4e501f5e501f6e501f7e501f8e501f9e501fae501fbe501fce501fde501fee501ffe50200e50201e50202e50203e50204e50205e50206e50207e50208e50209e5020ae5020be5020ce5020de5020ee5020fe50210e50211e50212e50213e50214e50215e50216e50217e50218e50219e5021ae5021be5021ce5021de5021ee5021fe50220e50221e50222e50223e50224e50225e50226e50227e50228e50229e5022ae5022be5022ce5022de5022ee5022fe50230e50231e50232e50233e50234e50235e50236e50237e50238e50239e5023ae5023be5023ce5023de5023ee5023fe50240e50241e50242e50243e50244e50245e50246e50247e50248e50249e5024ae5024be5024ce5024de5024ee5024fe50250e50251e50252e50253e50254e50255e50256e50257e50258e50259e5025ae5025be5025ce5025de5025ee5025fe50260e50261e50262e50263e50264e50265e50266e50267e50268e50269e5026ae5026be5026ce5026de5026ee5026fe50270e50271e50272e50273e50274e50275e50276e50277e50278e50279e5027ae5027be5027ce5027de5027ee5027fe50280e50281e50282e50283e50284e50285e50286e50287e50288e50289e5028ae5028be5028ce5028de5028ee5028fe50290e50291e50292e50293e50294e50295e50296e50297e50298e50299e5029ae5029be5029ce5029de5029ee5029fe502a0e502a1e502a2e502a3e502a4e502a5e502a6e502a7e502a8e502a9e502aae502abe502ace502ade502aee502afe502b0e502b1e502b2e502b3e502b4e502b5e502b6e502b7e502b8e502b9e502bae502bbe502bce502bde502bee502bfe502c0e502c1e502c2e502c3e502c4e502c5e502c6e502c7e502c8e502c9e502cae502cbe502cce502cde502cee502cfe502d0e502d1e502d2e502d3e502d4e502d5e502d6e502d7e502d8e502d9e502dae502dbe502dce502dde502dee502dfe502e0e502e1e502e2e502e3e502e4e502e5e502e6e502e7e502e8e502e9e502eae502ebe502ece502ede502eee502efe502f0e502f1e502f2e502f3e502f4e502f5e502f6e502f7e502f8e502f9e502fae502fbe502fce502fde502fee502ffe50300e50301e50302e50303e50304e50305e50306e50307e50308e50309e5030ae5030be5030ce5030de5030ee5030fe50310e50311e50312e50313e50314e50315e50316e50317e50318e50319e5031ae5031be5031ce5031de5031ee5031fe50320e50321e50322e50323e50324e50325e50326e50327e50328e50329e5032ae5032be5032ce5032de5032ee5032fe50330e50331e50332e50333e50334e50335e50336e50337e50338e50339e5033ae5033be5033ce5033de5033ee5033fe50340e50341e50342e50343e50344e50345e50346e50347e50348e50349e5034ae5034be5034ce5034de5034ee5034fe50350e50351e50352e50353e50354e50355e50356e50357e50358e50359e5035ae5035be5035ce5035de5035ee5035fe50360e50361e50362e50363e50364e50365e50366e50367e50368e50369e5036ae5036be5036ce5036de5036ee5036fe50370e50371e50372e50373e50374e50375e50376e50377e50378e50379e5037ae5037be5037ce5037de5037ee5037fe50380e50381e50382e50383e50384e50385e50386e50387e50388e50389e5038ae5038be5038ce5038de5038ee5038fe50390e50391e50392e50393e50394e50395e50396e50397e50398e50399e5039ae5039be5039ce5039de5039ee5039fe503a0e503a1e503a2e503a3e503a4e503a5e503a6e503a7e503a8e503a9e503aae503abe503ace503ade503aee503afe503b0e503b1e503b2e503b3e503b4e503b5e503b6e503b7e503b8e503b9e503bae503bbe503bce503bde503bee503bfe503c0e503c1e503c2e503c3e503c4e503c5e503c6e503c7e503c8e503c9e503cae503cbe503cce503cde503cee503cfe503d0e503d1e503d2e503d3e503d4e503d5e503d6e503d7e503d8e503d9e503dae503dbe503dce503dde503dee503dfe503e0e503e1e503e2e503e3e503e4e503e5e503e6e503e7e503e8e503e9e503eae503ebe503ece503ede503eee503efe503f0e503f1e503f2e503f3e503f4e503f5e503f6e503f7e503f8e503f9e503fae503fbe503fce503fde503fee503ff5b5b00", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_trailing_bytes.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_trailing_bytes.json new file mode 100644 index 00000000..1c77f092 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_trailing_bytes.json @@ -0,0 +1,24 @@ +{ + "EOF1_trailing_bytes": { + "vectors": { + "EOF1_trailing_bytes_0": { + "code": "0xef000101000402000100010400000000800000fedeadbeef", + "results": { + "Prague": { + "exception": "EOF_InvalidSectionBodiesSize", + "result": false + } + } + }, + "EOF1_trailing_bytes_1": { + "code": "0xef000101000402000100010400020000800000feaabbdeadbeef", + "results": { + "Prague": { + "exception": "EOF_InvalidSectionBodiesSize", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_truncated_push.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_truncated_push.json new file mode 100644 index 00000000..893f226f --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_truncated_push.json @@ -0,0 +1,5014 @@ +{ + "EOF1_truncated_push": { + "vectors": { + "EOF1_truncated_push_0": { + "code": "0xef00010100040200010001040000000080000060", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_1": { + "code": "0xef000101000402000100030400000000800001600000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_10": { + "code": "0xef0001010004020001000204000000008000016300", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_100": { + "code": "0xef0001010004020001000b04000000008000016c00000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_101": { + "code": "0xef0001010004020001000c04000000008000016c0000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_102": { + "code": "0xef0001010004020001000d04000000008000016c000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_103": { + "code": "0xef0001010004020001000f04000000008000016c0000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_104": { + "code": "0xef0001010004020001000104000000008000016d", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_105": { + "code": "0xef0001010004020001000204000000008000016d00", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_106": { + "code": "0xef0001010004020001000304000000008000016d0000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_107": { + "code": "0xef0001010004020001000404000000008000016d000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_108": { + "code": "0xef0001010004020001000504000000008000016d00000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_109": { + "code": "0xef0001010004020001000604000000008000016d0000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_11": { + "code": "0xef000101000402000100030400000000800001630000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_110": { + "code": "0xef0001010004020001000704000000008000016d000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_111": { + "code": "0xef0001010004020001000804000000008000016d00000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_112": { + "code": "0xef0001010004020001000904000000008000016d0000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_113": { + "code": "0xef0001010004020001000a04000000008000016d000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_114": { + "code": "0xef0001010004020001000b04000000008000016d00000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_115": { + "code": "0xef0001010004020001000c04000000008000016d0000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_116": { + "code": "0xef0001010004020001000d04000000008000016d000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_117": { + "code": "0xef0001010004020001000e04000000008000016d00000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_118": { + "code": "0xef0001010004020001001004000000008000016d000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_119": { + "code": "0xef0001010004020001000104000000008000016e", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_12": { + "code": "0xef00010100040200010004040000000080000163000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_120": { + "code": "0xef0001010004020001000204000000008000016e00", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_121": { + "code": "0xef0001010004020001000304000000008000016e0000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_122": { + "code": "0xef0001010004020001000404000000008000016e000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_123": { + "code": "0xef0001010004020001000504000000008000016e00000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_124": { + "code": "0xef0001010004020001000604000000008000016e0000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_125": { + "code": "0xef0001010004020001000704000000008000016e000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_126": { + "code": "0xef0001010004020001000804000000008000016e00000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_127": { + "code": "0xef0001010004020001000904000000008000016e0000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_128": { + "code": "0xef0001010004020001000a04000000008000016e000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_129": { + "code": "0xef0001010004020001000b04000000008000016e00000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_13": { + "code": "0xef000101000402000100060400000000800001630000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_130": { + "code": "0xef0001010004020001000c04000000008000016e0000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_131": { + "code": "0xef0001010004020001000d04000000008000016e000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_132": { + "code": "0xef0001010004020001000e04000000008000016e00000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_133": { + "code": "0xef0001010004020001000f04000000008000016e0000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_134": { + "code": "0xef0001010004020001001104000000008000016e00000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_135": { + "code": "0xef0001010004020001000104000000008000016f", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_136": { + "code": "0xef0001010004020001000204000000008000016f00", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_137": { + "code": "0xef0001010004020001000304000000008000016f0000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_138": { + "code": "0xef0001010004020001000404000000008000016f000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_139": { + "code": "0xef0001010004020001000504000000008000016f00000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_14": { + "code": "0xef00010100040200010001040000000080000164", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_140": { + "code": "0xef0001010004020001000604000000008000016f0000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_141": { + "code": "0xef0001010004020001000704000000008000016f000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_142": { + "code": "0xef0001010004020001000804000000008000016f00000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_143": { + "code": "0xef0001010004020001000904000000008000016f0000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_144": { + "code": "0xef0001010004020001000a04000000008000016f000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_145": { + "code": "0xef0001010004020001000b04000000008000016f00000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_146": { + "code": "0xef0001010004020001000c04000000008000016f0000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_147": { + "code": "0xef0001010004020001000d04000000008000016f000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_148": { + "code": "0xef0001010004020001000e04000000008000016f00000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_149": { + "code": "0xef0001010004020001000f04000000008000016f0000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_15": { + "code": "0xef0001010004020001000204000000008000016400", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_150": { + "code": "0xef0001010004020001001004000000008000016f000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_151": { + "code": "0xef0001010004020001001204000000008000016f0000000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_152": { + "code": "0xef00010100040200010001040000000080000170", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_153": { + "code": "0xef0001010004020001000204000000008000017000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_154": { + "code": "0xef000101000402000100030400000000800001700000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_155": { + "code": "0xef00010100040200010004040000000080000170000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_156": { + "code": "0xef0001010004020001000504000000008000017000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_157": { + "code": "0xef000101000402000100060400000000800001700000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_158": { + "code": "0xef00010100040200010007040000000080000170000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_159": { + "code": "0xef0001010004020001000804000000008000017000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_16": { + "code": "0xef000101000402000100030400000000800001640000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_160": { + "code": "0xef000101000402000100090400000000800001700000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_161": { + "code": "0xef0001010004020001000a040000000080000170000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_162": { + "code": "0xef0001010004020001000b04000000008000017000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_163": { + "code": "0xef0001010004020001000c0400000000800001700000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_164": { + "code": "0xef0001010004020001000d040000000080000170000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_165": { + "code": "0xef0001010004020001000e04000000008000017000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_166": { + "code": "0xef0001010004020001000f0400000000800001700000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_167": { + "code": "0xef00010100040200010010040000000080000170000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_168": { + "code": "0xef0001010004020001001104000000008000017000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_169": { + "code": "0xef00010100040200010013040000000080000170000000000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_17": { + "code": "0xef00010100040200010004040000000080000164000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_170": { + "code": "0xef00010100040200010001040000000080000171", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_171": { + "code": "0xef0001010004020001000204000000008000017100", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_172": { + "code": "0xef000101000402000100030400000000800001710000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_173": { + "code": "0xef00010100040200010004040000000080000171000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_174": { + "code": "0xef0001010004020001000504000000008000017100000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_175": { + "code": "0xef000101000402000100060400000000800001710000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_176": { + "code": "0xef00010100040200010007040000000080000171000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_177": { + "code": "0xef0001010004020001000804000000008000017100000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_178": { + "code": "0xef000101000402000100090400000000800001710000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_179": { + "code": "0xef0001010004020001000a040000000080000171000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_18": { + "code": "0xef0001010004020001000504000000008000016400000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_180": { + "code": "0xef0001010004020001000b04000000008000017100000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_181": { + "code": "0xef0001010004020001000c0400000000800001710000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_182": { + "code": "0xef0001010004020001000d040000000080000171000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_183": { + "code": "0xef0001010004020001000e04000000008000017100000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_184": { + "code": "0xef0001010004020001000f0400000000800001710000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_185": { + "code": "0xef00010100040200010010040000000080000171000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_186": { + "code": "0xef0001010004020001001104000000008000017100000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_187": { + "code": "0xef000101000402000100120400000000800001710000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_188": { + "code": "0xef0001010004020001001404000000008000017100000000000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_189": { + "code": "0xef00010100040200010001040000000080000172", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_19": { + "code": "0xef00010100040200010007040000000080000164000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_190": { + "code": "0xef0001010004020001000204000000008000017200", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_191": { + "code": "0xef000101000402000100030400000000800001720000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_192": { + "code": "0xef00010100040200010004040000000080000172000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_193": { + "code": "0xef0001010004020001000504000000008000017200000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_194": { + "code": "0xef000101000402000100060400000000800001720000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_195": { + "code": "0xef00010100040200010007040000000080000172000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_196": { + "code": "0xef0001010004020001000804000000008000017200000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_197": { + "code": "0xef000101000402000100090400000000800001720000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_198": { + "code": "0xef0001010004020001000a040000000080000172000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_199": { + "code": "0xef0001010004020001000b04000000008000017200000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_2": { + "code": "0xef00010100040200010001040000000080000161", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_20": { + "code": "0xef00010100040200010001040000000080000165", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_200": { + "code": "0xef0001010004020001000c0400000000800001720000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_201": { + "code": "0xef0001010004020001000d040000000080000172000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_202": { + "code": "0xef0001010004020001000e04000000008000017200000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_203": { + "code": "0xef0001010004020001000f0400000000800001720000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_204": { + "code": "0xef00010100040200010010040000000080000172000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_205": { + "code": "0xef0001010004020001001104000000008000017200000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_206": { + "code": "0xef000101000402000100120400000000800001720000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_207": { + "code": "0xef00010100040200010013040000000080000172000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_208": { + "code": "0xef000101000402000100150400000000800001720000000000000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_209": { + "code": "0xef00010100040200010001040000000080000173", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_21": { + "code": "0xef0001010004020001000204000000008000016500", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_210": { + "code": "0xef0001010004020001000204000000008000017300", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_211": { + "code": "0xef000101000402000100030400000000800001730000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_212": { + "code": "0xef00010100040200010004040000000080000173000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_213": { + "code": "0xef0001010004020001000504000000008000017300000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_214": { + "code": "0xef000101000402000100060400000000800001730000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_215": { + "code": "0xef00010100040200010007040000000080000173000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_216": { + "code": "0xef0001010004020001000804000000008000017300000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_217": { + "code": "0xef000101000402000100090400000000800001730000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_218": { + "code": "0xef0001010004020001000a040000000080000173000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_219": { + "code": "0xef0001010004020001000b04000000008000017300000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_22": { + "code": "0xef000101000402000100030400000000800001650000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_220": { + "code": "0xef0001010004020001000c0400000000800001730000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_221": { + "code": "0xef0001010004020001000d040000000080000173000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_222": { + "code": "0xef0001010004020001000e04000000008000017300000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_223": { + "code": "0xef0001010004020001000f0400000000800001730000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_224": { + "code": "0xef00010100040200010010040000000080000173000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_225": { + "code": "0xef0001010004020001001104000000008000017300000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_226": { + "code": "0xef000101000402000100120400000000800001730000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_227": { + "code": "0xef00010100040200010013040000000080000173000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_228": { + "code": "0xef0001010004020001001404000000008000017300000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_229": { + "code": "0xef00010100040200010016040000000080000173000000000000000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_23": { + "code": "0xef00010100040200010004040000000080000165000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_230": { + "code": "0xef00010100040200010001040000000080000174", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_231": { + "code": "0xef0001010004020001000204000000008000017400", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_232": { + "code": "0xef000101000402000100030400000000800001740000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_233": { + "code": "0xef00010100040200010004040000000080000174000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_234": { + "code": "0xef0001010004020001000504000000008000017400000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_235": { + "code": "0xef000101000402000100060400000000800001740000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_236": { + "code": "0xef00010100040200010007040000000080000174000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_237": { + "code": "0xef0001010004020001000804000000008000017400000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_238": { + "code": "0xef000101000402000100090400000000800001740000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_239": { + "code": "0xef0001010004020001000a040000000080000174000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_24": { + "code": "0xef0001010004020001000504000000008000016500000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_240": { + "code": "0xef0001010004020001000b04000000008000017400000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_241": { + "code": "0xef0001010004020001000c0400000000800001740000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_242": { + "code": "0xef0001010004020001000d040000000080000174000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_243": { + "code": "0xef0001010004020001000e04000000008000017400000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_244": { + "code": "0xef0001010004020001000f0400000000800001740000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_245": { + "code": "0xef00010100040200010010040000000080000174000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_246": { + "code": "0xef0001010004020001001104000000008000017400000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_247": { + "code": "0xef000101000402000100120400000000800001740000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_248": { + "code": "0xef00010100040200010013040000000080000174000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_249": { + "code": "0xef0001010004020001001404000000008000017400000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_25": { + "code": "0xef000101000402000100060400000000800001650000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_250": { + "code": "0xef000101000402000100150400000000800001740000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_251": { + "code": "0xef0001010004020001001704000000008000017400000000000000000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_252": { + "code": "0xef00010100040200010001040000000080000175", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_253": { + "code": "0xef0001010004020001000204000000008000017500", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_254": { + "code": "0xef000101000402000100030400000000800001750000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_255": { + "code": "0xef00010100040200010004040000000080000175000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_256": { + "code": "0xef0001010004020001000504000000008000017500000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_257": { + "code": "0xef000101000402000100060400000000800001750000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_258": { + "code": "0xef00010100040200010007040000000080000175000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_259": { + "code": "0xef0001010004020001000804000000008000017500000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_26": { + "code": "0xef0001010004020001000804000000008000016500000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_260": { + "code": "0xef000101000402000100090400000000800001750000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_261": { + "code": "0xef0001010004020001000a040000000080000175000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_262": { + "code": "0xef0001010004020001000b04000000008000017500000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_263": { + "code": "0xef0001010004020001000c0400000000800001750000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_264": { + "code": "0xef0001010004020001000d040000000080000175000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_265": { + "code": "0xef0001010004020001000e04000000008000017500000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_266": { + "code": "0xef0001010004020001000f0400000000800001750000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_267": { + "code": "0xef00010100040200010010040000000080000175000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_268": { + "code": "0xef0001010004020001001104000000008000017500000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_269": { + "code": "0xef000101000402000100120400000000800001750000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_27": { + "code": "0xef00010100040200010001040000000080000166", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_270": { + "code": "0xef00010100040200010013040000000080000175000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_271": { + "code": "0xef0001010004020001001404000000008000017500000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_272": { + "code": "0xef000101000402000100150400000000800001750000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_273": { + "code": "0xef00010100040200010016040000000080000175000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_274": { + "code": "0xef000101000402000100180400000000800001750000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_275": { + "code": "0xef00010100040200010001040000000080000176", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_276": { + "code": "0xef0001010004020001000204000000008000017600", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_277": { + "code": "0xef000101000402000100030400000000800001760000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_278": { + "code": "0xef00010100040200010004040000000080000176000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_279": { + "code": "0xef0001010004020001000504000000008000017600000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_28": { + "code": "0xef0001010004020001000204000000008000016600", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_280": { + "code": "0xef000101000402000100060400000000800001760000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_281": { + "code": "0xef00010100040200010007040000000080000176000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_282": { + "code": "0xef0001010004020001000804000000008000017600000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_283": { + "code": "0xef000101000402000100090400000000800001760000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_284": { + "code": "0xef0001010004020001000a040000000080000176000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_285": { + "code": "0xef0001010004020001000b04000000008000017600000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_286": { + "code": "0xef0001010004020001000c0400000000800001760000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_287": { + "code": "0xef0001010004020001000d040000000080000176000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_288": { + "code": "0xef0001010004020001000e04000000008000017600000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_289": { + "code": "0xef0001010004020001000f0400000000800001760000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_29": { + "code": "0xef000101000402000100030400000000800001660000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_290": { + "code": "0xef00010100040200010010040000000080000176000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_291": { + "code": "0xef0001010004020001001104000000008000017600000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_292": { + "code": "0xef000101000402000100120400000000800001760000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_293": { + "code": "0xef00010100040200010013040000000080000176000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_294": { + "code": "0xef0001010004020001001404000000008000017600000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_295": { + "code": "0xef000101000402000100150400000000800001760000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_296": { + "code": "0xef00010100040200010016040000000080000176000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_297": { + "code": "0xef0001010004020001001704000000008000017600000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_298": { + "code": "0xef00010100040200010019040000000080000176000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_299": { + "code": "0xef00010100040200010001040000000080000177", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_3": { + "code": "0xef0001010004020001000204000000008000016100", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_30": { + "code": "0xef00010100040200010004040000000080000166000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_300": { + "code": "0xef0001010004020001000204000000008000017700", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_301": { + "code": "0xef000101000402000100030400000000800001770000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_302": { + "code": "0xef00010100040200010004040000000080000177000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_303": { + "code": "0xef0001010004020001000504000000008000017700000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_304": { + "code": "0xef000101000402000100060400000000800001770000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_305": { + "code": "0xef00010100040200010007040000000080000177000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_306": { + "code": "0xef0001010004020001000804000000008000017700000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_307": { + "code": "0xef000101000402000100090400000000800001770000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_308": { + "code": "0xef0001010004020001000a040000000080000177000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_309": { + "code": "0xef0001010004020001000b04000000008000017700000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_31": { + "code": "0xef0001010004020001000504000000008000016600000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_310": { + "code": "0xef0001010004020001000c0400000000800001770000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_311": { + "code": "0xef0001010004020001000d040000000080000177000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_312": { + "code": "0xef0001010004020001000e04000000008000017700000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_313": { + "code": "0xef0001010004020001000f0400000000800001770000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_314": { + "code": "0xef00010100040200010010040000000080000177000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_315": { + "code": "0xef0001010004020001001104000000008000017700000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_316": { + "code": "0xef000101000402000100120400000000800001770000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_317": { + "code": "0xef00010100040200010013040000000080000177000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_318": { + "code": "0xef0001010004020001001404000000008000017700000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_319": { + "code": "0xef000101000402000100150400000000800001770000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_32": { + "code": "0xef000101000402000100060400000000800001660000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_320": { + "code": "0xef00010100040200010016040000000080000177000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_321": { + "code": "0xef0001010004020001001704000000008000017700000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_322": { + "code": "0xef000101000402000100180400000000800001770000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_323": { + "code": "0xef0001010004020001001a04000000008000017700000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_324": { + "code": "0xef00010100040200010001040000000080000178", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_325": { + "code": "0xef0001010004020001000204000000008000017800", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_326": { + "code": "0xef000101000402000100030400000000800001780000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_327": { + "code": "0xef00010100040200010004040000000080000178000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_328": { + "code": "0xef0001010004020001000504000000008000017800000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_329": { + "code": "0xef000101000402000100060400000000800001780000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_33": { + "code": "0xef00010100040200010007040000000080000166000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_330": { + "code": "0xef00010100040200010007040000000080000178000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_331": { + "code": "0xef0001010004020001000804000000008000017800000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_332": { + "code": "0xef000101000402000100090400000000800001780000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_333": { + "code": "0xef0001010004020001000a040000000080000178000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_334": { + "code": "0xef0001010004020001000b04000000008000017800000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_335": { + "code": "0xef0001010004020001000c0400000000800001780000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_336": { + "code": "0xef0001010004020001000d040000000080000178000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_337": { + "code": "0xef0001010004020001000e04000000008000017800000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_338": { + "code": "0xef0001010004020001000f0400000000800001780000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_339": { + "code": "0xef00010100040200010010040000000080000178000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_34": { + "code": "0xef000101000402000100090400000000800001660000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_340": { + "code": "0xef0001010004020001001104000000008000017800000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_341": { + "code": "0xef000101000402000100120400000000800001780000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_342": { + "code": "0xef00010100040200010013040000000080000178000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_343": { + "code": "0xef0001010004020001001404000000008000017800000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_344": { + "code": "0xef000101000402000100150400000000800001780000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_345": { + "code": "0xef00010100040200010016040000000080000178000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_346": { + "code": "0xef0001010004020001001704000000008000017800000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_347": { + "code": "0xef000101000402000100180400000000800001780000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_348": { + "code": "0xef00010100040200010019040000000080000178000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_349": { + "code": "0xef0001010004020001001b0400000000800001780000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_35": { + "code": "0xef00010100040200010001040000000080000167", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_350": { + "code": "0xef00010100040200010001040000000080000179", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_351": { + "code": "0xef0001010004020001000204000000008000017900", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_352": { + "code": "0xef000101000402000100030400000000800001790000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_353": { + "code": "0xef00010100040200010004040000000080000179000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_354": { + "code": "0xef0001010004020001000504000000008000017900000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_355": { + "code": "0xef000101000402000100060400000000800001790000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_356": { + "code": "0xef00010100040200010007040000000080000179000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_357": { + "code": "0xef0001010004020001000804000000008000017900000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_358": { + "code": "0xef000101000402000100090400000000800001790000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_359": { + "code": "0xef0001010004020001000a040000000080000179000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_36": { + "code": "0xef0001010004020001000204000000008000016700", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_360": { + "code": "0xef0001010004020001000b04000000008000017900000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_361": { + "code": "0xef0001010004020001000c0400000000800001790000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_362": { + "code": "0xef0001010004020001000d040000000080000179000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_363": { + "code": "0xef0001010004020001000e04000000008000017900000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_364": { + "code": "0xef0001010004020001000f0400000000800001790000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_365": { + "code": "0xef00010100040200010010040000000080000179000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_366": { + "code": "0xef0001010004020001001104000000008000017900000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_367": { + "code": "0xef000101000402000100120400000000800001790000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_368": { + "code": "0xef00010100040200010013040000000080000179000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_369": { + "code": "0xef0001010004020001001404000000008000017900000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_37": { + "code": "0xef000101000402000100030400000000800001670000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_370": { + "code": "0xef000101000402000100150400000000800001790000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_371": { + "code": "0xef00010100040200010016040000000080000179000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_372": { + "code": "0xef0001010004020001001704000000008000017900000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_373": { + "code": "0xef000101000402000100180400000000800001790000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_374": { + "code": "0xef00010100040200010019040000000080000179000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_375": { + "code": "0xef0001010004020001001a04000000008000017900000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_376": { + "code": "0xef0001010004020001001c040000000080000179000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_377": { + "code": "0xef0001010004020001000104000000008000017a", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_378": { + "code": "0xef0001010004020001000204000000008000017a00", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_379": { + "code": "0xef0001010004020001000304000000008000017a0000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_38": { + "code": "0xef00010100040200010004040000000080000167000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_380": { + "code": "0xef0001010004020001000404000000008000017a000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_381": { + "code": "0xef0001010004020001000504000000008000017a00000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_382": { + "code": "0xef0001010004020001000604000000008000017a0000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_383": { + "code": "0xef0001010004020001000704000000008000017a000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_384": { + "code": "0xef0001010004020001000804000000008000017a00000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_385": { + "code": "0xef0001010004020001000904000000008000017a0000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_386": { + "code": "0xef0001010004020001000a04000000008000017a000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_387": { + "code": "0xef0001010004020001000b04000000008000017a00000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_388": { + "code": "0xef0001010004020001000c04000000008000017a0000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_389": { + "code": "0xef0001010004020001000d04000000008000017a000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_39": { + "code": "0xef0001010004020001000504000000008000016700000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_390": { + "code": "0xef0001010004020001000e04000000008000017a00000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_391": { + "code": "0xef0001010004020001000f04000000008000017a0000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_392": { + "code": "0xef0001010004020001001004000000008000017a000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_393": { + "code": "0xef0001010004020001001104000000008000017a00000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_394": { + "code": "0xef0001010004020001001204000000008000017a0000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_395": { + "code": "0xef0001010004020001001304000000008000017a000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_396": { + "code": "0xef0001010004020001001404000000008000017a00000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_397": { + "code": "0xef0001010004020001001504000000008000017a0000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_398": { + "code": "0xef0001010004020001001604000000008000017a000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_399": { + "code": "0xef0001010004020001001704000000008000017a00000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_4": { + "code": "0xef00010100040200010004040000000080000161000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_40": { + "code": "0xef000101000402000100060400000000800001670000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_400": { + "code": "0xef0001010004020001001804000000008000017a0000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_401": { + "code": "0xef0001010004020001001904000000008000017a000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_402": { + "code": "0xef0001010004020001001a04000000008000017a00000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_403": { + "code": "0xef0001010004020001001b04000000008000017a0000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_404": { + "code": "0xef0001010004020001001d04000000008000017a00000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_405": { + "code": "0xef0001010004020001000104000000008000017b", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_406": { + "code": "0xef0001010004020001000204000000008000017b00", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_407": { + "code": "0xef0001010004020001000304000000008000017b0000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_408": { + "code": "0xef0001010004020001000404000000008000017b000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_409": { + "code": "0xef0001010004020001000504000000008000017b00000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_41": { + "code": "0xef00010100040200010007040000000080000167000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_410": { + "code": "0xef0001010004020001000604000000008000017b0000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_411": { + "code": "0xef0001010004020001000704000000008000017b000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_412": { + "code": "0xef0001010004020001000804000000008000017b00000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_413": { + "code": "0xef0001010004020001000904000000008000017b0000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_414": { + "code": "0xef0001010004020001000a04000000008000017b000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_415": { + "code": "0xef0001010004020001000b04000000008000017b00000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_416": { + "code": "0xef0001010004020001000c04000000008000017b0000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_417": { + "code": "0xef0001010004020001000d04000000008000017b000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_418": { + "code": "0xef0001010004020001000e04000000008000017b00000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_419": { + "code": "0xef0001010004020001000f04000000008000017b0000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_42": { + "code": "0xef0001010004020001000804000000008000016700000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_420": { + "code": "0xef0001010004020001001004000000008000017b000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_421": { + "code": "0xef0001010004020001001104000000008000017b00000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_422": { + "code": "0xef0001010004020001001204000000008000017b0000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_423": { + "code": "0xef0001010004020001001304000000008000017b000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_424": { + "code": "0xef0001010004020001001404000000008000017b00000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_425": { + "code": "0xef0001010004020001001504000000008000017b0000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_426": { + "code": "0xef0001010004020001001604000000008000017b000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_427": { + "code": "0xef0001010004020001001704000000008000017b00000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_428": { + "code": "0xef0001010004020001001804000000008000017b0000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_429": { + "code": "0xef0001010004020001001904000000008000017b000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_43": { + "code": "0xef0001010004020001000a040000000080000167000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_430": { + "code": "0xef0001010004020001001a04000000008000017b00000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_431": { + "code": "0xef0001010004020001001b04000000008000017b0000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_432": { + "code": "0xef0001010004020001001c04000000008000017b000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_433": { + "code": "0xef0001010004020001001e04000000008000017b0000000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_434": { + "code": "0xef0001010004020001000104000000008000017c", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_435": { + "code": "0xef0001010004020001000204000000008000017c00", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_436": { + "code": "0xef0001010004020001000304000000008000017c0000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_437": { + "code": "0xef0001010004020001000404000000008000017c000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_438": { + "code": "0xef0001010004020001000504000000008000017c00000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_439": { + "code": "0xef0001010004020001000604000000008000017c0000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_44": { + "code": "0xef00010100040200010001040000000080000168", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_440": { + "code": "0xef0001010004020001000704000000008000017c000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_441": { + "code": "0xef0001010004020001000804000000008000017c00000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_442": { + "code": "0xef0001010004020001000904000000008000017c0000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_443": { + "code": "0xef0001010004020001000a04000000008000017c000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_444": { + "code": "0xef0001010004020001000b04000000008000017c00000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_445": { + "code": "0xef0001010004020001000c04000000008000017c0000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_446": { + "code": "0xef0001010004020001000d04000000008000017c000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_447": { + "code": "0xef0001010004020001000e04000000008000017c00000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_448": { + "code": "0xef0001010004020001000f04000000008000017c0000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_449": { + "code": "0xef0001010004020001001004000000008000017c000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_45": { + "code": "0xef0001010004020001000204000000008000016800", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_450": { + "code": "0xef0001010004020001001104000000008000017c00000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_451": { + "code": "0xef0001010004020001001204000000008000017c0000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_452": { + "code": "0xef0001010004020001001304000000008000017c000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_453": { + "code": "0xef0001010004020001001404000000008000017c00000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_454": { + "code": "0xef0001010004020001001504000000008000017c0000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_455": { + "code": "0xef0001010004020001001604000000008000017c000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_456": { + "code": "0xef0001010004020001001704000000008000017c00000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_457": { + "code": "0xef0001010004020001001804000000008000017c0000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_458": { + "code": "0xef0001010004020001001904000000008000017c000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_459": { + "code": "0xef0001010004020001001a04000000008000017c00000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_46": { + "code": "0xef000101000402000100030400000000800001680000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_460": { + "code": "0xef0001010004020001001b04000000008000017c0000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_461": { + "code": "0xef0001010004020001001c04000000008000017c000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_462": { + "code": "0xef0001010004020001001d04000000008000017c00000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_463": { + "code": "0xef0001010004020001001f04000000008000017c000000000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_464": { + "code": "0xef0001010004020001000104000000008000017d", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_465": { + "code": "0xef0001010004020001000204000000008000017d00", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_466": { + "code": "0xef0001010004020001000304000000008000017d0000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_467": { + "code": "0xef0001010004020001000404000000008000017d000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_468": { + "code": "0xef0001010004020001000504000000008000017d00000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_469": { + "code": "0xef0001010004020001000604000000008000017d0000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_47": { + "code": "0xef00010100040200010004040000000080000168000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_470": { + "code": "0xef0001010004020001000704000000008000017d000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_471": { + "code": "0xef0001010004020001000804000000008000017d00000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_472": { + "code": "0xef0001010004020001000904000000008000017d0000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_473": { + "code": "0xef0001010004020001000a04000000008000017d000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_474": { + "code": "0xef0001010004020001000b04000000008000017d00000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_475": { + "code": "0xef0001010004020001000c04000000008000017d0000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_476": { + "code": "0xef0001010004020001000d04000000008000017d000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_477": { + "code": "0xef0001010004020001000e04000000008000017d00000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_478": { + "code": "0xef0001010004020001000f04000000008000017d0000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_479": { + "code": "0xef0001010004020001001004000000008000017d000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_48": { + "code": "0xef0001010004020001000504000000008000016800000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_480": { + "code": "0xef0001010004020001001104000000008000017d00000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_481": { + "code": "0xef0001010004020001001204000000008000017d0000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_482": { + "code": "0xef0001010004020001001304000000008000017d000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_483": { + "code": "0xef0001010004020001001404000000008000017d00000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_484": { + "code": "0xef0001010004020001001504000000008000017d0000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_485": { + "code": "0xef0001010004020001001604000000008000017d000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_486": { + "code": "0xef0001010004020001001704000000008000017d00000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_487": { + "code": "0xef0001010004020001001804000000008000017d0000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_488": { + "code": "0xef0001010004020001001904000000008000017d000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_489": { + "code": "0xef0001010004020001001a04000000008000017d00000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_49": { + "code": "0xef000101000402000100060400000000800001680000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_490": { + "code": "0xef0001010004020001001b04000000008000017d0000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_491": { + "code": "0xef0001010004020001001c04000000008000017d000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_492": { + "code": "0xef0001010004020001001d04000000008000017d00000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_493": { + "code": "0xef0001010004020001001e04000000008000017d0000000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_494": { + "code": "0xef0001010004020001002004000000008000017d00000000000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_495": { + "code": "0xef0001010004020001000104000000008000017e", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_496": { + "code": "0xef0001010004020001000204000000008000017e00", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_497": { + "code": "0xef0001010004020001000304000000008000017e0000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_498": { + "code": "0xef0001010004020001000404000000008000017e000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_499": { + "code": "0xef0001010004020001000504000000008000017e00000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_5": { + "code": "0xef00010100040200010001040000000080000162", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_50": { + "code": "0xef00010100040200010007040000000080000168000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_500": { + "code": "0xef0001010004020001000604000000008000017e0000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_501": { + "code": "0xef0001010004020001000704000000008000017e000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_502": { + "code": "0xef0001010004020001000804000000008000017e00000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_503": { + "code": "0xef0001010004020001000904000000008000017e0000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_504": { + "code": "0xef0001010004020001000a04000000008000017e000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_505": { + "code": "0xef0001010004020001000b04000000008000017e00000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_506": { + "code": "0xef0001010004020001000c04000000008000017e0000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_507": { + "code": "0xef0001010004020001000d04000000008000017e000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_508": { + "code": "0xef0001010004020001000e04000000008000017e00000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_509": { + "code": "0xef0001010004020001000f04000000008000017e0000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_51": { + "code": "0xef0001010004020001000804000000008000016800000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_510": { + "code": "0xef0001010004020001001004000000008000017e000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_511": { + "code": "0xef0001010004020001001104000000008000017e00000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_512": { + "code": "0xef0001010004020001001204000000008000017e0000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_513": { + "code": "0xef0001010004020001001304000000008000017e000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_514": { + "code": "0xef0001010004020001001404000000008000017e00000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_515": { + "code": "0xef0001010004020001001504000000008000017e0000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_516": { + "code": "0xef0001010004020001001604000000008000017e000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_517": { + "code": "0xef0001010004020001001704000000008000017e00000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_518": { + "code": "0xef0001010004020001001804000000008000017e0000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_519": { + "code": "0xef0001010004020001001904000000008000017e000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_52": { + "code": "0xef000101000402000100090400000000800001680000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_520": { + "code": "0xef0001010004020001001a04000000008000017e00000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_521": { + "code": "0xef0001010004020001001b04000000008000017e0000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_522": { + "code": "0xef0001010004020001001c04000000008000017e000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_523": { + "code": "0xef0001010004020001001d04000000008000017e00000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_524": { + "code": "0xef0001010004020001001e04000000008000017e0000000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_525": { + "code": "0xef0001010004020001001f04000000008000017e000000000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_526": { + "code": "0xef0001010004020001002104000000008000017e0000000000000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_527": { + "code": "0xef0001010004020001000104000000008000017f", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_528": { + "code": "0xef0001010004020001000204000000008000017f00", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_529": { + "code": "0xef0001010004020001000304000000008000017f0000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_53": { + "code": "0xef0001010004020001000b04000000008000016800000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_530": { + "code": "0xef0001010004020001000404000000008000017f000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_531": { + "code": "0xef0001010004020001000504000000008000017f00000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_532": { + "code": "0xef0001010004020001000604000000008000017f0000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_533": { + "code": "0xef0001010004020001000704000000008000017f000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_534": { + "code": "0xef0001010004020001000804000000008000017f00000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_535": { + "code": "0xef0001010004020001000904000000008000017f0000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_536": { + "code": "0xef0001010004020001000a04000000008000017f000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_537": { + "code": "0xef0001010004020001000b04000000008000017f00000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_538": { + "code": "0xef0001010004020001000c04000000008000017f0000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_539": { + "code": "0xef0001010004020001000d04000000008000017f000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_54": { + "code": "0xef00010100040200010001040000000080000169", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_540": { + "code": "0xef0001010004020001000e04000000008000017f00000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_541": { + "code": "0xef0001010004020001000f04000000008000017f0000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_542": { + "code": "0xef0001010004020001001004000000008000017f000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_543": { + "code": "0xef0001010004020001001104000000008000017f00000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_544": { + "code": "0xef0001010004020001001204000000008000017f0000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_545": { + "code": "0xef0001010004020001001304000000008000017f000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_546": { + "code": "0xef0001010004020001001404000000008000017f00000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_547": { + "code": "0xef0001010004020001001504000000008000017f0000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_548": { + "code": "0xef0001010004020001001604000000008000017f000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_549": { + "code": "0xef0001010004020001001704000000008000017f00000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_55": { + "code": "0xef0001010004020001000204000000008000016900", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_550": { + "code": "0xef0001010004020001001804000000008000017f0000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_551": { + "code": "0xef0001010004020001001904000000008000017f000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_552": { + "code": "0xef0001010004020001001a04000000008000017f00000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_553": { + "code": "0xef0001010004020001001b04000000008000017f0000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_554": { + "code": "0xef0001010004020001001c04000000008000017f000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_555": { + "code": "0xef0001010004020001001d04000000008000017f00000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_556": { + "code": "0xef0001010004020001001e04000000008000017f0000000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_557": { + "code": "0xef0001010004020001001f04000000008000017f000000000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_558": { + "code": "0xef0001010004020001002004000000008000017f00000000000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_559": { + "code": "0xef0001010004020001002204000000008000017f000000000000000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_56": { + "code": "0xef000101000402000100030400000000800001690000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_57": { + "code": "0xef00010100040200010004040000000080000169000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_58": { + "code": "0xef0001010004020001000504000000008000016900000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_59": { + "code": "0xef000101000402000100060400000000800001690000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_6": { + "code": "0xef0001010004020001000204000000008000016200", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_60": { + "code": "0xef00010100040200010007040000000080000169000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_61": { + "code": "0xef0001010004020001000804000000008000016900000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_62": { + "code": "0xef000101000402000100090400000000800001690000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_63": { + "code": "0xef0001010004020001000a040000000080000169000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_64": { + "code": "0xef0001010004020001000c0400000000800001690000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_65": { + "code": "0xef0001010004020001000104000000008000016a", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_66": { + "code": "0xef0001010004020001000204000000008000016a00", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_67": { + "code": "0xef0001010004020001000304000000008000016a0000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_68": { + "code": "0xef0001010004020001000404000000008000016a000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_69": { + "code": "0xef0001010004020001000504000000008000016a00000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_7": { + "code": "0xef000101000402000100030400000000800001620000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_70": { + "code": "0xef0001010004020001000604000000008000016a0000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_71": { + "code": "0xef0001010004020001000704000000008000016a000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_72": { + "code": "0xef0001010004020001000804000000008000016a00000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_73": { + "code": "0xef0001010004020001000904000000008000016a0000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_74": { + "code": "0xef0001010004020001000a04000000008000016a000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_75": { + "code": "0xef0001010004020001000b04000000008000016a00000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_76": { + "code": "0xef0001010004020001000d04000000008000016a000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_77": { + "code": "0xef0001010004020001000104000000008000016b", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_78": { + "code": "0xef0001010004020001000204000000008000016b00", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_79": { + "code": "0xef0001010004020001000304000000008000016b0000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_8": { + "code": "0xef0001010004020001000504000000008000016200000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_80": { + "code": "0xef0001010004020001000404000000008000016b000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_81": { + "code": "0xef0001010004020001000504000000008000016b00000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_82": { + "code": "0xef0001010004020001000604000000008000016b0000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_83": { + "code": "0xef0001010004020001000704000000008000016b000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_84": { + "code": "0xef0001010004020001000804000000008000016b00000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_85": { + "code": "0xef0001010004020001000904000000008000016b0000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_86": { + "code": "0xef0001010004020001000a04000000008000016b000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_87": { + "code": "0xef0001010004020001000b04000000008000016b00000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_88": { + "code": "0xef0001010004020001000c04000000008000016b0000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_89": { + "code": "0xef0001010004020001000e04000000008000016b00000000000000000000000000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_push_9": { + "code": "0xef00010100040200010001040000000080000163", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_90": { + "code": "0xef0001010004020001000104000000008000016c", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_91": { + "code": "0xef0001010004020001000204000000008000016c00", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_92": { + "code": "0xef0001010004020001000304000000008000016c0000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_93": { + "code": "0xef0001010004020001000404000000008000016c000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_94": { + "code": "0xef0001010004020001000504000000008000016c00000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_95": { + "code": "0xef0001010004020001000604000000008000016c0000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_96": { + "code": "0xef0001010004020001000704000000008000016c000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_97": { + "code": "0xef0001010004020001000804000000008000016c00000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_98": { + "code": "0xef0001010004020001000904000000008000016c0000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + }, + "EOF1_truncated_push_99": { + "code": "0xef0001010004020001000a04000000008000016c000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TruncatedImmediate", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_truncated_section.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_truncated_section.json new file mode 100644 index 00000000..66305988 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_truncated_section.json @@ -0,0 +1,49 @@ +{ + "EOF1_truncated_section": { + "vectors": { + "EOF1_truncated_section_0": { + "code": "0xef0001010004020001000204000000", + "results": { + "Prague": { + "exception": "EOF_InvalidSectionBodiesSize", + "result": false + } + } + }, + "EOF1_truncated_section_1": { + "code": "0xef0001010004020001000204000000008000", + "results": { + "Prague": { + "exception": "EOF_InvalidSectionBodiesSize", + "result": false + } + } + }, + "EOF1_truncated_section_2": { + "code": "0xef000101000402000100020400000000800000fe", + "results": { + "Prague": { + "exception": "EOF_InvalidSectionBodiesSize", + "result": false + } + } + }, + "EOF1_truncated_section_3": { + "code": "0xef000101000402000100010400020000800000fe", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_truncated_section_4": { + "code": "0xef000101000402000100010400020000800000feaa", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_type_section_missing.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_type_section_missing.json new file mode 100644 index 00000000..c91d4ac5 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_type_section_missing.json @@ -0,0 +1,33 @@ +{ + "EOF1_type_section_missing": { + "vectors": { + "EOF1_type_section_missing_0": { + "code": "0xef0001020001000100fe", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + }, + "EOF1_type_section_missing_1": { + "code": "0xef0001020001000103000100feda", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + }, + "EOF1_type_section_missing_2": { + "code": "0xef000100", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_type_section_not_first.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_type_section_not_first.json new file mode 100644 index 00000000..fa9d8475 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_type_section_not_first.json @@ -0,0 +1,42 @@ +{ + "EOF1_type_section_not_first": { + "vectors": { + "EOF1_type_section_not_first_0": { + "code": "0xef0001020001000101000400fe00800000", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + }, + "EOF1_type_section_not_first_1": { + "code": "0xef00010200020001000101000400fefe00800000", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + }, + "EOF1_type_section_not_first_2": { + "code": "0xef0001020001000101000404000300fe00800000aabbcc", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + }, + "EOF1_type_section_not_first_3": { + "code": "0xef0001020001000104000301000400feaabbcc00800000", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_types_section_0_size.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_types_section_0_size.json new file mode 100644 index 00000000..9f2cc366 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_types_section_0_size.json @@ -0,0 +1,24 @@ +{ + "EOF1_types_section_0_size": { + "vectors": { + "EOF1_types_section_0_size_0": { + "code": "0xef0001010000020001000100fe", + "results": { + "Prague": { + "exception": "EOF_ZeroSectionSize", + "result": false + } + } + }, + "EOF1_types_section_0_size_1": { + "code": "0xef0001010000020001000104000100feda", + "results": { + "Prague": { + "exception": "EOF_ZeroSectionSize", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_types_section_missing.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_types_section_missing.json new file mode 100644 index 00000000..a82c85ba --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_types_section_missing.json @@ -0,0 +1,24 @@ +{ + "EOF1_types_section_missing": { + "vectors": { + "EOF1_types_section_missing_0": { + "code": "0xef0001020001000100fe", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + }, + "EOF1_types_section_missing_1": { + "code": "0xef0001020001000104000100feda", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_undefined_opcodes.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_undefined_opcodes.json new file mode 100644 index 00000000..ae4289f8 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_undefined_opcodes.json @@ -0,0 +1,1677 @@ +{ + "EOF1_undefined_opcodes": { + "vectors": { + "EOF1_undefined_opcodes_0": { + "code": "0xef00010100040200010013040000000080001160018080808080808080808080808080808000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_1": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080800100", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_10": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080800a00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_100": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080808d00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_101": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080808e00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_102": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080808f00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_103": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080809000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_104": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080809100", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_105": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080809200", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_106": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080809300", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_107": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080809400", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_108": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080809500", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_109": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080809600", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_11": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080800b00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_110": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080809700", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_111": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080809800", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_112": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080809900", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_113": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080809a00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_114": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080809b00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_115": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080809c00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_116": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080809d00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_117": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080809e00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_118": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080809f00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_119": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080a000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_12": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080800c00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_120": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080a100", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_121": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080a200", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_122": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080a300", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_123": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080a400", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_124": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080a500", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_125": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080a600", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_126": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080a700", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_127": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080a800", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_128": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080a900", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_129": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080aa00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_13": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080800d00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_130": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080ab00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_131": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080ac00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_132": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080ad00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_133": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080ae00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_134": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080af00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_135": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080b000", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_136": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080b100", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_137": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080b200", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_138": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080b300", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_139": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080b400", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_14": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080800e00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_140": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080b500", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_141": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080b600", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_142": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080b700", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_143": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080b800", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_144": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080b900", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_145": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080ba00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_146": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080bb00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_147": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080bc00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_148": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080bd00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_149": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080be00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_15": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080800f00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_150": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080bf00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_151": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080c000", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_152": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080c100", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_153": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080c200", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_154": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080c300", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_155": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080c400", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_156": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080c500", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_157": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080c600", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_158": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080c700", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_159": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080c800", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_16": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080801000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_160": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080c900", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_161": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080ca00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_162": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080cb00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_163": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080cc00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_164": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080cd00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_165": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080ce00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_166": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080cf00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_167": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080d000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_168": { + "code": "0xef000101000402000100140400000000800012600180808080808080808080808080808080d200", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_169": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080d300", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_17": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080801100", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_170": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080d400", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_171": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080d500", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_172": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080d600", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_173": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080d700", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_174": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080d800", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_175": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080d900", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_176": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080da00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_177": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080db00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_178": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080dc00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_179": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080dd00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_18": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080801200", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_180": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080de00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_181": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080df00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_182": { + "code": "0xef000101000802000200040001040000000080000000000000e3000100e4", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_183": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080e900", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_184": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080ea00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_185": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080eb00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_186": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080ed00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_187": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080ef00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_188": { + "code": "0xef000101000402000100130400000000800011600180808080808080808080808080808080f3", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_189": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080f600", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_19": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080801300", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_190": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080f700", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_191": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080f800", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_192": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080f900", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_193": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080fb00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_194": { + "code": "0xef000101000402000100140400000000800011600180808080808080808080808080808080fc00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_195": { + "code": "0xef000101000402000100130400000000800011600180808080808080808080808080808080fd", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_196": { + "code": "0xef000101000402000100130400000000800011600180808080808080808080808080808080fe", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_197": { + "code": "0xef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_2": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080800200", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_20": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080801400", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_21": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080801500", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_22": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080801600", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_23": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080801700", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_24": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080801800", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_25": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080801900", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_26": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080801a00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_27": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080801b00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_28": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080801c00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_29": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080801d00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_3": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080800300", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_30": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080801e00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_31": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080801f00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_32": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080802000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_33": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080802100", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_34": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080802200", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_35": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080802300", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_36": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080802400", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_37": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080802500", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_38": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080802600", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_39": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080802700", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_4": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080800400", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_40": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080802800", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_41": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080802900", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_42": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080802a00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_43": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080802b00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_44": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080802c00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_45": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080802d00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_46": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080802e00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_47": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080802f00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_48": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080803000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_49": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080803100", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_5": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080800500", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_50": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080803200", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_51": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080803300", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_52": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080803400", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_53": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080803500", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_54": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080803600", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_55": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080803700", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_56": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080803a00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_57": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080803d00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_58": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080803e00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_59": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080804000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_6": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080800600", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_60": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080804100", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_61": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080804200", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_62": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080804300", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_63": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080804400", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_64": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080804500", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_65": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080804600", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_66": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080804700", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_67": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080804800", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_68": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080804900", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_69": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080804a00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_7": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080800700", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_70": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080804b00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_71": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080804c00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_72": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080804d00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_73": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080804e00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_74": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080804f00", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "EOF1_undefined_opcodes_75": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080805000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_76": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080805100", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_77": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080805200", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_78": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080805300", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_79": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080805400", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_8": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080800800", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_80": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080805500", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_81": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080805900", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_82": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080805b00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_83": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080805c00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_84": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080805d00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_85": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080805e00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_86": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080805f00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_87": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080808000", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_88": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080808100", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_89": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080808200", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_9": { + "code": "0xef0001010004020001001404000000008000116001808080808080808080808080808080800900", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_90": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080808300", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_91": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080808400", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_92": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080808500", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_93": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080808600", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_94": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080808700", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_95": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080808800", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_96": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080808900", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_97": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080808a00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_98": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080808b00", + "results": { + "Prague": { + "result": true + } + } + }, + "EOF1_undefined_opcodes_99": { + "code": "0xef0001010004020001001404000000008000126001808080808080808080808080808080808c00", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_unknown_section.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_unknown_section.json new file mode 100644 index 00000000..4c15cc70 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_unknown_section.json @@ -0,0 +1,60 @@ +{ + "EOF1_unknown_section": { + "vectors": { + "EOF1_unknown_section_0": { + "code": "0xef000105000100fe", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + }, + "EOF1_unknown_section_1": { + "code": "0xef0001ff000100fe", + "results": { + "Prague": { + "exception": "EOF_TypeSectionMissing", + "result": false + } + } + }, + "EOF1_unknown_section_2": { + "code": "0xef000101000402000100010500010000800000fe00", + "results": { + "Prague": { + "exception": "EOF_DataSectionMissing", + "result": false + } + } + }, + "EOF1_unknown_section_3": { + "code": "0xef00010100040200010001ff00010000800000fe00", + "results": { + "Prague": { + "exception": "EOF_DataSectionMissing", + "result": false + } + } + }, + "EOF1_unknown_section_4": { + "code": "0xef000101000402000100010400010500010000800000feaa00", + "results": { + "Prague": { + "exception": "EOF_HeaderTerminatorMissing", + "result": false + } + } + }, + "EOF1_unknown_section_5": { + "code": "0xef00010100040200010001040001ff00010000800000feaa00", + "results": { + "Prague": { + "exception": "EOF_HeaderTerminatorMissing", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_valid_rjump.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_valid_rjump.json new file mode 100644 index 00000000..63091929 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_valid_rjump.json @@ -0,0 +1,30 @@ +{ + "EOF1_valid_rjump": { + "vectors": { + "offset_negative": { + "code": "0xef0001010004020001000404000000008000005be0fffc", + "results": { + "Prague": { + "result": true + } + } + }, + "offset_positive": { + "code": "0xef0001010004020001000d04000000008000025fe100055f5fe000035f600100", + "results": { + "Prague": { + "result": true + } + } + }, + "offset_zero": { + "code": "0xef000101000402000100040400000000800000e0000000", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_valid_rjumpi.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_valid_rjumpi.json new file mode 100644 index 00000000..fe3b175a --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_valid_rjumpi.json @@ -0,0 +1,30 @@ +{ + "EOF1_valid_rjumpi": { + "vectors": { + "offset_negative": { + "code": "0xef0001010004020001000604000000008000016000e1fffb00", + "results": { + "Prague": { + "result": true + } + } + }, + "offset_positive": { + "code": "0xef0001010004020001000904000000008000016000e100035b5b5b00", + "results": { + "Prague": { + "result": true + } + } + }, + "offset_zero": { + "code": "0xef0001010004020001000604000000008000016000e1000000", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/EOF1_valid_rjumpv.json b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_valid_rjumpv.json new file mode 100644 index 00000000..774f82ca --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/EOF1_valid_rjumpv.json @@ -0,0 +1,38 @@ +{ + "EOF1_valid_rjumpv": { + "vectors": { + "single_entry_case_0": { + "code": "0xef0001010004020001000904000000008000016000e2000000600100", + "results": { + "Prague": { + "result": true + } + } + }, + "three_entries_case_2": { + "code": "0xef0001010004020001001004000000008000016002e20200000003fff6600100600200", + "results": { + "Prague": { + "result": true + } + } + }, + "two_entries_case_0": { + "code": "0xef0001010004020001000e04000000008000016000e20100000003600100600200", + "results": { + "Prague": { + "result": true + } + } + }, + "two_entries_case_2": { + "code": "0xef0001010004020001000e04000000008000016002e20100000003600100600200", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/callf_into_nonreturning.json b/crates/interpreter/tests/EOFTests/eof_validation/callf_into_nonreturning.json new file mode 100644 index 00000000..f753f692 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/callf_into_nonreturning.json @@ -0,0 +1,15 @@ +{ + "callf_into_nonreturning": { + "vectors": { + "callf_into_nonreturning_0": { + "code": "0xef000101000802000200040001040000000080000000800000e300010000", + "results": { + "Prague": { + "exception": "EOF_CallfToNonReturningFunction", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/callf_invalid_code_section_index.json b/crates/interpreter/tests/EOFTests/eof_validation/callf_invalid_code_section_index.json new file mode 100644 index 00000000..f934ccab --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/callf_invalid_code_section_index.json @@ -0,0 +1,15 @@ +{ + "callf_invalid_code_section_index": { + "vectors": { + "callf_invalid_code_section_index_0": { + "code": "0xef000101000402000100040400000000800000e3000100", + "results": { + "Prague": { + "exception": "EOF_InvalidCodeSectionIndex", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/data_section_missing.json b/crates/interpreter/tests/EOFTests/eof_validation/data_section_missing.json new file mode 100644 index 00000000..19479cd6 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/data_section_missing.json @@ -0,0 +1,15 @@ +{ + "data_section_missing": { + "vectors": { + "data_section_missing_0": { + "code": "0xef000101000402000100010000800000fe", + "results": { + "Prague": { + "exception": "EOF_DataSectionMissing", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/dataloadn.json b/crates/interpreter/tests/EOFTests/eof_validation/dataloadn.json new file mode 100644 index 00000000..14724fd6 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/dataloadn.json @@ -0,0 +1,75 @@ +{ + "dataloadn": { + "vectors": { + "dataloadn_0": { + "code": "0xef000101000402000100050400200000800001d1000050000000000000000000111111111111111122222222222222223333333333333333", + "results": { + "Prague": { + "result": true + } + } + }, + "dataloadn_1": { + "code": "0xef000101000402000100050400210000800001d100015000000000000000000011111111111111112222222222222222333333333333333344", + "results": { + "Prague": { + "result": true + } + } + }, + "dataloadn_2": { + "code": "0xef000101000402000100050400400000800001d10020500000000000000000001111111111111111222222222222222233333333333333330000000000000000111111111111111122222222222222223333333333333333", + "results": { + "Prague": { + "result": true + } + } + }, + "dataloadn_3": { + "code": "0xef000101000402000100050400000000800001d100005000", + "results": { + "Prague": { + "exception": "EOF_InvalidDataloadnIndex", + "result": false + } + } + }, + "dataloadn_4": { + "code": "0xef000101000402000100050400010000800001d10001500000", + "results": { + "Prague": { + "exception": "EOF_InvalidDataloadnIndex", + "result": false + } + } + }, + "dataloadn_5": { + "code": "0xef000101000402000100050400200000800001d1002050000000000000000000111111111111111122222222222222223333333333333333", + "results": { + "Prague": { + "exception": "EOF_InvalidDataloadnIndex", + "result": false + } + } + }, + "dataloadn_6": { + "code": "0xef000101000402000100050400200000800001d1ffff50000000000000000000111111111111111122222222222222223333333333333333", + "results": { + "Prague": { + "exception": "EOF_InvalidDataloadnIndex", + "result": false + } + } + }, + "dataloadn_7": { + "code": "0xef0001010004020001000504003f0000800001d100205000000000000000000011111111111111112222222222222222333333333333333300000000000000001111111111111111222222222222222233333333333333", + "results": { + "Prague": { + "exception": "EOF_InvalidDataloadnIndex", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/deprecated_instructions.json b/crates/interpreter/tests/EOFTests/eof_validation/deprecated_instructions.json new file mode 100644 index 00000000..3da47115 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/deprecated_instructions.json @@ -0,0 +1,150 @@ +{ + "deprecated_instructions": { + "vectors": { + "deprecated_instructions_0": { + "code": "0xef000101000402000100010400000000800000f2", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "deprecated_instructions_1": { + "code": "0xef000101000402000100010400000000800000ff", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "deprecated_instructions_10": { + "code": "0xef00010100040200010001040000000080000038", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "deprecated_instructions_11": { + "code": "0xef00010100040200010001040000000080000039", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "deprecated_instructions_12": { + "code": "0xef0001010004020001000104000000008000003b", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "deprecated_instructions_13": { + "code": "0xef0001010004020001000104000000008000003c", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "deprecated_instructions_14": { + "code": "0xef0001010004020001000104000000008000003f", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "deprecated_instructions_15": { + "code": "0xef0001010004020001000104000000008000005a", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "deprecated_instructions_2": { + "code": "0xef00010100040200010001040000000080000056", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "deprecated_instructions_3": { + "code": "0xef00010100040200010001040000000080000057", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "deprecated_instructions_4": { + "code": "0xef00010100040200010001040000000080000058", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "deprecated_instructions_5": { + "code": "0xef000101000402000100010400000000800000f1", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "deprecated_instructions_6": { + "code": "0xef000101000402000100010400000000800000fa", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "deprecated_instructions_7": { + "code": "0xef000101000402000100010400000000800000f4", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "deprecated_instructions_8": { + "code": "0xef000101000402000100010400000000800000f0", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + }, + "deprecated_instructions_9": { + "code": "0xef000101000402000100010400000000800000f5", + "results": { + "Prague": { + "exception": "EOF_UndefinedInstruction", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/incomplete_section_size.json b/crates/interpreter/tests/EOFTests/eof_validation/incomplete_section_size.json new file mode 100644 index 00000000..9cc794d5 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/incomplete_section_size.json @@ -0,0 +1,15 @@ +{ + "incomplete_section_size": { + "vectors": { + "incomplete_section_size_0": { + "code": "0xef000101010002003f0100", + "results": { + "Prague": { + "exception": "EOF_IncompleteSectionSize", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/jumpf_compatible_outputs.json b/crates/interpreter/tests/EOFTests/eof_validation/jumpf_compatible_outputs.json new file mode 100644 index 00000000..4fab55d4 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/jumpf_compatible_outputs.json @@ -0,0 +1,14 @@ +{ + "jumpf_compatible_outputs": { + "vectors": { + "jumpf_compatible_outputs_0": { + "code": "0xef000101000c02000300040005000404000000008000050005000200030003e30001005f5fe500025f5f5fe4", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/jumpf_equal_outputs.json b/crates/interpreter/tests/EOFTests/eof_validation/jumpf_equal_outputs.json new file mode 100644 index 00000000..b9aba3a0 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/jumpf_equal_outputs.json @@ -0,0 +1,14 @@ +{ + "jumpf_equal_outputs": { + "vectors": { + "jumpf_equal_outputs_0": { + "code": "0xef000101000c02000300040003000404000000008000030003000000030003e3000100e500025f5f5fe4", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/jumpf_incompatible_outputs.json b/crates/interpreter/tests/EOFTests/eof_validation/jumpf_incompatible_outputs.json new file mode 100644 index 00000000..b79ea57b --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/jumpf_incompatible_outputs.json @@ -0,0 +1,15 @@ +{ + "jumpf_incompatible_outputs": { + "vectors": { + "jumpf_incompatible_outputs_0": { + "code": "0xef000101000c02000300040005000404000000008000030003000200050003e3000100e500025f5f5f5f5fe4", + "results": { + "Prague": { + "exception": "EOF_JumpfDestinationIncompatibleOutputs", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/many_code_sections_1023.json b/crates/interpreter/tests/EOFTests/eof_validation/many_code_sections_1023.json new file mode 100644 index 00000000..05c74681 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/many_code_sections_1023.json @@ -0,0 +1,14 @@ +{ + "many_code_sections_1023": { + "vectors": { + "many_code_sections_1023_0": { + "code": "0xef0001010ffc0203ff00030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000304000000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000e50001e50002e50003e50004e50005e50006e50007e50008e50009e5000ae5000be5000ce5000de5000ee5000fe50010e50011e50012e50013e50014e50015e50016e50017e50018e50019e5001ae5001be5001ce5001de5001ee5001fe50020e50021e50022e50023e50024e50025e50026e50027e50028e50029e5002ae5002be5002ce5002de5002ee5002fe50030e50031e50032e50033e50034e50035e50036e50037e50038e50039e5003ae5003be5003ce5003de5003ee5003fe50040e50041e50042e50043e50044e50045e50046e50047e50048e50049e5004ae5004be5004ce5004de5004ee5004fe50050e50051e50052e50053e50054e50055e50056e50057e50058e50059e5005ae5005be5005ce5005de5005ee5005fe50060e50061e50062e50063e50064e50065e50066e50067e50068e50069e5006ae5006be5006ce5006de5006ee5006fe50070e50071e50072e50073e50074e50075e50076e50077e50078e50079e5007ae5007be5007ce5007de5007ee5007fe50080e50081e50082e50083e50084e50085e50086e50087e50088e50089e5008ae5008be5008ce5008de5008ee5008fe50090e50091e50092e50093e50094e50095e50096e50097e50098e50099e5009ae5009be5009ce5009de5009ee5009fe500a0e500a1e500a2e500a3e500a4e500a5e500a6e500a7e500a8e500a9e500aae500abe500ace500ade500aee500afe500b0e500b1e500b2e500b3e500b4e500b5e500b6e500b7e500b8e500b9e500bae500bbe500bce500bde500bee500bfe500c0e500c1e500c2e500c3e500c4e500c5e500c6e500c7e500c8e500c9e500cae500cbe500cce500cde500cee500cfe500d0e500d1e500d2e500d3e500d4e500d5e500d6e500d7e500d8e500d9e500dae500dbe500dce500dde500dee500dfe500e0e500e1e500e2e500e3e500e4e500e5e500e6e500e7e500e8e500e9e500eae500ebe500ece500ede500eee500efe500f0e500f1e500f2e500f3e500f4e500f5e500f6e500f7e500f8e500f9e500fae500fbe500fce500fde500fee500ffe50100e50101e50102e50103e50104e50105e50106e50107e50108e50109e5010ae5010be5010ce5010de5010ee5010fe50110e50111e50112e50113e50114e50115e50116e50117e50118e50119e5011ae5011be5011ce5011de5011ee5011fe50120e50121e50122e50123e50124e50125e50126e50127e50128e50129e5012ae5012be5012ce5012de5012ee5012fe50130e50131e50132e50133e50134e50135e50136e50137e50138e50139e5013ae5013be5013ce5013de5013ee5013fe50140e50141e50142e50143e50144e50145e50146e50147e50148e50149e5014ae5014be5014ce5014de5014ee5014fe50150e50151e50152e50153e50154e50155e50156e50157e50158e50159e5015ae5015be5015ce5015de5015ee5015fe50160e50161e50162e50163e50164e50165e50166e50167e50168e50169e5016ae5016be5016ce5016de5016ee5016fe50170e50171e50172e50173e50174e50175e50176e50177e50178e50179e5017ae5017be5017ce5017de5017ee5017fe50180e50181e50182e50183e50184e50185e50186e50187e50188e50189e5018ae5018be5018ce5018de5018ee5018fe50190e50191e50192e50193e50194e50195e50196e50197e50198e50199e5019ae5019be5019ce5019de5019ee5019fe501a0e501a1e501a2e501a3e501a4e501a5e501a6e501a7e501a8e501a9e501aae501abe501ace501ade501aee501afe501b0e501b1e501b2e501b3e501b4e501b5e501b6e501b7e501b8e501b9e501bae501bbe501bce501bde501bee501bfe501c0e501c1e501c2e501c3e501c4e501c5e501c6e501c7e501c8e501c9e501cae501cbe501cce501cde501cee501cfe501d0e501d1e501d2e501d3e501d4e501d5e501d6e501d7e501d8e501d9e501dae501dbe501dce501dde501dee501dfe501e0e501e1e501e2e501e3e501e4e501e5e501e6e501e7e501e8e501e9e501eae501ebe501ece501ede501eee501efe501f0e501f1e501f2e501f3e501f4e501f5e501f6e501f7e501f8e501f9e501fae501fbe501fce501fde501fee501ffe50200e50201e50202e50203e50204e50205e50206e50207e50208e50209e5020ae5020be5020ce5020de5020ee5020fe50210e50211e50212e50213e50214e50215e50216e50217e50218e50219e5021ae5021be5021ce5021de5021ee5021fe50220e50221e50222e50223e50224e50225e50226e50227e50228e50229e5022ae5022be5022ce5022de5022ee5022fe50230e50231e50232e50233e50234e50235e50236e50237e50238e50239e5023ae5023be5023ce5023de5023ee5023fe50240e50241e50242e50243e50244e50245e50246e50247e50248e50249e5024ae5024be5024ce5024de5024ee5024fe50250e50251e50252e50253e50254e50255e50256e50257e50258e50259e5025ae5025be5025ce5025de5025ee5025fe50260e50261e50262e50263e50264e50265e50266e50267e50268e50269e5026ae5026be5026ce5026de5026ee5026fe50270e50271e50272e50273e50274e50275e50276e50277e50278e50279e5027ae5027be5027ce5027de5027ee5027fe50280e50281e50282e50283e50284e50285e50286e50287e50288e50289e5028ae5028be5028ce5028de5028ee5028fe50290e50291e50292e50293e50294e50295e50296e50297e50298e50299e5029ae5029be5029ce5029de5029ee5029fe502a0e502a1e502a2e502a3e502a4e502a5e502a6e502a7e502a8e502a9e502aae502abe502ace502ade502aee502afe502b0e502b1e502b2e502b3e502b4e502b5e502b6e502b7e502b8e502b9e502bae502bbe502bce502bde502bee502bfe502c0e502c1e502c2e502c3e502c4e502c5e502c6e502c7e502c8e502c9e502cae502cbe502cce502cde502cee502cfe502d0e502d1e502d2e502d3e502d4e502d5e502d6e502d7e502d8e502d9e502dae502dbe502dce502dde502dee502dfe502e0e502e1e502e2e502e3e502e4e502e5e502e6e502e7e502e8e502e9e502eae502ebe502ece502ede502eee502efe502f0e502f1e502f2e502f3e502f4e502f5e502f6e502f7e502f8e502f9e502fae502fbe502fce502fde502fee502ffe50300e50301e50302e50303e50304e50305e50306e50307e50308e50309e5030ae5030be5030ce5030de5030ee5030fe50310e50311e50312e50313e50314e50315e50316e50317e50318e50319e5031ae5031be5031ce5031de5031ee5031fe50320e50321e50322e50323e50324e50325e50326e50327e50328e50329e5032ae5032be5032ce5032de5032ee5032fe50330e50331e50332e50333e50334e50335e50336e50337e50338e50339e5033ae5033be5033ce5033de5033ee5033fe50340e50341e50342e50343e50344e50345e50346e50347e50348e50349e5034ae5034be5034ce5034de5034ee5034fe50350e50351e50352e50353e50354e50355e50356e50357e50358e50359e5035ae5035be5035ce5035de5035ee5035fe50360e50361e50362e50363e50364e50365e50366e50367e50368e50369e5036ae5036be5036ce5036de5036ee5036fe50370e50371e50372e50373e50374e50375e50376e50377e50378e50379e5037ae5037be5037ce5037de5037ee5037fe50380e50381e50382e50383e50384e50385e50386e50387e50388e50389e5038ae5038be5038ce5038de5038ee5038fe50390e50391e50392e50393e50394e50395e50396e50397e50398e50399e5039ae5039be5039ce5039de5039ee5039fe503a0e503a1e503a2e503a3e503a4e503a5e503a6e503a7e503a8e503a9e503aae503abe503ace503ade503aee503afe503b0e503b1e503b2e503b3e503b4e503b5e503b6e503b7e503b8e503b9e503bae503bbe503bce503bde503bee503bfe503c0e503c1e503c2e503c3e503c4e503c5e503c6e503c7e503c8e503c9e503cae503cbe503cce503cde503cee503cfe503d0e503d1e503d2e503d3e503d4e503d5e503d6e503d7e503d8e503d9e503dae503dbe503dce503dde503dee503dfe503e0e503e1e503e2e503e3e503e4e503e5e503e6e503e7e503e8e503e9e503eae503ebe503ece503ede503eee503efe503f0e503f1e503f2e503f3e503f4e503f5e503f6e503f7e503f8e503f9e503fae503fbe503fce503fde503fe5b5b00", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/many_code_sections_1024.json b/crates/interpreter/tests/EOFTests/eof_validation/many_code_sections_1024.json new file mode 100644 index 00000000..65681219 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/many_code_sections_1024.json @@ -0,0 +1,14 @@ +{ + "many_code_sections_1024": { + "vectors": { + "many_code_sections_1024_0": { + "code": "0xef000101100002040000030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030400000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000e50001e50002e50003e50004e50005e50006e50007e50008e50009e5000ae5000be5000ce5000de5000ee5000fe50010e50011e50012e50013e50014e50015e50016e50017e50018e50019e5001ae5001be5001ce5001de5001ee5001fe50020e50021e50022e50023e50024e50025e50026e50027e50028e50029e5002ae5002be5002ce5002de5002ee5002fe50030e50031e50032e50033e50034e50035e50036e50037e50038e50039e5003ae5003be5003ce5003de5003ee5003fe50040e50041e50042e50043e50044e50045e50046e50047e50048e50049e5004ae5004be5004ce5004de5004ee5004fe50050e50051e50052e50053e50054e50055e50056e50057e50058e50059e5005ae5005be5005ce5005de5005ee5005fe50060e50061e50062e50063e50064e50065e50066e50067e50068e50069e5006ae5006be5006ce5006de5006ee5006fe50070e50071e50072e50073e50074e50075e50076e50077e50078e50079e5007ae5007be5007ce5007de5007ee5007fe50080e50081e50082e50083e50084e50085e50086e50087e50088e50089e5008ae5008be5008ce5008de5008ee5008fe50090e50091e50092e50093e50094e50095e50096e50097e50098e50099e5009ae5009be5009ce5009de5009ee5009fe500a0e500a1e500a2e500a3e500a4e500a5e500a6e500a7e500a8e500a9e500aae500abe500ace500ade500aee500afe500b0e500b1e500b2e500b3e500b4e500b5e500b6e500b7e500b8e500b9e500bae500bbe500bce500bde500bee500bfe500c0e500c1e500c2e500c3e500c4e500c5e500c6e500c7e500c8e500c9e500cae500cbe500cce500cde500cee500cfe500d0e500d1e500d2e500d3e500d4e500d5e500d6e500d7e500d8e500d9e500dae500dbe500dce500dde500dee500dfe500e0e500e1e500e2e500e3e500e4e500e5e500e6e500e7e500e8e500e9e500eae500ebe500ece500ede500eee500efe500f0e500f1e500f2e500f3e500f4e500f5e500f6e500f7e500f8e500f9e500fae500fbe500fce500fde500fee500ffe50100e50101e50102e50103e50104e50105e50106e50107e50108e50109e5010ae5010be5010ce5010de5010ee5010fe50110e50111e50112e50113e50114e50115e50116e50117e50118e50119e5011ae5011be5011ce5011de5011ee5011fe50120e50121e50122e50123e50124e50125e50126e50127e50128e50129e5012ae5012be5012ce5012de5012ee5012fe50130e50131e50132e50133e50134e50135e50136e50137e50138e50139e5013ae5013be5013ce5013de5013ee5013fe50140e50141e50142e50143e50144e50145e50146e50147e50148e50149e5014ae5014be5014ce5014de5014ee5014fe50150e50151e50152e50153e50154e50155e50156e50157e50158e50159e5015ae5015be5015ce5015de5015ee5015fe50160e50161e50162e50163e50164e50165e50166e50167e50168e50169e5016ae5016be5016ce5016de5016ee5016fe50170e50171e50172e50173e50174e50175e50176e50177e50178e50179e5017ae5017be5017ce5017de5017ee5017fe50180e50181e50182e50183e50184e50185e50186e50187e50188e50189e5018ae5018be5018ce5018de5018ee5018fe50190e50191e50192e50193e50194e50195e50196e50197e50198e50199e5019ae5019be5019ce5019de5019ee5019fe501a0e501a1e501a2e501a3e501a4e501a5e501a6e501a7e501a8e501a9e501aae501abe501ace501ade501aee501afe501b0e501b1e501b2e501b3e501b4e501b5e501b6e501b7e501b8e501b9e501bae501bbe501bce501bde501bee501bfe501c0e501c1e501c2e501c3e501c4e501c5e501c6e501c7e501c8e501c9e501cae501cbe501cce501cde501cee501cfe501d0e501d1e501d2e501d3e501d4e501d5e501d6e501d7e501d8e501d9e501dae501dbe501dce501dde501dee501dfe501e0e501e1e501e2e501e3e501e4e501e5e501e6e501e7e501e8e501e9e501eae501ebe501ece501ede501eee501efe501f0e501f1e501f2e501f3e501f4e501f5e501f6e501f7e501f8e501f9e501fae501fbe501fce501fde501fee501ffe50200e50201e50202e50203e50204e50205e50206e50207e50208e50209e5020ae5020be5020ce5020de5020ee5020fe50210e50211e50212e50213e50214e50215e50216e50217e50218e50219e5021ae5021be5021ce5021de5021ee5021fe50220e50221e50222e50223e50224e50225e50226e50227e50228e50229e5022ae5022be5022ce5022de5022ee5022fe50230e50231e50232e50233e50234e50235e50236e50237e50238e50239e5023ae5023be5023ce5023de5023ee5023fe50240e50241e50242e50243e50244e50245e50246e50247e50248e50249e5024ae5024be5024ce5024de5024ee5024fe50250e50251e50252e50253e50254e50255e50256e50257e50258e50259e5025ae5025be5025ce5025de5025ee5025fe50260e50261e50262e50263e50264e50265e50266e50267e50268e50269e5026ae5026be5026ce5026de5026ee5026fe50270e50271e50272e50273e50274e50275e50276e50277e50278e50279e5027ae5027be5027ce5027de5027ee5027fe50280e50281e50282e50283e50284e50285e50286e50287e50288e50289e5028ae5028be5028ce5028de5028ee5028fe50290e50291e50292e50293e50294e50295e50296e50297e50298e50299e5029ae5029be5029ce5029de5029ee5029fe502a0e502a1e502a2e502a3e502a4e502a5e502a6e502a7e502a8e502a9e502aae502abe502ace502ade502aee502afe502b0e502b1e502b2e502b3e502b4e502b5e502b6e502b7e502b8e502b9e502bae502bbe502bce502bde502bee502bfe502c0e502c1e502c2e502c3e502c4e502c5e502c6e502c7e502c8e502c9e502cae502cbe502cce502cde502cee502cfe502d0e502d1e502d2e502d3e502d4e502d5e502d6e502d7e502d8e502d9e502dae502dbe502dce502dde502dee502dfe502e0e502e1e502e2e502e3e502e4e502e5e502e6e502e7e502e8e502e9e502eae502ebe502ece502ede502eee502efe502f0e502f1e502f2e502f3e502f4e502f5e502f6e502f7e502f8e502f9e502fae502fbe502fce502fde502fee502ffe50300e50301e50302e50303e50304e50305e50306e50307e50308e50309e5030ae5030be5030ce5030de5030ee5030fe50310e50311e50312e50313e50314e50315e50316e50317e50318e50319e5031ae5031be5031ce5031de5031ee5031fe50320e50321e50322e50323e50324e50325e50326e50327e50328e50329e5032ae5032be5032ce5032de5032ee5032fe50330e50331e50332e50333e50334e50335e50336e50337e50338e50339e5033ae5033be5033ce5033de5033ee5033fe50340e50341e50342e50343e50344e50345e50346e50347e50348e50349e5034ae5034be5034ce5034de5034ee5034fe50350e50351e50352e50353e50354e50355e50356e50357e50358e50359e5035ae5035be5035ce5035de5035ee5035fe50360e50361e50362e50363e50364e50365e50366e50367e50368e50369e5036ae5036be5036ce5036de5036ee5036fe50370e50371e50372e50373e50374e50375e50376e50377e50378e50379e5037ae5037be5037ce5037de5037ee5037fe50380e50381e50382e50383e50384e50385e50386e50387e50388e50389e5038ae5038be5038ce5038de5038ee5038fe50390e50391e50392e50393e50394e50395e50396e50397e50398e50399e5039ae5039be5039ce5039de5039ee5039fe503a0e503a1e503a2e503a3e503a4e503a5e503a6e503a7e503a8e503a9e503aae503abe503ace503ade503aee503afe503b0e503b1e503b2e503b3e503b4e503b5e503b6e503b7e503b8e503b9e503bae503bbe503bce503bde503bee503bfe503c0e503c1e503c2e503c3e503c4e503c5e503c6e503c7e503c8e503c9e503cae503cbe503cce503cde503cee503cfe503d0e503d1e503d2e503d3e503d4e503d5e503d6e503d7e503d8e503d9e503dae503dbe503dce503dde503dee503dfe503e0e503e1e503e2e503e3e503e4e503e5e503e6e503e7e503e8e503e9e503eae503ebe503ece503ede503eee503efe503f0e503f1e503f2e503f3e503f4e503f5e503f6e503f7e503f8e503f9e503fae503fbe503fce503fde503fee503ff5b5b00", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/max_arguments_count.json b/crates/interpreter/tests/EOFTests/eof_validation/max_arguments_count.json new file mode 100644 index 00000000..64633318 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/max_arguments_count.json @@ -0,0 +1,57 @@ +{ + "max_arguments_count": { + "vectors": { + "max_arguments_count_0": { + "code": "0xef000101000802000200830001040000000080007f7f7f007f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe3000100e4", + "results": { + "Prague": { + "result": true + } + } + }, + "max_arguments_count_1": { + "code": "0xef00010100080200020001000104000000008000008080008000e4", + "results": { + "Prague": { + "exception": "EOF_InputsOutputsNumAboveLimit", + "result": false + } + } + }, + "max_arguments_count_2": { + "code": "0xef0001010008020002000400ff040000000080007f007f007fe30001006001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e4", + "results": { + "Prague": { + "result": true + } + } + }, + "max_arguments_count_3": { + "code": "0xef0001010008020002000101010400000000800000008100810060016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e4", + "results": { + "Prague": { + "exception": "EOF_InputsOutputsNumAboveLimit", + "result": false + } + } + }, + "max_arguments_count_4": { + "code": "0xef000101000802000200830080040000000080007f7f00007f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe300010050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050e4", + "results": { + "Prague": { + "result": true + } + } + }, + "max_arguments_count_5": { + "code": "0xef000101000802000200010081040000000080000080000080005050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050e4", + "results": { + "Prague": { + "exception": "EOF_InputsOutputsNumAboveLimit", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/max_stack_height.json b/crates/interpreter/tests/EOFTests/eof_validation/max_stack_height.json new file mode 100644 index 00000000..6d00623a --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/max_stack_height.json @@ -0,0 +1,84 @@ +{ + "max_stack_height": { + "vectors": { + "max_stack_height_0": { + "code": "0xef000101000802000200040bfe0400000000800000000003ffe3000100600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050e4", + "results": { + "Prague": { + "result": true + } + } + }, + "max_stack_height_1": { + "code": "0xef00010100080200020c01000104000000008003ff00000000600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050e3000100e4", + "results": { + "Prague": { + "result": true + } + } + }, + "max_stack_height_2": { + "code": "0xef000101000802000200010c0104000000008000000000040000600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600150505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050e4", + "results": { + "Prague": { + "exception": "EOF_MaxStackHeightExceeded", + "result": false + } + } + }, + "max_stack_height_3": { + "code": "0xef00010100080200020c01000104000000008004000000000060016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160015050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505000e4", + "results": { + "Prague": { + "exception": "EOF_MaxStackHeightExceeded", + "result": false + } + } + }, + "max_stack_height_4": { + "code": "0xef000101000802000200010c010400000000800000000003ff00600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600150505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050e4", + "results": { + "Prague": { + "exception": "EOF_InvalidMaxStackHeight", + "result": false + } + } + }, + "max_stack_height_5": { + "code": "0xef00010100080200020c01000104000000008003ff0000000060016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160015050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505000e4", + "results": { + "Prague": { + "exception": "EOF_InvalidMaxStackHeight", + "result": false + } + } + }, + "max_stack_height_6": { + "code": "0xef0001010004020001000804000000008000016000e10002600100", + "results": { + "Prague": { + "result": true + } + } + }, + "max_stack_height_7": { + "code": "0xef0001010004020001000604000000008000016000e1fffd00", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "max_stack_height_8": { + "code": "0xef0001010004020001000704000000008000016000e200fffc00", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/minimal_valid_EOF1_code.json b/crates/interpreter/tests/EOFTests/eof_validation/minimal_valid_EOF1_code.json new file mode 100644 index 00000000..69b66da0 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/minimal_valid_EOF1_code.json @@ -0,0 +1,14 @@ +{ + "minimal_valid_EOF1_code": { + "vectors": { + "minimal_valid_EOF1_code_0": { + "code": "0xef000101000402000100010400000000800000fe", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/minimal_valid_EOF1_code_with_data.json b/crates/interpreter/tests/EOFTests/eof_validation/minimal_valid_EOF1_code_with_data.json new file mode 100644 index 00000000..3155e805 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/minimal_valid_EOF1_code_with_data.json @@ -0,0 +1,14 @@ +{ + "minimal_valid_EOF1_code_with_data": { + "vectors": { + "minimal_valid_EOF1_code_with_data_0": { + "code": "0xef000101000402000100010400010000800000feda", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/minimal_valid_EOF1_multiple_code_sections.json b/crates/interpreter/tests/EOFTests/eof_validation/minimal_valid_EOF1_multiple_code_sections.json new file mode 100644 index 00000000..29a43844 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/minimal_valid_EOF1_multiple_code_sections.json @@ -0,0 +1,31 @@ +{ + "minimal_valid_EOF1_multiple_code_sections": { + "vectors": { + "no_data_section": { + "code": "0xef000101000802000200010001000080000000800000fefe", + "results": { + "Prague": { + "exception": "EOF_DataSectionMissing", + "result": false + } + } + }, + "non_void_input_output": { + "code": "0xef0001010010020004000500060008000204000000008000010100000100010003020300035fe300010050e3000250e43080e300035050e480e4", + "results": { + "Prague": { + "result": true + } + } + }, + "with_data_section": { + "code": "0xef000101000802000200030001040001000080000000800000e50001feda", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/multiple_code_sections_headers.json b/crates/interpreter/tests/EOFTests/eof_validation/multiple_code_sections_headers.json new file mode 100644 index 00000000..0fd093f5 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/multiple_code_sections_headers.json @@ -0,0 +1,15 @@ +{ + "multiple_code_sections_headers": { + "vectors": { + "multiple_code_sections_headers_0": { + "code": "0xef0001010008020001000402000100050400000000800000045c000000405c0000002e0005", + "results": { + "Prague": { + "exception": "EOF_DataSectionMissing", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/non_returning_status.json b/crates/interpreter/tests/EOFTests/eof_validation/non_returning_status.json new file mode 100644 index 00000000..3627dd34 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/non_returning_status.json @@ -0,0 +1,124 @@ +{ + "non_returning_status": { + "vectors": { + "non_returning_status_0": { + "code": "0xef00010100040200010001040000000080000000", + "results": { + "Prague": { + "result": true + } + } + }, + "non_returning_status_1": { + "code": "0xef000101000802000200030001040000000080000000800000e5000100", + "results": { + "Prague": { + "result": true + } + } + }, + "non_returning_status_10": { + "code": "0xef000101000c0200030001000700010400000000800000018000010000000000e10001e4e50002e4", + "results": { + "Prague": { + "exception": "EOF_InvalidNonReturningFlag", + "result": false + } + } + }, + "non_returning_status_11": { + "code": "0xef00010100080200020001000704000000008000000180000100e10001e4e50000", + "results": { + "Prague": { + "exception": "EOF_InvalidNonReturningFlag", + "result": false + } + } + }, + "non_returning_status_12": { + "code": "0xef000101000c02000300030003000304000000008000000080000000800000e50001e50002e50001", + "results": { + "Prague": { + "result": true + } + } + }, + "non_returning_status_13": { + "code": "0xef000101000c02000300040003000304000000008000000000000000000000e3000100e50002e50001", + "results": { + "Prague": { + "result": true + } + } + }, + "non_returning_status_2": { + "code": "0xef000101000802000200040001040000000080000000000000e3000100e4", + "results": { + "Prague": { + "result": true + } + } + }, + "non_returning_status_3": { + "code": "0xef000101000c02000300040003000104000000008000000000000000000000e3000100e50002e4", + "results": { + "Prague": { + "result": true + } + } + }, + "non_returning_status_4": { + "code": "0xef000101000c020003000500070001040000000080000101000001000000005fe3000100e10001e4e50002e4", + "results": { + "Prague": { + "result": true + } + } + }, + "non_returning_status_5": { + "code": "0xef0001010008020002000500070400000000800001010000015fe3000100e10001e4e50000", + "results": { + "Prague": { + "result": true + } + } + }, + "non_returning_status_6": { + "code": "0xef00010100080200020001000104000000008000000080000000e4", + "results": { + "Prague": { + "exception": "EOF_InvalidNonReturningFlag", + "result": false + } + } + }, + "non_returning_status_7": { + "code": "0xef000101000402000100010400000000800000e4", + "results": { + "Prague": { + "exception": "EOF_InvalidNonReturningFlag", + "result": false + } + } + }, + "non_returning_status_8": { + "code": "0xef000101000c0200030001000300010400000000800000008000000000000000e50002e4", + "results": { + "Prague": { + "exception": "EOF_InvalidNonReturningFlag", + "result": false + } + } + }, + "non_returning_status_9": { + "code": "0xef00010100080200020001000304000000008000000000000000e50000", + "results": { + "Prague": { + "exception": "EOF_InvalidNonReturningFlag", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjump.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjump.json new file mode 100644 index 00000000..4e0e76d2 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjump.json @@ -0,0 +1,57 @@ +{ + "backwards_rjump": { + "vectors": { + "backwards_rjump_0": { + "code": "0xef000101000402000100030400000000800000e0fffd", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjump_1": { + "code": "0xef0001010004020001000504000000008000015f50e0fffb", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjump_2": { + "code": "0xef0001010004020001000d04000000008000015f506001e10003e0fff8e0fff5", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjump_3": { + "code": "0xef0001010004020001000e04000000008000015f506001e10003e0fff85fe0fff4", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjump_4": { + "code": "0xef0001010004020001000404000000008000015fe0fffc", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjump_5": { + "code": "0xef0001010004020001000504000000008000015f50e0fffc", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjump_variable_stack.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjump_variable_stack.json new file mode 100644 index 00000000..97257239 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjump_variable_stack.json @@ -0,0 +1,75 @@ +{ + "backwards_rjump_variable_stack": { + "vectors": { + "backwards_rjump_variable_stack_0": { + "code": "0xef0001010004020001000b04000000008000035f6000e100025f5fe0fffd", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjump_variable_stack_1": { + "code": "0xef0001010004020001000d04000000008000045f6000e100025f5f5f50e0fffb", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjump_variable_stack_2": { + "code": "0xef0001010004020001001504000000008000045f6000e100025f5f5f506001e10003e0fff8e0fff5", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjump_variable_stack_3": { + "code": "0xef0001010004020001001604000000008000045f6000e100025f5f5f506001e10003e0fff85fe0fff4", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjump_variable_stack_4": { + "code": "0xef0001010004020001001104000000008000045f6000e100025f5f6000e100015fe0fff9", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjump_variable_stack_5": { + "code": "0xef0001010004020001001104000000008000045f6000e100025f5f6000e1000150e0fff9", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjump_variable_stack_6": { + "code": "0xef0001010004020001000c04000000008000045f6000e100025f5f5fe0fffc", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjump_variable_stack_7": { + "code": "0xef0001010004020001000d04000000008000035f6000e100025f5f5f50e0fffc", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjumpi.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjumpi.json new file mode 100644 index 00000000..cdc6a587 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjumpi.json @@ -0,0 +1,100 @@ +{ + "backwards_rjumpi": { + "vectors": { + "backwards_rjumpi_0": { + "code": "0xef0001010004020001000604000000008000016000e1fffb00", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpi_1": { + "code": "0xef0001010004020001000804000000008000015f506000e1fff900", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpi_10": { + "code": "0xef0001010004020001000e040000000080000360be6000e10001506000e1fff500", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjumpi_2": { + "code": "0xef0001010004020001000d04000000008000015f506000e1fff96000e1fff400", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpi_3": { + "code": "0xef0001010004020001000e04000000008000025f506000e1fff95f6000e1fff300", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjumpi_4": { + "code": "0xef0001010004020001000904000000008000025f60010180e1fff900", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpi_5": { + "code": "0xef0001010004020001000a04000000008000025f6001018080e1fff800", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjumpi_6": { + "code": "0xef0001010004020001000804000000008000025f5f5f50e1fffc00", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjumpi_7": { + "code": "0xef0001010004020001000a04000000008000015f506000e1fff9e0fff6", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpi_8": { + "code": "0xef0001010004020001000b04000000008000015f506000e1fff95fe0fff5", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjumpi_9": { + "code": "0xef0001010004020001000d04000000008000035f6000e100015f6000e1fff500", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjumpi_variable_stack.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjumpi_variable_stack.json new file mode 100644 index 00000000..427148d4 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjumpi_variable_stack.json @@ -0,0 +1,82 @@ +{ + "backwards_rjumpi_variable_stack": { + "vectors": { + "backwards_rjumpi_variable_stack_0": { + "code": "0xef0001010004020001000e04000000008000045f6000e100025f5f6000e1fffb00", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpi_variable_stack_1": { + "code": "0xef0001010004020001001004000000008000045f6000e100025f5f5f506000e1fff900", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpi_variable_stack_2": { + "code": "0xef0001010004020001001504000000008000045f6000e100025f5f5f506000e1fff96000e1fff400", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpi_variable_stack_3": { + "code": "0xef0001010004020001001604000000008000055f6000e100025f5f5f506000e1fff95f6000e1fff300", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjumpi_variable_stack_4": { + "code": "0xef0001010004020001001104000000008000055f6000e100025f5f5f60010180e1fff900", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpi_variable_stack_5": { + "code": "0xef0001010004020001001204000000008000055f6000e100025f5f5f6001018080e1fff800", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjumpi_variable_stack_6": { + "code": "0xef0001010004020001001004000000008000055f6000e100025f5f5f5f5f50e1fffc00", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjumpi_variable_stack_7": { + "code": "0xef0001010004020001001204000000008000045f6000e100025f5f5f506000e1fff9e0fff6", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpi_variable_stack_8": { + "code": "0xef0001010004020001001304000000008000045f6000e100025f5f5f506000e1fff95fe0fff5", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjumpv.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjumpv.json new file mode 100644 index 00000000..fae2f608 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjumpv.json @@ -0,0 +1,74 @@ +{ + "backwards_rjumpv": { + "vectors": { + "backwards_rjumpv_0": { + "code": "0xef0001010004020001000704000000008000016000e200fffa00", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpv_1": { + "code": "0xef0001010004020001000904000000008000015f506000e200fff800", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpv_2": { + "code": "0xef0001010004020001000f04000000008000015f506000e200fff86000e200fff200", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpv_3": { + "code": "0xef0001010004020001001004000000008000025f506000e200fff85f6000e200fff100", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjumpv_4": { + "code": "0xef0001010004020001000b04000000008000015f506000e200fff8e0fff5", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpv_5": { + "code": "0xef0001010004020001000c04000000008000015f506000e200fff85fe0fff4", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjumpv_6": { + "code": "0xef0001010004020001000e04000000008000035f6000e100015f6000e200fff400", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjumpv_7": { + "code": "0xef0001010004020001000f040000000080000360be6000e10001506000e200fff400", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjumpv_variable_stack.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjumpv_variable_stack.json new file mode 100644 index 00000000..0cce8488 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/backwards_rjumpv_variable_stack.json @@ -0,0 +1,74 @@ +{ + "backwards_rjumpv_variable_stack": { + "vectors": { + "backwards_rjumpv_variable_stack_0": { + "code": "0xef0001010004020001000f04000000008000045f6000e100025f5f6000e200fffa00", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpv_variable_stack_1": { + "code": "0xef0001010004020001001104000000008000045f6000e100025f5f5f506000e200fff800", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpv_variable_stack_2": { + "code": "0xef0001010004020001001704000000008000045f6000e100025f5f5f506000e200fff86000e200fff200", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpv_variable_stack_3": { + "code": "0xef0001010004020001001804000000008000055f6000e100025f5f5f506000e200fff85f6000e200fff100", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjumpv_variable_stack_4": { + "code": "0xef0001010004020001001304000000008000045f6000e100025f5f5f506000e200fff8e0fff5", + "results": { + "Prague": { + "result": true + } + } + }, + "backwards_rjumpv_variable_stack_5": { + "code": "0xef0001010004020001001404000000008000045f6000e100025f5f5f506000e200fff85fe0fff4", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjumpv_variable_stack_6": { + "code": "0xef0001010004020001001604000000008000055f6000e100025f5f5f6000e100015f6000e200fff400", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "backwards_rjumpv_variable_stack_7": { + "code": "0xef0001010004020001001704000000008000055f6000e100025f5f5f5f6000e10001506000e200fff400", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/callf_stack_overflow.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/callf_stack_overflow.json new file mode 100644 index 00000000..bc17fd15 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/callf_stack_overflow.json @@ -0,0 +1,49 @@ +{ + "callf_stack_overflow": { + "vectors": { + "callf_stack_overflow_0": { + "code": "0xef000101000802000200040604040000000080000000000200e300010060016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e300015050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050e4", + "results": { + "Prague": { + "result": true + } + } + }, + "callf_stack_overflow_1": { + "code": "0xef000101000802000200040607040000000080000000000201e3000100600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30001505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050e4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "callf_stack_overflow_2": { + "code": "0xef000101000802000200040c010400000000800000000003ffe3000100600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30001505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050e4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "callf_stack_overflow_3": { + "code": "0xef000101000c02000300040c0100030400000000800000000003ff00000001e3000100600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30002505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050e45f50e4", + "results": { + "Prague": { + "result": true + } + } + }, + "callf_stack_overflow_4": { + "code": "0xef000101000c02000300040c0100050400000000800000000003ff00000002e3000100600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30002505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050e45f5f5050e4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/callf_stack_overflow_variable_stack.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/callf_stack_overflow_variable_stack.json new file mode 100644 index 00000000..cd78ff8f --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/callf_stack_overflow_variable_stack.json @@ -0,0 +1,58 @@ +{ + "callf_stack_overflow_variable_stack": { + "vectors": { + "callf_stack_overflow_variable_stack_0": { + "code": "0xef0001010008020002040606010400000000800200000002005f6000e100025f5f60016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e3000100600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160015050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050e4", + "results": { + "Prague": { + "result": true + } + } + }, + "callf_stack_overflow_variable_stack_1": { + "code": "0xef00010100080200020406060a0400000000800200000002035f6000e100025f5f60016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e3000100600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160015050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050e4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "callf_stack_overflow_variable_stack_2": { + "code": "0xef0001010008020002040606070400000000800200000002025f6000e100025f5f60016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e3000100600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600150505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050e4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "callf_stack_overflow_variable_stack_3": { + "code": "0xef00010100080200020804000304000000008003ff000000015f6000e100025f5f600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30001005f50e4", + "results": { + "Prague": { + "result": true + } + } + }, + "callf_stack_overflow_variable_stack_4": { + "code": "0xef00010100080200020804000b04000000008003ff000000055f6000e100025f5f600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30001005f5f5f5f5f5050505050e4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "callf_stack_overflow_variable_stack_5": { + "code": "0xef00010100080200020804000504000000008003ff000000025f6000e100025f5f600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30001005f5f5050e4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/callf_stack_validation.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/callf_stack_validation.json new file mode 100644 index 00000000..b0eda869 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/callf_stack_validation.json @@ -0,0 +1,32 @@ +{ + "callf_stack_validation": { + "vectors": { + "callf_stack_validation_0": { + "code": "0xef000101000c02000300040006000204000000008000010001000202010002e30001005f5fe30002e450e4", + "results": { + "Prague": { + "result": true + } + } + }, + "callf_stack_validation_1": { + "code": "0xef000101000c02000300040007000204000000008000010001000302010002e30001005f5f5fe30002e450e4", + "results": { + "Prague": { + "exception": "EOF_InvalidNumberOfOutputs", + "result": false + } + } + }, + "callf_stack_validation_2": { + "code": "0xef000101000c02000300040005000204000000008000010001000102010002e30001005fe30002e450e4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/callf_with_inputs_stack_overflow.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/callf_with_inputs_stack_overflow.json new file mode 100644 index 00000000..a6f5af7c --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/callf_with_inputs_stack_overflow.json @@ -0,0 +1,58 @@ +{ + "callf_with_inputs_stack_overflow": { + "vectors": { + "callf_with_inputs_stack_overflow_0": { + "code": "0xef00010100080200020bfd000304000000008003ff02000002600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e300015050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050f35050e4", + "results": { + "Prague": { + "result": true + } + } + }, + "callf_with_inputs_stack_overflow_1": { + "code": "0xef00010100080200020bff000404000000008003ff03030004600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e3000150505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050f3600150e4", + "results": { + "Prague": { + "result": true + } + } + }, + "callf_with_inputs_stack_overflow_2": { + "code": "0xef00010100080200020bff000304000000008003ff03050005600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e3000150505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050f35f5fe4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "callf_with_inputs_stack_overflow_3": { + "code": "0xef00010100080200020bff000504000000008003ff03030005600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e3000150505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050f35f5f5050e4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "callf_with_inputs_stack_overflow_4": { + "code": "0xef00010100080200020c00000504000000008003ff020000036001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30001505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050f35f505050e4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "callf_with_inputs_stack_overflow_5": { + "code": "0xef00010100080200020bfe000704000000008003ff02000004600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30001505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050f35f5f50505050e4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/callf_with_inputs_stack_overflow_variable_stack.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/callf_with_inputs_stack_overflow_variable_stack.json new file mode 100644 index 00000000..85ac3816 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/callf_with_inputs_stack_overflow_variable_stack.json @@ -0,0 +1,94 @@ +{ + "callf_with_inputs_stack_overflow_variable_stack": { + "vectors": { + "callf_with_inputs_stack_overflow_variable_stack_0": { + "code": "0xef00010100080200020804000304000000008003ff020000025f6000e100025f5f600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30001005050e4", + "results": { + "Prague": { + "result": true + } + } + }, + "callf_with_inputs_stack_overflow_variable_stack_1": { + "code": "0xef00010100080200020804000404000000008003ff030300045f6000e100025f5f600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e3000100600150e4", + "results": { + "Prague": { + "result": true + } + } + }, + "callf_with_inputs_stack_overflow_variable_stack_2": { + "code": "0xef00010100080200020804000504000000008003ff030700075f6000e100025f5f600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30001005f5f5f5fe4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "callf_with_inputs_stack_overflow_variable_stack_3": { + "code": "0xef00010100080200020804000304000000008003ff030500055f6000e100025f5f600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30001005f5fe4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "callf_with_inputs_stack_overflow_variable_stack_4": { + "code": "0xef00010100080200020804000704000000008003ff030300075f6000e100025f5f600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30001005f5f5f5f5050e4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "callf_with_inputs_stack_overflow_variable_stack_5": { + "code": "0xef00010100080200020804000504000000008003ff030300055f6000e100025f5f600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30001005f5f5050e4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "callf_with_inputs_stack_overflow_variable_stack_6": { + "code": "0xef00010100080200020806000904000000008003ff020000055f6000e100025f5f6001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30001005f5f5f5050505050e4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "callf_with_inputs_stack_overflow_variable_stack_7": { + "code": "0xef00010100080200020806000504000000008003ff020000035f6000e100025f5f6001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30001005f505050e4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "callf_with_inputs_stack_overflow_variable_stack_8": { + "code": "0xef00010100080200020804000b04000000008003ff020000065f6000e100025f5f600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30001005f5f5f5f505050505050e4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "callf_with_inputs_stack_overflow_variable_stack_9": { + "code": "0xef00010100080200020804000704000000008003ff020000045f6000e100025f5f600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e30001005f5f50505050e4", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/dupn_stack_validation.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/dupn_stack_validation.json new file mode 100644 index 00000000..e34d293d --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/dupn_stack_validation.json @@ -0,0 +1,58 @@ +{ + "dupn_stack_validation": { + "vectors": { + "dupn_stack_validation_0": { + "code": "0xef0001010004020001002b040000000080001560016001600160016001600160016001600160016001600160016001600160016001600160016001e60000", + "results": { + "Prague": { + "result": true + } + } + }, + "dupn_stack_validation_1": { + "code": "0xef0001010004020001002b040000000080001560016001600160016001600160016001600160016001600160016001600160016001600160016001e61300", + "results": { + "Prague": { + "result": true + } + } + }, + "dupn_stack_validation_2": { + "code": "0xef0001010004020001002b040000000080001560016001600160016001600160016001600160016001600160016001600160016001600160016001e61400", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "dupn_stack_validation_3": { + "code": "0xef0001010004020001002b040000000080001560016001600160016001600160016001600160016001600160016001600160016001600160016001e6d000", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "dupn_stack_validation_4": { + "code": "0xef0001010004020001002b040000000080001560016001600160016001600160016001600160016001600160016001600160016001600160016001e6fe00", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "dupn_stack_validation_5": { + "code": "0xef0001010004020001002b040000000080001560016001600160016001600160016001600160016001600160016001600160016001600160016001e6ff00", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/exchange_deep_stack_validation.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/exchange_deep_stack_validation.json new file mode 100644 index 00000000..830e71fe --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/exchange_deep_stack_validation.json @@ -0,0 +1,14 @@ +{ + "exchange_deep_stack_validation": { + "vectors": { + "exchange_deep_stack_validation_0": { + "code": "0xef000101000402000100450400000000800021600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e8ff00", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/exchange_empty_stack_validation.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/exchange_empty_stack_validation.json new file mode 100644 index 00000000..99fddf70 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/exchange_empty_stack_validation.json @@ -0,0 +1,15 @@ +{ + "exchange_empty_stack_validation": { + "vectors": { + "exchange_empty_stack_validation_0": { + "code": "0xef000101000402000100030400000000800000e80000", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/exchange_stack_validation.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/exchange_stack_validation.json new file mode 100644 index 00000000..831f3579 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/exchange_stack_validation.json @@ -0,0 +1,201 @@ +{ + "exchange_stack_validation": { + "vectors": { + "exchange_stack_validation_0": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e80000", + "results": { + "Prague": { + "result": true + } + } + }, + "exchange_stack_validation_1": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e81000", + "results": { + "Prague": { + "result": true + } + } + }, + "exchange_stack_validation_10": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e81600", + "results": { + "Prague": { + "result": true + } + } + }, + "exchange_stack_validation_11": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e86100", + "results": { + "Prague": { + "result": true + } + } + }, + "exchange_stack_validation_12": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e88000", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "exchange_stack_validation_13": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e80800", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "exchange_stack_validation_14": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e87100", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "exchange_stack_validation_15": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e81700", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "exchange_stack_validation_16": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e84400", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "exchange_stack_validation_17": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e85300", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "exchange_stack_validation_18": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e83500", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "exchange_stack_validation_19": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e8ee00", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "exchange_stack_validation_2": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e80100", + "results": { + "Prague": { + "result": true + } + } + }, + "exchange_stack_validation_20": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e8ef00", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "exchange_stack_validation_21": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e8fe00", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "exchange_stack_validation_22": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e8ff00", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "exchange_stack_validation_3": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e82000", + "results": { + "Prague": { + "result": true + } + } + }, + "exchange_stack_validation_4": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e80200", + "results": { + "Prague": { + "result": true + } + } + }, + "exchange_stack_validation_5": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e87000", + "results": { + "Prague": { + "result": true + } + } + }, + "exchange_stack_validation_6": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e80700", + "results": { + "Prague": { + "result": true + } + } + }, + "exchange_stack_validation_7": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e81100", + "results": { + "Prague": { + "result": true + } + } + }, + "exchange_stack_validation_8": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e83400", + "results": { + "Prague": { + "result": true + } + } + }, + "exchange_stack_validation_9": { + "code": "0xef00010100040200010017040000000080000a6001600160016001600160016001600160016001e84300", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjump.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjump.json new file mode 100644 index 00000000..e2b99000 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjump.json @@ -0,0 +1,46 @@ +{ + "forwards_rjump": { + "vectors": { + "forwards_rjump_0": { + "code": "0xef000101000402000100040400000000800000e0000000", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjump_1": { + "code": "0xef0001010004020001000b04000000008000025f6000e10003e000011900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjump_2": { + "code": "0xef0001010004020001001304000000008000025f6000e100086000e10006e00004e000011900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjump_3": { + "code": "0xef0001010004020001000b04000000008000025f6000e10003e000015f00", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjump_4": { + "code": "0xef0001010004020001001404000000008000025f6000e100086000e10007e000055fe000011900", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjump_variable_stack.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjump_variable_stack.json new file mode 100644 index 00000000..62c5fb2b --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjump_variable_stack.json @@ -0,0 +1,46 @@ +{ + "forwards_rjump_variable_stack": { + "vectors": { + "forwards_rjump_variable_stack_0": { + "code": "0xef0001010004020001000c04000000008000035f6000e100025f5fe0000000", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjump_variable_stack_1": { + "code": "0xef0001010004020001001304000000008000055f6000e100025f5f5f6000e10003e000011900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjump_variable_stack_2": { + "code": "0xef0001010004020001001b04000000008000055f6000e100025f5f5f6000e100086000e10006e00004e000011900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjump_variable_stack_3": { + "code": "0xef0001010004020001001304000000008000055f6000e100025f5f5f6000e10003e000015f00", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjump_variable_stack_4": { + "code": "0xef0001010004020001001b04000000008000045f6000e100025f5f6000e100086000e10007e000055fe000011900", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjumpi.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjumpi.json new file mode 100644 index 00000000..b7f9d445 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjumpi.json @@ -0,0 +1,110 @@ +{ + "forwards_rjumpi": { + "vectors": { + "forwards_rjumpi_0": { + "code": "0xef0001010004020001000604000000008000016001e1000000", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_1": { + "code": "0xef0001010004020001000804000000008000025f6000e100011900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_10": { + "code": "0xef0001010004020001000c04000000008000025f6000e1000450e000011900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_11": { + "code": "0xef0001010004020001000a04000000008000025f6000e10003e0000000", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_12": { + "code": "0xef0001010004020001000b04000000008000025f6000e100045fe0000000", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_2": { + "code": "0xef0001010004020001000d04000000008000025f6000e100066000e100011900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_3": { + "code": "0xef0001010004020001000804000000008000025f6000e100015f00", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_4": { + "code": "0xef0001010004020001000e04000000008000035f6000e100075f6000e100011900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_5": { + "code": "0xef0001010004020001001004000000008000035f60010180600a11e1000480e1fff200", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_6": { + "code": "0xef0001010004020001001104000000008000035f60010180600a11e100055f80e1fff300", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_7": { + "code": "0xef0001010004020001000c04000000008000025f6000e100045fe000015f00", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_8": { + "code": "0xef0001010004020001000c04000000008000025f6000e100045fe000011900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_9": { + "code": "0xef0001010004020001000c04000000008000025f6000e1000450e000015000", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjumpi_variable_stack.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjumpi_variable_stack.json new file mode 100644 index 00000000..cc0c4192 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjumpi_variable_stack.json @@ -0,0 +1,110 @@ +{ + "forwards_rjumpi_variable_stack": { + "vectors": { + "forwards_rjumpi_variable_stack_0": { + "code": "0xef0001010004020001000e04000000008000045f6000e100025f5f6001e1000000", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_variable_stack_1": { + "code": "0xef0001010004020001001004000000008000055f6000e100025f5f5f6000e100011900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_variable_stack_10": { + "code": "0xef0001010004020001001404000000008000055f6000e100025f5f5f6000e1000450e000011900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_variable_stack_11": { + "code": "0xef0001010004020001001204000000008000055f6000e100025f5f5f6000e10003e0000000", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_variable_stack_12": { + "code": "0xef0001010004020001001304000000008000055f6000e100025f5f5f6000e100045fe0000000", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_variable_stack_2": { + "code": "0xef0001010004020001001504000000008000055f6000e100025f5f5f6000e100066000e100011900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_variable_stack_3": { + "code": "0xef0001010004020001001004000000008000055f6000e100025f5f5f6000e100015f00", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_variable_stack_4": { + "code": "0xef0001010004020001001604000000008000065f6000e100025f5f5f6000e100075f6000e100011900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_variable_stack_5": { + "code": "0xef0001010004020001001804000000008000065f6000e100025f5f5f60010180600a11e1000480e1fff200", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_variable_stack_6": { + "code": "0xef0001010004020001001904000000008000065f6000e100025f5f5f60010180600a11e100055f80e1fff300", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_variable_stack_7": { + "code": "0xef0001010004020001001404000000008000055f6000e100025f5f5f6000e100045fe000015f00", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_variable_stack_8": { + "code": "0xef0001010004020001001404000000008000055f6000e100025f5f5f6000e100045fe000011900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpi_variable_stack_9": { + "code": "0xef0001010004020001001404000000008000055f6000e100025f5f5f6000e1000450e000015000", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjumpv.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjumpv.json new file mode 100644 index 00000000..dcfe6faa --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjumpv.json @@ -0,0 +1,86 @@ +{ + "forwards_rjumpv": { + "vectors": { + "forwards_rjumpv_0": { + "code": "0xef0001010004020001000704000000008000016001e200000000", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_1": { + "code": "0xef0001010004020001000904000000008000025f6000e20000011900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_2": { + "code": "0xef0001010004020001000d04000000008000025f6000e201000200035f501900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_3": { + "code": "0xef0001010004020001000904000000008000025f6000e20000015f00", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_4": { + "code": "0xef0001010004020001000d04000000008000035f6000e201000100025f5f1900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_5": { + "code": "0xef0001010004020001001604000000008000025f6000e2010005000a6001e000076002e00002600300", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_6": { + "code": "0xef0001010004020001001604000000008000045f6000e201000400095fe000085f5fe000035f5f5f00", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_7": { + "code": "0xef0001010004020001001904000000008000055f5f5f5f6000e2010004000950e000085050e0000350505000", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_8": { + "code": "0xef0001010004020001000b04000000008000025f6000e2000003e0000000", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_9": { + "code": "0xef0001010004020001000c04000000008000025f6000e20000045fe0000000", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjumpv_variable_stack.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjumpv_variable_stack.json new file mode 100644 index 00000000..a4d3aea5 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/forwards_rjumpv_variable_stack.json @@ -0,0 +1,86 @@ +{ + "forwards_rjumpv_variable_stack": { + "vectors": { + "forwards_rjumpv_variable_stack_0": { + "code": "0xef0001010004020001000f04000000008000045f6000e100025f5f6001e200000000", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_variable_stack_1": { + "code": "0xef0001010004020001001104000000008000055f6000e100025f5f5f6000e20000011900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_variable_stack_2": { + "code": "0xef0001010004020001001504000000008000055f6000e100025f5f5f6000e201000200035f501900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_variable_stack_3": { + "code": "0xef0001010004020001001104000000008000055f6000e100025f5f5f6000e20000015f00", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_variable_stack_4": { + "code": "0xef0001010004020001001504000000008000065f6000e100025f5f5f6000e201000100025f5f1900", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_variable_stack_5": { + "code": "0xef0001010004020001001e04000000008000055f6000e100025f5f5f6000e2010005000a6001e000076002e00002600300", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_variable_stack_6": { + "code": "0xef0001010004020001001e04000000008000075f6000e100025f5f5f6000e201000400095fe000085f5fe000035f5f5f00", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_variable_stack_7": { + "code": "0xef0001010004020001002104000000008000085f6000e100025f5f5f5f5f5f6000e2010004000950e000085050e0000350505000", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_variable_stack_8": { + "code": "0xef0001010004020001001304000000008000055f6000e100025f5f5f6000e2000003e0000000", + "results": { + "Prague": { + "result": true + } + } + }, + "forwards_rjumpv_variable_stack_9": { + "code": "0xef0001010004020001001404000000008000055f6000e100025f5f5f6000e20000045fe0000000", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_stack_overflow.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_stack_overflow.json new file mode 100644 index 00000000..1b7a0d95 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_stack_overflow.json @@ -0,0 +1,49 @@ +{ + "jumpf_stack_overflow": { + "vectors": { + "jumpf_stack_overflow_0": { + "code": "0xef00010100040200010403040000000080020060016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e50000", + "results": { + "Prague": { + "result": true + } + } + }, + "jumpf_stack_overflow_1": { + "code": "0xef000101000402000104050400000000800201600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e50000", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "jumpf_stack_overflow_2": { + "code": "0xef0001010004020001080104000000008003ff600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e50000", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "jumpf_stack_overflow_3": { + "code": "0xef00010100080200020801000204000000008003ff00800001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e500015f00", + "results": { + "Prague": { + "result": true + } + } + }, + "jumpf_stack_overflow_4": { + "code": "0xef00010100080200020801000304000000008003ff00800002600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001600160016001e500015f5f00", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_stack_overflow_variable_stack.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_stack_overflow_variable_stack.json new file mode 100644 index 00000000..4554f84b --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_stack_overflow_variable_stack.json @@ -0,0 +1,58 @@ +{ + "jumpf_stack_overflow_variable_stack": { + "vectors": { + "jumpf_stack_overflow_variable_stack_0": { + "code": "0xef0001010004020001020804000000008002005f6000e100025f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe50000", + "results": { + "Prague": { + "result": true + } + } + }, + "jumpf_stack_overflow_variable_stack_1": { + "code": "0xef0001010008020002020802040400000000800200008002035f6000e100025f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe500015f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f00", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "jumpf_stack_overflow_variable_stack_2": { + "code": "0xef0001010008020002020802030400000000800200008002025f6000e100025f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe500015f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f00", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "jumpf_stack_overflow_variable_stack_3": { + "code": "0xef00010100080200020407000204000000008003ff008000015f6000e100025f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe500015f00", + "results": { + "Prague": { + "result": true + } + } + }, + "jumpf_stack_overflow_variable_stack_4": { + "code": "0xef00010100080200020407000604000000008003ff008000055f6000e100025f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe500015f5f5f5f5f00", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "jumpf_stack_overflow_variable_stack_5": { + "code": "0xef00010100080200020407000304000000008003ff008000025f6000e100025f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe500015f5f00", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_to_nonreturning.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_to_nonreturning.json new file mode 100644 index 00000000..7cfccdea --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_to_nonreturning.json @@ -0,0 +1,47 @@ +{ + "jumpf_to_nonreturning": { + "vectors": { + "jumpf_to_nonreturning_0": { + "code": "0xef000101000802000200030001040000000080000000800000e5000100", + "results": { + "Prague": { + "result": true + } + } + }, + "jumpf_to_nonreturning_1": { + "code": "0xef0001010008020002000500010400000000800002008000005f5fe5000100", + "results": { + "Prague": { + "result": true + } + } + }, + "jumpf_to_nonreturning_2": { + "code": "0xef0001010008020002000600010400000000800003038000035f5f5fe5000100", + "results": { + "Prague": { + "result": true + } + } + }, + "jumpf_to_nonreturning_3": { + "code": "0xef0001010008020002000700010400000000800004038000035f5f5f5fe5000100", + "results": { + "Prague": { + "result": true + } + } + }, + "jumpf_to_nonreturning_4": { + "code": "0xef0001010008020002000500010400000000800002038000035f5fe5000100", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_to_nonreturning_variable_stack.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_to_nonreturning_variable_stack.json new file mode 100644 index 00000000..8ac969b8 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_to_nonreturning_variable_stack.json @@ -0,0 +1,40 @@ +{ + "jumpf_to_nonreturning_variable_stack": { + "vectors": { + "jumpf_to_nonreturning_variable_stack_0": { + "code": "0xef0001010008020002000b00010400000000800003058000055f6000e100025f5fe50001fe", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "jumpf_to_nonreturning_variable_stack_1": { + "code": "0xef0001010008020002000b00010400000000800003038000035f6000e100025f5fe50001fe", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "jumpf_to_nonreturning_variable_stack_2": { + "code": "0xef0001010008020002000b00010400000000800003018000015f6000e100025f5fe50001fe", + "results": { + "Prague": { + "result": true + } + } + }, + "jumpf_to_nonreturning_variable_stack_3": { + "code": "0xef0001010008020002000b00010400000000800003008000005f6000e100025f5fe50001fe", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_to_returning.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_to_returning.json new file mode 100644 index 00000000..4731686f --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_to_returning.json @@ -0,0 +1,101 @@ +{ + "jumpf_to_returning": { + "vectors": { + "jumpf_to_returning_0": { + "code": "0xef000101000c02000300040003000304000000008000020002000000020002e3000100e500025f5fe4", + "results": { + "Prague": { + "result": true + } + } + }, + "jumpf_to_returning_1": { + "code": "0xef000101000c02000300040005000304000000008000020002000200020002e30001005f5fe500025f5fe4", + "results": { + "Prague": { + "exception": "EOF_InvalidNumberOfOutputs", + "result": false + } + } + }, + "jumpf_to_returning_10": { + "code": "0xef000101000c02000300040006000304000000008000020002000303010003e30001005f5f5fe500025050e4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "jumpf_to_returning_2": { + "code": "0xef000101000c02000300040006000204000000008000020002000303020003e30001005f5f5fe5000250e4", + "results": { + "Prague": { + "result": true + } + } + }, + "jumpf_to_returning_3": { + "code": "0xef000101000c02000300040007000204000000008000020002000403020003e30001005f5f5f5fe5000250e4", + "results": { + "Prague": { + "exception": "EOF_InvalidNumberOfOutputs", + "result": false + } + } + }, + "jumpf_to_returning_4": { + "code": "0xef000101000c02000300040005000204000000008000020002000203020003e30001005f5fe5000250e4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "jumpf_to_returning_5": { + "code": "0xef000101000c02000300040004000204000000008000020002000100010001e30001005fe500025fe4", + "results": { + "Prague": { + "result": true + } + } + }, + "jumpf_to_returning_6": { + "code": "0xef000101000c02000300040006000204000000008000020002000300010001e30001005f5f5fe500025fe4", + "results": { + "Prague": { + "exception": "EOF_InvalidNumberOfOutputs", + "result": false + } + } + }, + "jumpf_to_returning_7": { + "code": "0xef000101000c02000300040003000204000000008000020002000000010001e3000100e500025fe4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "jumpf_to_returning_8": { + "code": "0xef000101000c02000300040007000304000000008000020002000403010003e30001005f5f5f5fe500025050e4", + "results": { + "Prague": { + "result": true + } + } + }, + "jumpf_to_returning_9": { + "code": "0xef000101000c02000300040008000304000000008000020002000503010003e30001005f5f5f5f5fe500025050e4", + "results": { + "Prague": { + "exception": "EOF_InvalidNumberOfOutputs", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_to_returning_variable_stack.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_to_returning_variable_stack.json new file mode 100644 index 00000000..af4bc13d --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_to_returning_variable_stack.json @@ -0,0 +1,78 @@ +{ + "jumpf_to_returning_variable_stack": { + "vectors": { + "jumpf_to_returning_variable_stack_0": { + "code": "0xef000101000c0200030004000b000204000000008000030003000305030003e30001005f6000e100025f5fe500025fe4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "jumpf_to_returning_variable_stack_1": { + "code": "0xef000101000c0200030004000b000104000000008000030003000303030003e30001005f6000e100025f5fe50002e4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "jumpf_to_returning_variable_stack_2": { + "code": "0xef000101000c0200030004000b000304000000008000030003000301030005e30001005f6000e100025f5fe500025f5fe4", + "results": { + "Prague": { + "exception": "EOF_InvalidNumberOfOutputs", + "result": false + } + } + }, + "jumpf_to_returning_variable_stack_3": { + "code": "0xef000101000c0200030004000b000404000000008000030003000300030003e30001005f6000e100025f5fe500025f5f5fe4", + "results": { + "Prague": { + "exception": "EOF_InvalidNumberOfOutputs", + "result": false + } + } + }, + "jumpf_to_returning_variable_stack_4": { + "code": "0xef000101000c0200030004000b000504000000008000020002000305010005e30001005f6000e100025f5fe5000250505050e4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "jumpf_to_returning_variable_stack_5": { + "code": "0xef000101000c0200030004000b000304000000008000020002000303010003e30001005f6000e100025f5fe500025050e4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "jumpf_to_returning_variable_stack_6": { + "code": "0xef000101000c0200030004000b000104000000008000020002000301010001e30001005f6000e100025f5fe50002e4", + "results": { + "Prague": { + "exception": "EOF_InvalidNumberOfOutputs", + "result": false + } + } + }, + "jumpf_to_returning_variable_stack_7": { + "code": "0xef000101000c0200030004000b000204000000008000020002000300010001e30001005f6000e100025f5fe500025fe4", + "results": { + "Prague": { + "exception": "EOF_InvalidNumberOfOutputs", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_with_inputs_stack_overflow.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_with_inputs_stack_overflow.json new file mode 100644 index 00000000..cd30b9ff --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_with_inputs_stack_overflow.json @@ -0,0 +1,32 @@ +{ + "jumpf_with_inputs_stack_overflow": { + "vectors": { + "jumpf_with_inputs_stack_overflow_0": { + "code": "0xef00010100080200020402000204000000008003ff028000035f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe500015f00", + "results": { + "Prague": { + "result": true + } + } + }, + "jumpf_with_inputs_stack_overflow_1": { + "code": "0xef00010100080200020402000304000000008003ff028000045f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe500015f5f00", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "jumpf_with_inputs_stack_overflow_2": { + "code": "0xef00010100080200020403000204000000008003ff028000035f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe500015f00", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_with_inputs_stack_overflow_variable_stack.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_with_inputs_stack_overflow_variable_stack.json new file mode 100644 index 00000000..d83e86a0 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/jumpf_with_inputs_stack_overflow_variable_stack.json @@ -0,0 +1,50 @@ +{ + "jumpf_with_inputs_stack_overflow_variable_stack": { + "vectors": { + "jumpf_with_inputs_stack_overflow_variable_stack_0": { + "code": "0xef00010100080200020407000204000000008003ff028000035f6000e100025f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe500015f00", + "results": { + "Prague": { + "result": true + } + } + }, + "jumpf_with_inputs_stack_overflow_variable_stack_1": { + "code": "0xef00010100080200020407000504000000008003ff028000065f6000e100025f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe500015f5f5f5f00", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "jumpf_with_inputs_stack_overflow_variable_stack_2": { + "code": "0xef00010100080200020407000304000000008003ff028000045f6000e100025f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe500015f5f00", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "jumpf_with_inputs_stack_overflow_variable_stack_3": { + "code": "0xef00010100080200020408000404000000008003ff028000055f6000e100025f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe500015f5f5f00", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + }, + "jumpf_with_inputs_stack_overflow_variable_stack_4": { + "code": "0xef00010100080200020408000204000000008003ff028000035f6000e100025f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe500015f00", + "results": { + "Prague": { + "exception": "EOF_StackOverflow", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/no_terminating_instruction.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/no_terminating_instruction.json new file mode 100644 index 00000000..dda6c5a1 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/no_terminating_instruction.json @@ -0,0 +1,33 @@ +{ + "no_terminating_instruction": { + "vectors": { + "no_terminating_instruction_0": { + "code": "0xef0001010004020001000104000000008000005f", + "results": { + "Prague": { + "exception": "EOF_InvalidCodeTermination", + "result": false + } + } + }, + "no_terminating_instruction_1": { + "code": "0xef0001010004020001000504000000008000006002600101", + "results": { + "Prague": { + "exception": "EOF_InvalidCodeTermination", + "result": false + } + } + }, + "no_terminating_instruction_2": { + "code": "0xef0001010004020001000504000000008000006001e1fffb", + "results": { + "Prague": { + "exception": "EOF_InvalidCodeTermination", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/non_constant_stack_height.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/non_constant_stack_height.json new file mode 100644 index 00000000..95903fbe --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/non_constant_stack_height.json @@ -0,0 +1,31 @@ +{ + "non_constant_stack_height": { + "vectors": { + "non_constant_stack_height_0": { + "code": "0xef0001010004020001000e04000000008000045fe100075f5f5fe10001505f5ffd", + "results": { + "Prague": { + "result": true + } + } + }, + "non_constant_stack_height_1": { + "code": "0xef0001010004020001000f04000000008000055f5fe100075f5f5fe10001505f5ffd", + "results": { + "Prague": { + "result": true + } + } + }, + "non_constant_stack_height_2": { + "code": "0xef0001010004020001000f04000000008000045fe100075f5f5fe1000150505f5ffd", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/retf_stack_validation.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/retf_stack_validation.json new file mode 100644 index 00000000..825c7b9a --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/retf_stack_validation.json @@ -0,0 +1,40 @@ +{ + "retf_stack_validation": { + "vectors": { + "retf_stack_validation_0": { + "code": "0xef000101000802000200040003040000000080000200020002e30001005f5fe4", + "results": { + "Prague": { + "result": true + } + } + }, + "retf_stack_validation_1": { + "code": "0xef000101000802000200040002040000000080000200020001e30001005fe4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "retf_stack_validation_2": { + "code": "0xef000101000802000200040004040000000080000200020003e30001005f5f5fe4", + "results": { + "Prague": { + "exception": "EOF_InvalidNumberOfOutputs", + "result": false + } + } + }, + "retf_stack_validation_3": { + "code": "0xef00010100080200020005000d0400000000800002010200025fe3000100e1000760016001e000025f5fe4", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/retf_variable_stack.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/retf_variable_stack.json new file mode 100644 index 00000000..0c0d2608 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/retf_variable_stack.json @@ -0,0 +1,42 @@ +{ + "retf_variable_stack": { + "vectors": { + "retf_variable_stack_0": { + "code": "0xef000101000802000200040009040000000080000500050003e30001005f6000e100025f5fe4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "retf_variable_stack_1": { + "code": "0xef000101000802000200040009040000000080000300030003e30001005f6000e100025f5fe4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "retf_variable_stack_2": { + "code": "0xef000101000802000200040009040000000080000100010003e30001005f6000e100025f5fe4", + "results": { + "Prague": { + "exception": "EOF_InvalidNumberOfOutputs", + "result": false + } + } + }, + "retf_variable_stack_3": { + "code": "0xef000101000802000200040009040000000080000000000003e30001005f6000e100025f5fe4", + "results": { + "Prague": { + "exception": "EOF_InvalidNumberOfOutputs", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/self_referencing_jumps.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/self_referencing_jumps.json new file mode 100644 index 00000000..7d6e1338 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/self_referencing_jumps.json @@ -0,0 +1,32 @@ +{ + "self_referencing_jumps": { + "vectors": { + "rjump": { + "code": "0xef000101000402000100030400000000800000e0fffd", + "results": { + "Prague": { + "result": true + } + } + }, + "rjumpi": { + "code": "0xef0001010004020001000604000000008000006000e1fffd00", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "rjumpv": { + "code": "0xef0001010004020001000704000000008000006000e200fffc00", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/self_referencing_jumps_variable_stack.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/self_referencing_jumps_variable_stack.json new file mode 100644 index 00000000..7c545a45 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/self_referencing_jumps_variable_stack.json @@ -0,0 +1,32 @@ +{ + "self_referencing_jumps_variable_stack": { + "vectors": { + "rjump": { + "code": "0xef0001010004020001000b04000000008000035f6000e100025f5fe0fffd", + "results": { + "Prague": { + "result": true + } + } + }, + "rjumpi": { + "code": "0xef0001010004020001000e04000000008000045f6000e100025f5f6000e1fffd00", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + }, + "rjumpv": { + "code": "0xef0001010004020001000f04000000008000045f6000e100025f5f6000e200fffc00", + "results": { + "Prague": { + "exception": "EOF_ConflictingStackHeight", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/stack_range_maximally_broad.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/stack_range_maximally_broad.json new file mode 100644 index 00000000..768020dc --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/stack_range_maximally_broad.json @@ -0,0 +1,23 @@ +{ + "stack_range_maximally_broad": { + "vectors": { + "invalid_1024_rjumpis": { + "code": "0xef0001010004020001140104000000008003ff5fe113fc5f5fe113f75f5fe113f25f5fe113ed5f5fe113e85f5fe113e35f5fe113de5f5fe113d95f5fe113d45f5fe113cf5f5fe113ca5f5fe113c55f5fe113c05f5fe113bb5f5fe113b65f5fe113b15f5fe113ac5f5fe113a75f5fe113a25f5fe1139d5f5fe113985f5fe113935f5fe1138e5f5fe113895f5fe113845f5fe1137f5f5fe1137a5f5fe113755f5fe113705f5fe1136b5f5fe113665f5fe113615f5fe1135c5f5fe113575f5fe113525f5fe1134d5f5fe113485f5fe113435f5fe1133e5f5fe113395f5fe113345f5fe1132f5f5fe1132a5f5fe113255f5fe113205f5fe1131b5f5fe113165f5fe113115f5fe1130c5f5fe113075f5fe113025f5fe112fd5f5fe112f85f5fe112f35f5fe112ee5f5fe112e95f5fe112e45f5fe112df5f5fe112da5f5fe112d55f5fe112d05f5fe112cb5f5fe112c65f5fe112c15f5fe112bc5f5fe112b75f5fe112b25f5fe112ad5f5fe112a85f5fe112a35f5fe1129e5f5fe112995f5fe112945f5fe1128f5f5fe1128a5f5fe112855f5fe112805f5fe1127b5f5fe112765f5fe112715f5fe1126c5f5fe112675f5fe112625f5fe1125d5f5fe112585f5fe112535f5fe1124e5f5fe112495f5fe112445f5fe1123f5f5fe1123a5f5fe112355f5fe112305f5fe1122b5f5fe112265f5fe112215f5fe1121c5f5fe112175f5fe112125f5fe1120d5f5fe112085f5fe112035f5fe111fe5f5fe111f95f5fe111f45f5fe111ef5f5fe111ea5f5fe111e55f5fe111e05f5fe111db5f5fe111d65f5fe111d15f5fe111cc5f5fe111c75f5fe111c25f5fe111bd5f5fe111b85f5fe111b35f5fe111ae5f5fe111a95f5fe111a45f5fe1119f5f5fe1119a5f5fe111955f5fe111905f5fe1118b5f5fe111865f5fe111815f5fe1117c5f5fe111775f5fe111725f5fe1116d5f5fe111685f5fe111635f5fe1115e5f5fe111595f5fe111545f5fe1114f5f5fe1114a5f5fe111455f5fe111405f5fe1113b5f5fe111365f5fe111315f5fe1112c5f5fe111275f5fe111225f5fe1111d5f5fe111185f5fe111135f5fe1110e5f5fe111095f5fe111045f5fe110ff5f5fe110fa5f5fe110f55f5fe110f05f5fe110eb5f5fe110e65f5fe110e15f5fe110dc5f5fe110d75f5fe110d25f5fe110cd5f5fe110c85f5fe110c35f5fe110be5f5fe110b95f5fe110b45f5fe110af5f5fe110aa5f5fe110a55f5fe110a05f5fe1109b5f5fe110965f5fe110915f5fe1108c5f5fe110875f5fe110825f5fe1107d5f5fe110785f5fe110735f5fe1106e5f5fe110695f5fe110645f5fe1105f5f5fe1105a5f5fe110555f5fe110505f5fe1104b5f5fe110465f5fe110415f5fe1103c5f5fe110375f5fe110325f5fe1102d5f5fe110285f5fe110235f5fe1101e5f5fe110195f5fe110145f5fe1100f5f5fe1100a5f5fe110055f5fe110005f5fe10ffb5f5fe10ff65f5fe10ff15f5fe10fec5f5fe10fe75f5fe10fe25f5fe10fdd5f5fe10fd85f5fe10fd35f5fe10fce5f5fe10fc95f5fe10fc45f5fe10fbf5f5fe10fba5f5fe10fb55f5fe10fb05f5fe10fab5f5fe10fa65f5fe10fa15f5fe10f9c5f5fe10f975f5fe10f925f5fe10f8d5f5fe10f885f5fe10f835f5fe10f7e5f5fe10f795f5fe10f745f5fe10f6f5f5fe10f6a5f5fe10f655f5fe10f605f5fe10f5b5f5fe10f565f5fe10f515f5fe10f4c5f5fe10f475f5fe10f425f5fe10f3d5f5fe10f385f5fe10f335f5fe10f2e5f5fe10f295f5fe10f245f5fe10f1f5f5fe10f1a5f5fe10f155f5fe10f105f5fe10f0b5f5fe10f065f5fe10f015f5fe10efc5f5fe10ef75f5fe10ef25f5fe10eed5f5fe10ee85f5fe10ee35f5fe10ede5f5fe10ed95f5fe10ed45f5fe10ecf5f5fe10eca5f5fe10ec55f5fe10ec05f5fe10ebb5f5fe10eb65f5fe10eb15f5fe10eac5f5fe10ea75f5fe10ea25f5fe10e9d5f5fe10e985f5fe10e935f5fe10e8e5f5fe10e895f5fe10e845f5fe10e7f5f5fe10e7a5f5fe10e755f5fe10e705f5fe10e6b5f5fe10e665f5fe10e615f5fe10e5c5f5fe10e575f5fe10e525f5fe10e4d5f5fe10e485f5fe10e435f5fe10e3e5f5fe10e395f5fe10e345f5fe10e2f5f5fe10e2a5f5fe10e255f5fe10e205f5fe10e1b5f5fe10e165f5fe10e115f5fe10e0c5f5fe10e075f5fe10e025f5fe10dfd5f5fe10df85f5fe10df35f5fe10dee5f5fe10de95f5fe10de45f5fe10ddf5f5fe10dda5f5fe10dd55f5fe10dd05f5fe10dcb5f5fe10dc65f5fe10dc15f5fe10dbc5f5fe10db75f5fe10db25f5fe10dad5f5fe10da85f5fe10da35f5fe10d9e5f5fe10d995f5fe10d945f5fe10d8f5f5fe10d8a5f5fe10d855f5fe10d805f5fe10d7b5f5fe10d765f5fe10d715f5fe10d6c5f5fe10d675f5fe10d625f5fe10d5d5f5fe10d585f5fe10d535f5fe10d4e5f5fe10d495f5fe10d445f5fe10d3f5f5fe10d3a5f5fe10d355f5fe10d305f5fe10d2b5f5fe10d265f5fe10d215f5fe10d1c5f5fe10d175f5fe10d125f5fe10d0d5f5fe10d085f5fe10d035f5fe10cfe5f5fe10cf95f5fe10cf45f5fe10cef5f5fe10cea5f5fe10ce55f5fe10ce05f5fe10cdb5f5fe10cd65f5fe10cd15f5fe10ccc5f5fe10cc75f5fe10cc25f5fe10cbd5f5fe10cb85f5fe10cb35f5fe10cae5f5fe10ca95f5fe10ca45f5fe10c9f5f5fe10c9a5f5fe10c955f5fe10c905f5fe10c8b5f5fe10c865f5fe10c815f5fe10c7c5f5fe10c775f5fe10c725f5fe10c6d5f5fe10c685f5fe10c635f5fe10c5e5f5fe10c595f5fe10c545f5fe10c4f5f5fe10c4a5f5fe10c455f5fe10c405f5fe10c3b5f5fe10c365f5fe10c315f5fe10c2c5f5fe10c275f5fe10c225f5fe10c1d5f5fe10c185f5fe10c135f5fe10c0e5f5fe10c095f5fe10c045f5fe10bff5f5fe10bfa5f5fe10bf55f5fe10bf05f5fe10beb5f5fe10be65f5fe10be15f5fe10bdc5f5fe10bd75f5fe10bd25f5fe10bcd5f5fe10bc85f5fe10bc35f5fe10bbe5f5fe10bb95f5fe10bb45f5fe10baf5f5fe10baa5f5fe10ba55f5fe10ba05f5fe10b9b5f5fe10b965f5fe10b915f5fe10b8c5f5fe10b875f5fe10b825f5fe10b7d5f5fe10b785f5fe10b735f5fe10b6e5f5fe10b695f5fe10b645f5fe10b5f5f5fe10b5a5f5fe10b555f5fe10b505f5fe10b4b5f5fe10b465f5fe10b415f5fe10b3c5f5fe10b375f5fe10b325f5fe10b2d5f5fe10b285f5fe10b235f5fe10b1e5f5fe10b195f5fe10b145f5fe10b0f5f5fe10b0a5f5fe10b055f5fe10b005f5fe10afb5f5fe10af65f5fe10af15f5fe10aec5f5fe10ae75f5fe10ae25f5fe10add5f5fe10ad85f5fe10ad35f5fe10ace5f5fe10ac95f5fe10ac45f5fe10abf5f5fe10aba5f5fe10ab55f5fe10ab05f5fe10aab5f5fe10aa65f5fe10aa15f5fe10a9c5f5fe10a975f5fe10a925f5fe10a8d5f5fe10a885f5fe10a835f5fe10a7e5f5fe10a795f5fe10a745f5fe10a6f5f5fe10a6a5f5fe10a655f5fe10a605f5fe10a5b5f5fe10a565f5fe10a515f5fe10a4c5f5fe10a475f5fe10a425f5fe10a3d5f5fe10a385f5fe10a335f5fe10a2e5f5fe10a295f5fe10a245f5fe10a1f5f5fe10a1a5f5fe10a155f5fe10a105f5fe10a0b5f5fe10a065f5fe10a015f5fe109fc5f5fe109f75f5fe109f25f5fe109ed5f5fe109e85f5fe109e35f5fe109de5f5fe109d95f5fe109d45f5fe109cf5f5fe109ca5f5fe109c55f5fe109c05f5fe109bb5f5fe109b65f5fe109b15f5fe109ac5f5fe109a75f5fe109a25f5fe1099d5f5fe109985f5fe109935f5fe1098e5f5fe109895f5fe109845f5fe1097f5f5fe1097a5f5fe109755f5fe109705f5fe1096b5f5fe109665f5fe109615f5fe1095c5f5fe109575f5fe109525f5fe1094d5f5fe109485f5fe109435f5fe1093e5f5fe109395f5fe109345f5fe1092f5f5fe1092a5f5fe109255f5fe109205f5fe1091b5f5fe109165f5fe109115f5fe1090c5f5fe109075f5fe109025f5fe108fd5f5fe108f85f5fe108f35f5fe108ee5f5fe108e95f5fe108e45f5fe108df5f5fe108da5f5fe108d55f5fe108d05f5fe108cb5f5fe108c65f5fe108c15f5fe108bc5f5fe108b75f5fe108b25f5fe108ad5f5fe108a85f5fe108a35f5fe1089e5f5fe108995f5fe108945f5fe1088f5f5fe1088a5f5fe108855f5fe108805f5fe1087b5f5fe108765f5fe108715f5fe1086c5f5fe108675f5fe108625f5fe1085d5f5fe108585f5fe108535f5fe1084e5f5fe108495f5fe108445f5fe1083f5f5fe1083a5f5fe108355f5fe108305f5fe1082b5f5fe108265f5fe108215f5fe1081c5f5fe108175f5fe108125f5fe1080d5f5fe108085f5fe108035f5fe107fe5f5fe107f95f5fe107f45f5fe107ef5f5fe107ea5f5fe107e55f5fe107e05f5fe107db5f5fe107d65f5fe107d15f5fe107cc5f5fe107c75f5fe107c25f5fe107bd5f5fe107b85f5fe107b35f5fe107ae5f5fe107a95f5fe107a45f5fe1079f5f5fe1079a5f5fe107955f5fe107905f5fe1078b5f5fe107865f5fe107815f5fe1077c5f5fe107775f5fe107725f5fe1076d5f5fe107685f5fe107635f5fe1075e5f5fe107595f5fe107545f5fe1074f5f5fe1074a5f5fe107455f5fe107405f5fe1073b5f5fe107365f5fe107315f5fe1072c5f5fe107275f5fe107225f5fe1071d5f5fe107185f5fe107135f5fe1070e5f5fe107095f5fe107045f5fe106ff5f5fe106fa5f5fe106f55f5fe106f05f5fe106eb5f5fe106e65f5fe106e15f5fe106dc5f5fe106d75f5fe106d25f5fe106cd5f5fe106c85f5fe106c35f5fe106be5f5fe106b95f5fe106b45f5fe106af5f5fe106aa5f5fe106a55f5fe106a05f5fe1069b5f5fe106965f5fe106915f5fe1068c5f5fe106875f5fe106825f5fe1067d5f5fe106785f5fe106735f5fe1066e5f5fe106695f5fe106645f5fe1065f5f5fe1065a5f5fe106555f5fe106505f5fe1064b5f5fe106465f5fe106415f5fe1063c5f5fe106375f5fe106325f5fe1062d5f5fe106285f5fe106235f5fe1061e5f5fe106195f5fe106145f5fe1060f5f5fe1060a5f5fe106055f5fe106005f5fe105fb5f5fe105f65f5fe105f15f5fe105ec5f5fe105e75f5fe105e25f5fe105dd5f5fe105d85f5fe105d35f5fe105ce5f5fe105c95f5fe105c45f5fe105bf5f5fe105ba5f5fe105b55f5fe105b05f5fe105ab5f5fe105a65f5fe105a15f5fe1059c5f5fe105975f5fe105925f5fe1058d5f5fe105885f5fe105835f5fe1057e5f5fe105795f5fe105745f5fe1056f5f5fe1056a5f5fe105655f5fe105605f5fe1055b5f5fe105565f5fe105515f5fe1054c5f5fe105475f5fe105425f5fe1053d5f5fe105385f5fe105335f5fe1052e5f5fe105295f5fe105245f5fe1051f5f5fe1051a5f5fe105155f5fe105105f5fe1050b5f5fe105065f5fe105015f5fe104fc5f5fe104f75f5fe104f25f5fe104ed5f5fe104e85f5fe104e35f5fe104de5f5fe104d95f5fe104d45f5fe104cf5f5fe104ca5f5fe104c55f5fe104c05f5fe104bb5f5fe104b65f5fe104b15f5fe104ac5f5fe104a75f5fe104a25f5fe1049d5f5fe104985f5fe104935f5fe1048e5f5fe104895f5fe104845f5fe1047f5f5fe1047a5f5fe104755f5fe104705f5fe1046b5f5fe104665f5fe104615f5fe1045c5f5fe104575f5fe104525f5fe1044d5f5fe104485f5fe104435f5fe1043e5f5fe104395f5fe104345f5fe1042f5f5fe1042a5f5fe104255f5fe104205f5fe1041b5f5fe104165f5fe104115f5fe1040c5f5fe104075f5fe104025f5fe103fd5f5fe103f85f5fe103f35f5fe103ee5f5fe103e95f5fe103e45f5fe103df5f5fe103da5f5fe103d55f5fe103d05f5fe103cb5f5fe103c65f5fe103c15f5fe103bc5f5fe103b75f5fe103b25f5fe103ad5f5fe103a85f5fe103a35f5fe1039e5f5fe103995f5fe103945f5fe1038f5f5fe1038a5f5fe103855f5fe103805f5fe1037b5f5fe103765f5fe103715f5fe1036c5f5fe103675f5fe103625f5fe1035d5f5fe103585f5fe103535f5fe1034e5f5fe103495f5fe103445f5fe1033f5f5fe1033a5f5fe103355f5fe103305f5fe1032b5f5fe103265f5fe103215f5fe1031c5f5fe103175f5fe103125f5fe1030d5f5fe103085f5fe103035f5fe102fe5f5fe102f95f5fe102f45f5fe102ef5f5fe102ea5f5fe102e55f5fe102e05f5fe102db5f5fe102d65f5fe102d15f5fe102cc5f5fe102c75f5fe102c25f5fe102bd5f5fe102b85f5fe102b35f5fe102ae5f5fe102a95f5fe102a45f5fe1029f5f5fe1029a5f5fe102955f5fe102905f5fe1028b5f5fe102865f5fe102815f5fe1027c5f5fe102775f5fe102725f5fe1026d5f5fe102685f5fe102635f5fe1025e5f5fe102595f5fe102545f5fe1024f5f5fe1024a5f5fe102455f5fe102405f5fe1023b5f5fe102365f5fe102315f5fe1022c5f5fe102275f5fe102225f5fe1021d5f5fe102185f5fe102135f5fe1020e5f5fe102095f5fe102045f5fe101ff5f5fe101fa5f5fe101f55f5fe101f05f5fe101eb5f5fe101e65f5fe101e15f5fe101dc5f5fe101d75f5fe101d25f5fe101cd5f5fe101c85f5fe101c35f5fe101be5f5fe101b95f5fe101b45f5fe101af5f5fe101aa5f5fe101a55f5fe101a05f5fe1019b5f5fe101965f5fe101915f5fe1018c5f5fe101875f5fe101825f5fe1017d5f5fe101785f5fe101735f5fe1016e5f5fe101695f5fe101645f5fe1015f5f5fe1015a5f5fe101555f5fe101505f5fe1014b5f5fe101465f5fe101415f5fe1013c5f5fe101375f5fe101325f5fe1012d5f5fe101285f5fe101235f5fe1011e5f5fe101195f5fe101145f5fe1010f5f5fe1010a5f5fe101055f5fe101005f5fe100fb5f5fe100f65f5fe100f15f5fe100ec5f5fe100e75f5fe100e25f5fe100dd5f5fe100d85f5fe100d35f5fe100ce5f5fe100c95f5fe100c45f5fe100bf5f5fe100ba5f5fe100b55f5fe100b05f5fe100ab5f5fe100a65f5fe100a15f5fe1009c5f5fe100975f5fe100925f5fe1008d5f5fe100885f5fe100835f5fe1007e5f5fe100795f5fe100745f5fe1006f5f5fe1006a5f5fe100655f5fe100605f5fe1005b5f5fe100565f5fe100515f5fe1004c5f5fe100475f5fe100425f5fe1003d5f5fe100385f5fe100335f5fe1002e5f5fe100295f5fe100245f5fe1001f5f5fe1001a5f5fe100155f5fe100105f5fe1000b5f5fe100065f5fe100015f00", + "results": { + "Prague": { + "exception": "EOF_InvalidMaxStackHeight", + "result": false + } + } + }, + "valid_1023_rjumpis": { + "code": "0xef000101000402000113fc04000000008003ff5fe113f75f5fe113f25f5fe113ed5f5fe113e85f5fe113e35f5fe113de5f5fe113d95f5fe113d45f5fe113cf5f5fe113ca5f5fe113c55f5fe113c05f5fe113bb5f5fe113b65f5fe113b15f5fe113ac5f5fe113a75f5fe113a25f5fe1139d5f5fe113985f5fe113935f5fe1138e5f5fe113895f5fe113845f5fe1137f5f5fe1137a5f5fe113755f5fe113705f5fe1136b5f5fe113665f5fe113615f5fe1135c5f5fe113575f5fe113525f5fe1134d5f5fe113485f5fe113435f5fe1133e5f5fe113395f5fe113345f5fe1132f5f5fe1132a5f5fe113255f5fe113205f5fe1131b5f5fe113165f5fe113115f5fe1130c5f5fe113075f5fe113025f5fe112fd5f5fe112f85f5fe112f35f5fe112ee5f5fe112e95f5fe112e45f5fe112df5f5fe112da5f5fe112d55f5fe112d05f5fe112cb5f5fe112c65f5fe112c15f5fe112bc5f5fe112b75f5fe112b25f5fe112ad5f5fe112a85f5fe112a35f5fe1129e5f5fe112995f5fe112945f5fe1128f5f5fe1128a5f5fe112855f5fe112805f5fe1127b5f5fe112765f5fe112715f5fe1126c5f5fe112675f5fe112625f5fe1125d5f5fe112585f5fe112535f5fe1124e5f5fe112495f5fe112445f5fe1123f5f5fe1123a5f5fe112355f5fe112305f5fe1122b5f5fe112265f5fe112215f5fe1121c5f5fe112175f5fe112125f5fe1120d5f5fe112085f5fe112035f5fe111fe5f5fe111f95f5fe111f45f5fe111ef5f5fe111ea5f5fe111e55f5fe111e05f5fe111db5f5fe111d65f5fe111d15f5fe111cc5f5fe111c75f5fe111c25f5fe111bd5f5fe111b85f5fe111b35f5fe111ae5f5fe111a95f5fe111a45f5fe1119f5f5fe1119a5f5fe111955f5fe111905f5fe1118b5f5fe111865f5fe111815f5fe1117c5f5fe111775f5fe111725f5fe1116d5f5fe111685f5fe111635f5fe1115e5f5fe111595f5fe111545f5fe1114f5f5fe1114a5f5fe111455f5fe111405f5fe1113b5f5fe111365f5fe111315f5fe1112c5f5fe111275f5fe111225f5fe1111d5f5fe111185f5fe111135f5fe1110e5f5fe111095f5fe111045f5fe110ff5f5fe110fa5f5fe110f55f5fe110f05f5fe110eb5f5fe110e65f5fe110e15f5fe110dc5f5fe110d75f5fe110d25f5fe110cd5f5fe110c85f5fe110c35f5fe110be5f5fe110b95f5fe110b45f5fe110af5f5fe110aa5f5fe110a55f5fe110a05f5fe1109b5f5fe110965f5fe110915f5fe1108c5f5fe110875f5fe110825f5fe1107d5f5fe110785f5fe110735f5fe1106e5f5fe110695f5fe110645f5fe1105f5f5fe1105a5f5fe110555f5fe110505f5fe1104b5f5fe110465f5fe110415f5fe1103c5f5fe110375f5fe110325f5fe1102d5f5fe110285f5fe110235f5fe1101e5f5fe110195f5fe110145f5fe1100f5f5fe1100a5f5fe110055f5fe110005f5fe10ffb5f5fe10ff65f5fe10ff15f5fe10fec5f5fe10fe75f5fe10fe25f5fe10fdd5f5fe10fd85f5fe10fd35f5fe10fce5f5fe10fc95f5fe10fc45f5fe10fbf5f5fe10fba5f5fe10fb55f5fe10fb05f5fe10fab5f5fe10fa65f5fe10fa15f5fe10f9c5f5fe10f975f5fe10f925f5fe10f8d5f5fe10f885f5fe10f835f5fe10f7e5f5fe10f795f5fe10f745f5fe10f6f5f5fe10f6a5f5fe10f655f5fe10f605f5fe10f5b5f5fe10f565f5fe10f515f5fe10f4c5f5fe10f475f5fe10f425f5fe10f3d5f5fe10f385f5fe10f335f5fe10f2e5f5fe10f295f5fe10f245f5fe10f1f5f5fe10f1a5f5fe10f155f5fe10f105f5fe10f0b5f5fe10f065f5fe10f015f5fe10efc5f5fe10ef75f5fe10ef25f5fe10eed5f5fe10ee85f5fe10ee35f5fe10ede5f5fe10ed95f5fe10ed45f5fe10ecf5f5fe10eca5f5fe10ec55f5fe10ec05f5fe10ebb5f5fe10eb65f5fe10eb15f5fe10eac5f5fe10ea75f5fe10ea25f5fe10e9d5f5fe10e985f5fe10e935f5fe10e8e5f5fe10e895f5fe10e845f5fe10e7f5f5fe10e7a5f5fe10e755f5fe10e705f5fe10e6b5f5fe10e665f5fe10e615f5fe10e5c5f5fe10e575f5fe10e525f5fe10e4d5f5fe10e485f5fe10e435f5fe10e3e5f5fe10e395f5fe10e345f5fe10e2f5f5fe10e2a5f5fe10e255f5fe10e205f5fe10e1b5f5fe10e165f5fe10e115f5fe10e0c5f5fe10e075f5fe10e025f5fe10dfd5f5fe10df85f5fe10df35f5fe10dee5f5fe10de95f5fe10de45f5fe10ddf5f5fe10dda5f5fe10dd55f5fe10dd05f5fe10dcb5f5fe10dc65f5fe10dc15f5fe10dbc5f5fe10db75f5fe10db25f5fe10dad5f5fe10da85f5fe10da35f5fe10d9e5f5fe10d995f5fe10d945f5fe10d8f5f5fe10d8a5f5fe10d855f5fe10d805f5fe10d7b5f5fe10d765f5fe10d715f5fe10d6c5f5fe10d675f5fe10d625f5fe10d5d5f5fe10d585f5fe10d535f5fe10d4e5f5fe10d495f5fe10d445f5fe10d3f5f5fe10d3a5f5fe10d355f5fe10d305f5fe10d2b5f5fe10d265f5fe10d215f5fe10d1c5f5fe10d175f5fe10d125f5fe10d0d5f5fe10d085f5fe10d035f5fe10cfe5f5fe10cf95f5fe10cf45f5fe10cef5f5fe10cea5f5fe10ce55f5fe10ce05f5fe10cdb5f5fe10cd65f5fe10cd15f5fe10ccc5f5fe10cc75f5fe10cc25f5fe10cbd5f5fe10cb85f5fe10cb35f5fe10cae5f5fe10ca95f5fe10ca45f5fe10c9f5f5fe10c9a5f5fe10c955f5fe10c905f5fe10c8b5f5fe10c865f5fe10c815f5fe10c7c5f5fe10c775f5fe10c725f5fe10c6d5f5fe10c685f5fe10c635f5fe10c5e5f5fe10c595f5fe10c545f5fe10c4f5f5fe10c4a5f5fe10c455f5fe10c405f5fe10c3b5f5fe10c365f5fe10c315f5fe10c2c5f5fe10c275f5fe10c225f5fe10c1d5f5fe10c185f5fe10c135f5fe10c0e5f5fe10c095f5fe10c045f5fe10bff5f5fe10bfa5f5fe10bf55f5fe10bf05f5fe10beb5f5fe10be65f5fe10be15f5fe10bdc5f5fe10bd75f5fe10bd25f5fe10bcd5f5fe10bc85f5fe10bc35f5fe10bbe5f5fe10bb95f5fe10bb45f5fe10baf5f5fe10baa5f5fe10ba55f5fe10ba05f5fe10b9b5f5fe10b965f5fe10b915f5fe10b8c5f5fe10b875f5fe10b825f5fe10b7d5f5fe10b785f5fe10b735f5fe10b6e5f5fe10b695f5fe10b645f5fe10b5f5f5fe10b5a5f5fe10b555f5fe10b505f5fe10b4b5f5fe10b465f5fe10b415f5fe10b3c5f5fe10b375f5fe10b325f5fe10b2d5f5fe10b285f5fe10b235f5fe10b1e5f5fe10b195f5fe10b145f5fe10b0f5f5fe10b0a5f5fe10b055f5fe10b005f5fe10afb5f5fe10af65f5fe10af15f5fe10aec5f5fe10ae75f5fe10ae25f5fe10add5f5fe10ad85f5fe10ad35f5fe10ace5f5fe10ac95f5fe10ac45f5fe10abf5f5fe10aba5f5fe10ab55f5fe10ab05f5fe10aab5f5fe10aa65f5fe10aa15f5fe10a9c5f5fe10a975f5fe10a925f5fe10a8d5f5fe10a885f5fe10a835f5fe10a7e5f5fe10a795f5fe10a745f5fe10a6f5f5fe10a6a5f5fe10a655f5fe10a605f5fe10a5b5f5fe10a565f5fe10a515f5fe10a4c5f5fe10a475f5fe10a425f5fe10a3d5f5fe10a385f5fe10a335f5fe10a2e5f5fe10a295f5fe10a245f5fe10a1f5f5fe10a1a5f5fe10a155f5fe10a105f5fe10a0b5f5fe10a065f5fe10a015f5fe109fc5f5fe109f75f5fe109f25f5fe109ed5f5fe109e85f5fe109e35f5fe109de5f5fe109d95f5fe109d45f5fe109cf5f5fe109ca5f5fe109c55f5fe109c05f5fe109bb5f5fe109b65f5fe109b15f5fe109ac5f5fe109a75f5fe109a25f5fe1099d5f5fe109985f5fe109935f5fe1098e5f5fe109895f5fe109845f5fe1097f5f5fe1097a5f5fe109755f5fe109705f5fe1096b5f5fe109665f5fe109615f5fe1095c5f5fe109575f5fe109525f5fe1094d5f5fe109485f5fe109435f5fe1093e5f5fe109395f5fe109345f5fe1092f5f5fe1092a5f5fe109255f5fe109205f5fe1091b5f5fe109165f5fe109115f5fe1090c5f5fe109075f5fe109025f5fe108fd5f5fe108f85f5fe108f35f5fe108ee5f5fe108e95f5fe108e45f5fe108df5f5fe108da5f5fe108d55f5fe108d05f5fe108cb5f5fe108c65f5fe108c15f5fe108bc5f5fe108b75f5fe108b25f5fe108ad5f5fe108a85f5fe108a35f5fe1089e5f5fe108995f5fe108945f5fe1088f5f5fe1088a5f5fe108855f5fe108805f5fe1087b5f5fe108765f5fe108715f5fe1086c5f5fe108675f5fe108625f5fe1085d5f5fe108585f5fe108535f5fe1084e5f5fe108495f5fe108445f5fe1083f5f5fe1083a5f5fe108355f5fe108305f5fe1082b5f5fe108265f5fe108215f5fe1081c5f5fe108175f5fe108125f5fe1080d5f5fe108085f5fe108035f5fe107fe5f5fe107f95f5fe107f45f5fe107ef5f5fe107ea5f5fe107e55f5fe107e05f5fe107db5f5fe107d65f5fe107d15f5fe107cc5f5fe107c75f5fe107c25f5fe107bd5f5fe107b85f5fe107b35f5fe107ae5f5fe107a95f5fe107a45f5fe1079f5f5fe1079a5f5fe107955f5fe107905f5fe1078b5f5fe107865f5fe107815f5fe1077c5f5fe107775f5fe107725f5fe1076d5f5fe107685f5fe107635f5fe1075e5f5fe107595f5fe107545f5fe1074f5f5fe1074a5f5fe107455f5fe107405f5fe1073b5f5fe107365f5fe107315f5fe1072c5f5fe107275f5fe107225f5fe1071d5f5fe107185f5fe107135f5fe1070e5f5fe107095f5fe107045f5fe106ff5f5fe106fa5f5fe106f55f5fe106f05f5fe106eb5f5fe106e65f5fe106e15f5fe106dc5f5fe106d75f5fe106d25f5fe106cd5f5fe106c85f5fe106c35f5fe106be5f5fe106b95f5fe106b45f5fe106af5f5fe106aa5f5fe106a55f5fe106a05f5fe1069b5f5fe106965f5fe106915f5fe1068c5f5fe106875f5fe106825f5fe1067d5f5fe106785f5fe106735f5fe1066e5f5fe106695f5fe106645f5fe1065f5f5fe1065a5f5fe106555f5fe106505f5fe1064b5f5fe106465f5fe106415f5fe1063c5f5fe106375f5fe106325f5fe1062d5f5fe106285f5fe106235f5fe1061e5f5fe106195f5fe106145f5fe1060f5f5fe1060a5f5fe106055f5fe106005f5fe105fb5f5fe105f65f5fe105f15f5fe105ec5f5fe105e75f5fe105e25f5fe105dd5f5fe105d85f5fe105d35f5fe105ce5f5fe105c95f5fe105c45f5fe105bf5f5fe105ba5f5fe105b55f5fe105b05f5fe105ab5f5fe105a65f5fe105a15f5fe1059c5f5fe105975f5fe105925f5fe1058d5f5fe105885f5fe105835f5fe1057e5f5fe105795f5fe105745f5fe1056f5f5fe1056a5f5fe105655f5fe105605f5fe1055b5f5fe105565f5fe105515f5fe1054c5f5fe105475f5fe105425f5fe1053d5f5fe105385f5fe105335f5fe1052e5f5fe105295f5fe105245f5fe1051f5f5fe1051a5f5fe105155f5fe105105f5fe1050b5f5fe105065f5fe105015f5fe104fc5f5fe104f75f5fe104f25f5fe104ed5f5fe104e85f5fe104e35f5fe104de5f5fe104d95f5fe104d45f5fe104cf5f5fe104ca5f5fe104c55f5fe104c05f5fe104bb5f5fe104b65f5fe104b15f5fe104ac5f5fe104a75f5fe104a25f5fe1049d5f5fe104985f5fe104935f5fe1048e5f5fe104895f5fe104845f5fe1047f5f5fe1047a5f5fe104755f5fe104705f5fe1046b5f5fe104665f5fe104615f5fe1045c5f5fe104575f5fe104525f5fe1044d5f5fe104485f5fe104435f5fe1043e5f5fe104395f5fe104345f5fe1042f5f5fe1042a5f5fe104255f5fe104205f5fe1041b5f5fe104165f5fe104115f5fe1040c5f5fe104075f5fe104025f5fe103fd5f5fe103f85f5fe103f35f5fe103ee5f5fe103e95f5fe103e45f5fe103df5f5fe103da5f5fe103d55f5fe103d05f5fe103cb5f5fe103c65f5fe103c15f5fe103bc5f5fe103b75f5fe103b25f5fe103ad5f5fe103a85f5fe103a35f5fe1039e5f5fe103995f5fe103945f5fe1038f5f5fe1038a5f5fe103855f5fe103805f5fe1037b5f5fe103765f5fe103715f5fe1036c5f5fe103675f5fe103625f5fe1035d5f5fe103585f5fe103535f5fe1034e5f5fe103495f5fe103445f5fe1033f5f5fe1033a5f5fe103355f5fe103305f5fe1032b5f5fe103265f5fe103215f5fe1031c5f5fe103175f5fe103125f5fe1030d5f5fe103085f5fe103035f5fe102fe5f5fe102f95f5fe102f45f5fe102ef5f5fe102ea5f5fe102e55f5fe102e05f5fe102db5f5fe102d65f5fe102d15f5fe102cc5f5fe102c75f5fe102c25f5fe102bd5f5fe102b85f5fe102b35f5fe102ae5f5fe102a95f5fe102a45f5fe1029f5f5fe1029a5f5fe102955f5fe102905f5fe1028b5f5fe102865f5fe102815f5fe1027c5f5fe102775f5fe102725f5fe1026d5f5fe102685f5fe102635f5fe1025e5f5fe102595f5fe102545f5fe1024f5f5fe1024a5f5fe102455f5fe102405f5fe1023b5f5fe102365f5fe102315f5fe1022c5f5fe102275f5fe102225f5fe1021d5f5fe102185f5fe102135f5fe1020e5f5fe102095f5fe102045f5fe101ff5f5fe101fa5f5fe101f55f5fe101f05f5fe101eb5f5fe101e65f5fe101e15f5fe101dc5f5fe101d75f5fe101d25f5fe101cd5f5fe101c85f5fe101c35f5fe101be5f5fe101b95f5fe101b45f5fe101af5f5fe101aa5f5fe101a55f5fe101a05f5fe1019b5f5fe101965f5fe101915f5fe1018c5f5fe101875f5fe101825f5fe1017d5f5fe101785f5fe101735f5fe1016e5f5fe101695f5fe101645f5fe1015f5f5fe1015a5f5fe101555f5fe101505f5fe1014b5f5fe101465f5fe101415f5fe1013c5f5fe101375f5fe101325f5fe1012d5f5fe101285f5fe101235f5fe1011e5f5fe101195f5fe101145f5fe1010f5f5fe1010a5f5fe101055f5fe101005f5fe100fb5f5fe100f65f5fe100f15f5fe100ec5f5fe100e75f5fe100e25f5fe100dd5f5fe100d85f5fe100d35f5fe100ce5f5fe100c95f5fe100c45f5fe100bf5f5fe100ba5f5fe100b55f5fe100b05f5fe100ab5f5fe100a65f5fe100a15f5fe1009c5f5fe100975f5fe100925f5fe1008d5f5fe100885f5fe100835f5fe1007e5f5fe100795f5fe100745f5fe1006f5f5fe1006a5f5fe100655f5fe100605f5fe1005b5f5fe100565f5fe100515f5fe1004c5f5fe100475f5fe100425f5fe1003d5f5fe100385f5fe100335f5fe1002e5f5fe100295f5fe100245f5fe1001f5f5fe1001a5f5fe100155f5fe100105f5fe1000b5f5fe100065f5fe100015f00", + "results": { + "Prague": { + "result": true + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/swapn_stack_validation.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/swapn_stack_validation.json new file mode 100644 index 00000000..276041f4 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/swapn_stack_validation.json @@ -0,0 +1,58 @@ +{ + "swapn_stack_validation": { + "vectors": { + "swapn_stack_validation_0": { + "code": "0xef0001010004020001002b040000000080001460016001600160016001600160016001600160016001600160016001600160016001600160016001e70000", + "results": { + "Prague": { + "result": true + } + } + }, + "swapn_stack_validation_1": { + "code": "0xef0001010004020001002b040000000080001460016001600160016001600160016001600160016001600160016001600160016001600160016001e71200", + "results": { + "Prague": { + "result": true + } + } + }, + "swapn_stack_validation_2": { + "code": "0xef0001010004020001002b040000000080001460016001600160016001600160016001600160016001600160016001600160016001600160016001e71300", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "swapn_stack_validation_3": { + "code": "0xef0001010004020001002b040000000080001460016001600160016001600160016001600160016001600160016001600160016001600160016001e7d000", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "swapn_stack_validation_4": { + "code": "0xef0001010004020001002b040000000080001460016001600160016001600160016001600160016001600160016001600160016001600160016001e7fe00", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "swapn_stack_validation_5": { + "code": "0xef0001010004020001002b040000000080001460016001600160016001600160016001600160016001600160016001600160016001600160016001e7ff00", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/underflow.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/underflow.json new file mode 100644 index 00000000..e44554ec --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/underflow.json @@ -0,0 +1,51 @@ +{ + "underflow": { + "vectors": { + "underflow_0": { + "code": "0xef0001010004020001000204000000008000000100", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "underflow_1": { + "code": "0xef000101000802000200040002040000000080000101020002e30001005fe4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "underflow_2": { + "code": "0xef000101000c02000300040003000204000000008000020002000001020002e3000100e500025fe4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "underflow_3": { + "code": "0xef000101000802000200030005040000000080000001800003e5000160006000fd", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "underflow_4": { + "code": "0xef000101000802000200040002040000000080000200020001e30001005fe4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/underflow_variable_stack.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/underflow_variable_stack.json new file mode 100644 index 00000000..035174da --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/underflow_variable_stack.json @@ -0,0 +1,96 @@ +{ + "underflow_variable_stack": { + "vectors": { + "underflow_variable_stack_0": { + "code": "0xef0001010004020001000a04000000008000035f6000e100025f5fa200", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "underflow_variable_stack_1": { + "code": "0xef0001010004020001000a04000000008000035f6000e100025f5f0100", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "underflow_variable_stack_2": { + "code": "0xef0001010008020002000c00020400000000800004040500055f6000e100025f5fe30001005fe4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "underflow_variable_stack_3": { + "code": "0xef0001010008020002000c00020400000000800004030400045f6000e100025f5fe30001005fe4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "underflow_variable_stack_4": { + "code": "0xef000101000c0200030004000b000304000000008000030003000305030003e30001005f6000e100025f5fe500025050e4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "underflow_variable_stack_5": { + "code": "0xef000101000c0200030004000b000104000000008000030003000303030003e30001005f6000e100025f5fe50002e4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "underflow_variable_stack_6": { + "code": "0xef0001010008020002000b00050400000000800000058000075f6000e100025f5fe5000160006000fd", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "underflow_variable_stack_7": { + "code": "0xef0001010008020002000b00050400000000800000038000055f6000e100025f5fe5000160006000fd", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "underflow_variable_stack_8": { + "code": "0xef000101000802000200040009040000000080000500050003e30001005f6000e100025f5fe4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + }, + "underflow_variable_stack_9": { + "code": "0xef000101000802000200040009040000000080000300030003e30001005f6000e100025f5fe4", + "results": { + "Prague": { + "exception": "EOF_StackUnderflow", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/stack/unreachable_instructions.json b/crates/interpreter/tests/EOFTests/eof_validation/stack/unreachable_instructions.json new file mode 100644 index 00000000..fe8ac098 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/stack/unreachable_instructions.json @@ -0,0 +1,33 @@ +{ + "unreachable_instructions": { + "vectors": { + "unreachable_instructions_0": { + "code": "0xef0001010004020001000204000000008000000000", + "results": { + "Prague": { + "exception": "EOF_UnreachableCode", + "result": false + } + } + }, + "unreachable_instructions_1": { + "code": "0xef000101000402000100050400000000800000e000010000", + "results": { + "Prague": { + "exception": "EOF_UnreachableCode", + "result": false + } + } + }, + "unreachable_instructions_2": { + "code": "0xef000101000402000100070400000000800000e0000100e0fffc", + "results": { + "Prague": { + "exception": "EOF_UnreachableCode", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/too_many_code_sections.json b/crates/interpreter/tests/EOFTests/eof_validation/too_many_code_sections.json new file mode 100644 index 00000000..485b8987 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/too_many_code_sections.json @@ -0,0 +1,15 @@ +{ + "too_many_code_sections": { + "vectors": { + "too_many_code_sections_0": { + "code": "0xef0001011004020401000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010400000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "results": { + "Prague": { + "exception": "EOF_TooManyCodeSections", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/unreachable_code_sections.json b/crates/interpreter/tests/EOFTests/eof_validation/unreachable_code_sections.json new file mode 100644 index 00000000..9c7d8d3b --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/unreachable_code_sections.json @@ -0,0 +1,78 @@ +{ + "unreachable_code_sections": { + "vectors": { + "unreachable_code_sections_0": { + "code": "0xef000101000802000200010001040000000080000000800000fefe", + "results": { + "Prague": { + "exception": "EOF_UnreachableCodeSections", + "result": false + } + } + }, + "unreachable_code_sections_1": { + "code": "0xef000101000c02000300040002000104000000008000000000000000800000e30001005be4fe", + "results": { + "Prague": { + "exception": "EOF_UnreachableCodeSections", + "result": false + } + } + }, + "unreachable_code_sections_2": { + "code": "0xef000101000c02000300040001000204000000008000000080000000000000e3000200fe5be4", + "results": { + "Prague": { + "exception": "EOF_UnreachableCodeSections", + "result": false + } + } + }, + "unreachable_code_sections_3": { + "code": "0xef000101001002000400040001000200040400000000800000008000000000000000000000e3000300fe5be4e30002e4", + "results": { + "Prague": { + "exception": "EOF_UnreachableCodeSections", + "result": false + } + } + }, + "unreachable_code_sections_4": { + "code": "0xef000101000802000200030003040000000080000000800000e50000e50001", + "results": { + "Prague": { + "exception": "EOF_UnreachableCodeSections", + "result": false + } + } + }, + "unreachable_code_sections_5": { + "code": "0xef000101000c02000300030001000204000000008000000080000000000000e50001005be4", + "results": { + "Prague": { + "exception": "EOF_UnreachableCodeSections", + "result": false + } + } + }, + "unreachable_code_sections_6": { + "code": "0xef000101040002010000030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300040400000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000e50001e50001e50003e50004e50005e50006e50007e50008e50009e5000ae5000be5000ce5000de5000ee5000fe50010e50011e50012e50013e50014e50015e50016e50017e50018e50019e5001ae5001be5001ce5001de5001ee5001fe50020e50021e50022e50023e50024e50025e50026e50027e50028e50029e5002ae5002be5002ce5002de5002ee5002fe50030e50031e50032e50033e50034e50035e50036e50037e50038e50039e5003ae5003be5003ce5003de5003ee5003fe50040e50041e50042e50043e50044e50045e50046e50047e50048e50049e5004ae5004be5004ce5004de5004ee5004fe50050e50051e50052e50053e50054e50055e50056e50057e50058e50059e5005ae5005be5005ce5005de5005ee5005fe50060e50061e50062e50063e50064e50065e50066e50067e50068e50069e5006ae5006be5006ce5006de5006ee5006fe50070e50071e50072e50073e50074e50075e50076e50077e50078e50079e5007ae5007be5007ce5007de5007ee5007fe50080e50081e50082e50083e50084e50085e50086e50087e50088e50089e5008ae5008be5008ce5008de5008ee5008fe50090e50091e50092e50093e50094e50095e50096e50097e50098e50099e5009ae5009be5009ce5009de5009ee5009fe500a0e500a1e500a2e500a3e500a4e500a5e500a6e500a7e500a8e500a9e500aae500abe500ace500ade500aee500afe500b0e500b1e500b2e500b3e500b4e500b5e500b6e500b7e500b8e500b9e500bae500bbe500bce500bde500bee500bfe500c0e500c1e500c2e500c3e500c4e500c5e500c6e500c7e500c8e500c9e500cae500cbe500cce500cde500cee500cfe500d0e500d1e500d2e500d3e500d4e500d5e500d6e500d7e500d8e500d9e500dae500dbe500dce500dde500dee500dfe500e0e500e1e500e2e500e3e500e4e500e5e500e6e500e7e500e8e500e9e500eae500ebe500ece500ede500eee500efe500f0e500f1e500f2e500f3e500f4e500f5e500f6e500f7e500f8e500f9e500fae500fbe500fce500fde500fee500ff5b5b5b00", + "results": { + "Prague": { + "exception": "EOF_UnreachableCodeSections", + "result": false + } + } + }, + "unreachable_code_sections_7": { + "code": "0xef000101040002010000030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300030003000300040400000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000e50001e50002e50003e50004e50005e50006e50007e50008e50009e5000ae5000be5000ce5000de5000ee5000fe50010e50011e50012e50013e50014e50015e50016e50017e50018e50019e5001ae5001be5001ce5001de5001ee5001fe50020e50021e50022e50023e50024e50025e50026e50027e50028e50029e5002ae5002be5002ce5002de5002ee5002fe50030e50031e50032e50033e50034e50035e50036e50037e50038e50039e5003ae5003be5003ce5003de5003ee5003fe50040e50041e50042e50043e50044e50045e50046e50047e50048e50049e5004ae5004be5004ce5004de5004ee5004fe50050e50051e50052e50053e50054e50055e50056e50057e50058e50059e5005ae5005be5005ce5005de5005ee5005fe50060e50061e50062e50063e50064e50065e50066e50067e50068e50069e5006ae5006be5006ce5006de5006ee5006fe50070e50071e50072e50073e50074e50075e50076e50077e50078e50079e5007ae5007be5007ce5007de5007ee5007fe50080e50081e50082e50083e50084e50085e50086e50087e50088e50089e5008ae5008be5008ce5008de5008ee5008fe50090e50091e50092e50093e50094e50095e50096e50097e50098e50099e5009ae5009be5009ce5009de5009ee5009fe500a0e500a1e500a2e500a3e500a4e500a5e500a6e500a7e500a8e500a9e500aae500abe500ace500ade500aee500afe500b0e500b1e500b2e500b3e500b4e500b5e500b6e500b7e500b8e500b9e500bae500bbe500bce500bde500bee500bfe500c0e500c1e500c2e500c3e500c4e500c5e500c6e500c7e500c8e500c9e500cae500cbe500cce500cde500cee500cfe500d0e500d1e500d2e500d3e500d4e500d5e500d6e500d7e500d8e500d9e500dae500dbe500dce500dde500dee500dfe500e0e500e1e500e2e500e3e500e4e500e5e500e6e500e7e500e8e500e9e500eae500ebe500ece500ede500eee500efe500f0e500f1e500f2e500f3e500f4e500f5e500f6e500f7e500f8e500f9e500fae500fbe500fce500fde500fee500fe5b5b5b00", + "results": { + "Prague": { + "exception": "EOF_UnreachableCodeSections", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/validate_EOF_prefix.json b/crates/interpreter/tests/EOFTests/eof_validation/validate_EOF_prefix.json new file mode 100644 index 00000000..0e11c22b --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/validate_EOF_prefix.json @@ -0,0 +1,87 @@ +{ + "validate_EOF_prefix": { + "vectors": { + "valid_except_magic": { + "code": "0xefff0101000402000100030300040000800000600000aabbccdd", + "results": { + "Prague": { + "exception": "EOF_InvalidPrefix", + "result": false + } + } + }, + "validate_EOF_prefix_0": { + "code": "0x00", + "results": { + "Prague": { + "exception": "EOF_InvalidPrefix", + "result": false + } + } + }, + "validate_EOF_prefix_1": { + "code": "0xfe", + "results": { + "Prague": { + "exception": "EOF_InvalidPrefix", + "result": false + } + } + }, + "validate_EOF_prefix_2": { + "code": "0xef", + "results": { + "Prague": { + "exception": "EOF_InvalidPrefix", + "result": false + } + } + }, + "validate_EOF_prefix_3": { + "code": "0xef0101", + "results": { + "Prague": { + "exception": "EOF_InvalidPrefix", + "result": false + } + } + }, + "validate_EOF_prefix_4": { + "code": "0xefef01", + "results": { + "Prague": { + "exception": "EOF_InvalidPrefix", + "result": false + } + } + }, + "validate_EOF_prefix_5": { + "code": "0xefff01", + "results": { + "Prague": { + "exception": "EOF_InvalidPrefix", + "result": false + } + } + }, + "validate_EOF_prefix_6": { + "code": "0xef00", + "results": { + "Prague": { + "exception": "EOF_UnknownVersion", + "result": false + } + } + }, + "validate_EOF_prefix_7": { + "code": "0xef0001", + "results": { + "Prague": { + "exception": "EOF_SectionHeadersNotTerminated", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/validate_EOF_version.json b/crates/interpreter/tests/EOFTests/eof_validation/validate_EOF_version.json new file mode 100644 index 00000000..a55f4200 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/validate_EOF_version.json @@ -0,0 +1,51 @@ +{ + "validate_EOF_version": { + "vectors": { + "valid_except_version_00": { + "code": "0xef000001000402000100030200040000800000600000aabbccdd", + "results": { + "Prague": { + "exception": "EOF_UnknownVersion", + "result": false + } + } + }, + "valid_except_version_02": { + "code": "0xef000201000402000100030200040000800000600000aabbccdd", + "results": { + "Prague": { + "exception": "EOF_UnknownVersion", + "result": false + } + } + }, + "valid_except_version_FF": { + "code": "0xef00ff01000402000100030200040000800000600000aabbccdd", + "results": { + "Prague": { + "exception": "EOF_UnknownVersion", + "result": false + } + } + }, + "validate_EOF_version_0": { + "code": "0xef0002", + "results": { + "Prague": { + "exception": "EOF_UnknownVersion", + "result": false + } + } + }, + "validate_EOF_version_1": { + "code": "0xef00ff", + "results": { + "Prague": { + "exception": "EOF_UnknownVersion", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/eof_validation/validate_empty_code.json b/crates/interpreter/tests/EOFTests/eof_validation/validate_empty_code.json new file mode 100644 index 00000000..4f60ba26 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/eof_validation/validate_empty_code.json @@ -0,0 +1,15 @@ +{ + "validate_empty_code": { + "vectors": { + "validate_empty_code_0": { + "code": "0x", + "results": { + "Prague": { + "exception": "EOF_InvalidPrefix", + "result": false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/EOFTests/ori/validInvalid.json b/crates/interpreter/tests/EOFTests/ori/validInvalid.json new file mode 100644 index 00000000..2f33a251 --- /dev/null +++ b/crates/interpreter/tests/EOFTests/ori/validInvalid.json @@ -0,0 +1,677 @@ +{ + "validInvalid" : { + "_info" : { + "comment" : "Ori Pomerantz qbzzt1@gmail.com\nImplements EOF1I0001, EOF1I0002, EOF1I0003, EOF1I0004, EOF1I0005,\nEOF1I0006, EOF1I0007, EOF1I0008, EOF1I0009, EOF1I0010,\nEOF1I0011, EOF1I0012, EOF1I0013, EOF1I0014, EOF1I0015,\nEOF1I0016, EOF1I0017, EOF1I0018, EOF1I0019, EOF1I0020,\nEOF1I0021, EOF1I0022, EOF1I0023, EOF1I0024, EOF1I0025,\nEOF1V0001, EOF1V0002, EOF1V0003, EOF1V0004, EOF1V0005,\nEOF1V0006, EOF1V0007, EOF1V0008, EOF1V0009, EOF1V0010,\nEOF1V0011, EOF1V0012, EOF1V0013, EOF1V0014, EOF1V0015\n", + "filling-rpc-server" : "evmone-t8n 0.12.0-dev+commit.14ba7529", + "filling-tool-version" : "retesteth-0.3.2-cancun+commit.9d793abd.Linux.g++", + "generatedTestHash" : "42a674b5b1d41a51050ca56d5e2924a22edcd0e4f8b251913bfc7bb34c5d1457", + "lllcversion" : "Version: 0.5.14-develop.2022.4.6+commit.401d5358.Linux.g++", + "solidity" : "Version: 0.8.18-develop.2023.1.16+commit.469d6d4d.Linux.g++", + "source" : "src/EOFTestsFiller/ori/validInvalidFiller.yml", + "sourceHash" : "f4594e906050a1a0e30a17822dbb83cd4382fc613a1a7dac7f6b97360ba2e903" + }, + "vectors" : { + "validInvalid_0" : { + "code" : "0xef020101000402000100030400010000800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidPrefix", + "result" : false + } + } + }, + "validInvalid_1" : { + "code" : "0xef000001000402000100030400010000800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_UnknownVersion", + "result" : false + } + } + }, + "validInvalid_10" : { + "code" : "0xef000101000402000100010400010000800000efef", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_11" : { + "code" : "0xef0001010004020001000504000100008000013030505000ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidMaxStackHeight", + "result" : false + } + } + }, + "validInvalid_12" : { + "code" : "0xef0001010004020001000504000100008000033030505000ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidMaxStackHeight", + "result" : false + } + } + }, + "validInvalid_13" : { + "code" : "0xef00010100040200010004040001000080000130505000ef", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_14" : { + "code" : "0xef000101000c0200030037000b001f0400010000800400000a000a00640064e30002e30002e30002e30002e30002e30002e30002e30002e30002e300023030303030303030303030303030303030303030303030300030303030303030303030e4e30001e30001e30001e30001e30001e30001e30001e30001e30001e30001e4ef", + "results" : { + "Prague" : { + "exception" : "EOF_MaxStackHeightExceeded", + "result" : false + } + } + }, + "validInvalid_15" : { + "code" : "0xef000101000802000200070004040001000180000200000001300150e3000100305000e4ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidFirstSectionType", + "result" : false + } + } + }, + "validInvalid_16" : { + "code" : "0xef000101000802000200060003040001000001000200800001303001e50001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidFirstSectionType", + "result" : false + } + } + }, + "validInvalid_17" : { + "code" : "0xef000101000802000200040001040001000080000000800000e300020000ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidCodeSectionIndex", + "result" : false + } + } + }, + "validInvalid_18" : { + "code" : "0xef00010100040200010004040001000080000130015000ef", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_19" : { + "code" : "0xef0001010008020002000600040400010000800002020000005f80e3000100505050e4ef", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_2" : { + "code" : "0xef000201000402000100030400010000800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_UnknownVersion", + "result" : false + } + } + }, + "validInvalid_20" : { + "code" : "0xef0001010008020002000600050400010000800002020000035f80e300010082505050e4ef", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_21" : { + "code" : "0xef0001010008020002000600040400010000800002020000025f80e3000100915050e4ef", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_22" : { + "code" : "0xef000101000802000200040005040001000080000000000001e30001005b600056e4ef", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_23" : { + "code" : "0xef000101000802000200040007040001000080000000000001e30001005b6001600057e4ef", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_24" : { + "code" : "0xef00010100040200010006040001000080000260016002ff00ef", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_25" : { + "code" : "0xef0001010004020001001004000100008000076001600260036004600560066007f200ef", + "results" : { + "Prague" : { + "exception" : "EOF_UndefinedInstruction", + "result" : false + } + } + }, + "validInvalid_26" : { + "code" : "0xef000101000802000200040004040001000080000000000000e3000100e00010e4ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_27" : { + "code" : "0xef000101000802000200040004040001000080000000000000e3000100e0ff00e4ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_28" : { + "code" : "0xef000101000c02000300060004000104000100008000000000000000800000e30001e50002e00001e400ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_29" : { + "code" : "0xef000101000c02000300060004000104000100008000000000000000800000e30001e50002e0fffce400ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_3" : { + "code" : "0xef000102000100030400010100040000800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_TypeSectionMissing", + "result" : false + } + } + }, + "validInvalid_30" : { + "code" : "0xef000101000802000200060007040001000080000200020003e30001505000600160026003e4ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidNumberOfOutputs", + "result" : false + } + } + }, + "validInvalid_31" : { + "code" : "0xef000101000802000200040008040001000080000000000001e3000100e0000160ff60ffe4ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_32" : { + "code" : "0xef000101000802000200040009040001000080000000000001e30001006001e1000160ff50e4ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_33" : { + "code" : "0xef0001010004020001001304000100008000016001e204000000010001000200010060ff5000ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_34" : { + "code" : "0xef0001010004020001001304000100008000016001e204000000010001fffe00010060ff5000ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidJumpDestination", + "result" : false + } + } + }, + "validInvalid_35" : { + "code" : "0xef000101000402000100050400010000800000e000010000ef", + "results" : { + "Prague" : { + "exception" : "EOF_UnreachableCode", + "result" : false + } + } + }, + "validInvalid_36" : { + "code" : "0xef0001010004020001000a04000100008000016001e100020000305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_UnreachableCode", + "result" : false + } + } + }, + "validInvalid_37" : { + "code" : "0xef0001010004020001000f04000100008000016001e2010002000430500000305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_UnreachableCode", + "result" : false + } + } + }, + "validInvalid_38" : { + "code" : "0xef00010100080200020005000304000100008000010200000230e30001005050e4ef", + "results" : { + "Prague" : { + "exception" : "EOF_StackUnderflow", + "result" : false + } + } + }, + "validInvalid_39" : { + "code" : "0xef0001010004020001000804000100008000046000600060006000ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidCodeTermination", + "result" : false + } + } + }, + "validInvalid_4" : { + "code" : "0xef00010100040400010000800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_CodeSectionMissing", + "result" : false + } + } + }, + "validInvalid_40" : { + "code" : "0xef000101000402000100090400010000800004600060006000600001ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidCodeTermination", + "result" : false + } + } + }, + "validInvalid_41" : { + "code" : "0xef000101000402000100090400010000800004600060006000600034ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidCodeTermination", + "result" : false + } + } + }, + "validInvalid_42" : { + "code" : "0xef000101000402000100090400010000800004600060006000600003ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidCodeTermination", + "result" : false + } + } + }, + "validInvalid_43" : { + "code" : "0xef0001010004020001000d0400010000800006600060006000600060006000a4ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidCodeTermination", + "result" : false + } + } + }, + "validInvalid_44" : { + "code" : "0xef0001010004020001000304000100008000013050e4ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidNonReturningFlag", + "result" : false + } + } + }, + "validInvalid_45" : { + "code" : "0xef000101000402000100030400010000800001305000ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_46" : { + "code" : "0xef0001010008020002000600050400010000800001000000023050e300010030305050e4ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_47" : { + "code" : "0xef0001010010020004000600060006000304000100008000010000000100000001000000013050e30001003050e30002e43050e30003e43050e4ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_48" : { + "code" : "0xef000101000402000100030400060000800001305000ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_49" : { + "code" : "0xef000101000402000100010400010000800000feef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_5" : { + "code" : "0xef000101000402000100030000800001305000", + "results" : { + "Prague" : { + "exception" : "EOF_DataSectionMissing", + "result" : false + } + } + }, + "validInvalid_50" : { + "code" : "0xef0001010004020001000504000100008000023030505000ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_51" : { + "code" : "0xef000101000c0200030036000b001f04000100008003ff000a000a00640064e30002e30002e30002e30002e30002e30002e30002e30002e30002e3000230303030303030303030303030303030303030303030300030303030303030303030e4e30001e30001e30001e30001e30001e30001e30001e30001e30001e30001e4ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_52" : { + "code" : "0xef00010100080200020005000404000100008000010100000230e3000100300150e4ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_53" : { + "code" : "0xef0001010008020002000700040400010000800001000100023050e300015000303001e4ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_54" : { + "code" : "0xef0001010004020001000504000100008000023030015000ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_55" : { + "code" : "0xef0001010004020001000504000100008000013050e50000ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_56" : { + "code" : "0xef00010100080200020006000204000100008000010100000160ffe300010050e4ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_57" : { + "code" : "0xef0001010008020002000600050400010000800002020000035f80e300010081505050e4ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_58" : { + "code" : "0xef0001010008020002000600040400010000800002020000025f80e3000100905050e4ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_59" : { + "code" : "0xef000101000802000200030004040001000080000000800000e50001e0000000ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_6" : { + "code" : "0xef00010100040200010003040001ff00800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_HeaderTerminatorMissing", + "result" : false + } + } + }, + "validInvalid_60" : { + "code" : "0xef000101000802000200040009040001000080000000000001e30001006001e10001e4e0fffcef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_61" : { + "code" : "0xef000101000802000200040007040001000080000000000000e3000100e00000e00000e4ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_62" : { + "code" : "0xef000101000802000200030007040001000080000000800001e500016000e100003000ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_63" : { + "code" : "0xef000101000802000200030009040001000080000000800001e500016000e1000230503000ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_64" : { + "code" : "0xef000101000802000200030009040001000080000000800001e500016000e1000230503000ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_65" : { + "code" : "0xef000101000802000200030008040001000080000000800002e500016000e10001303000ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_66" : { + "code" : "0xef000101000802000200050003040001000080000100010001e30001500060ffe4ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_67" : { + "code" : "0xef0001010004020001000f04000100008000016001e2040000000000000000000000ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_68" : { + "code" : "0xef0001010004020001001204000100008000016001e2040000000100010000000100305000ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_69" : { + "code" : "0xef000101000402000100040400010000800000e0000000ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_7" : { + "code" : "0xef000101000802000100030400010000800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidSectionBodiesSize", + "result" : false + } + } + }, + "validInvalid_70" : { + "code" : "0xef0001010004020001000904000100008000016001e1000100305000ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_71" : { + "code" : "0xef0001010004020001000f04000100008000016001e2010002000430503050305000ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_72" : { + "code" : "0xef0001010008020002000600030400010000800002020000023030e30001005050e4ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_73" : { + "code" : "0xef000101000402000100090400010000800004600060006000600000ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_74" : { + "code" : "0xef0001010004020001000904000100008000046000600060006000f3ef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_75" : { + "code" : "0xef0001010004020001000904000100008000046000600060006000fdef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_76" : { + "code" : "0xef0001010004020001000904000100008000046000600060006000feef", + "results" : { + "Prague" : { + "result" : true + } + } + }, + "validInvalid_8" : { + "code" : "0xef000101000402000100030400010000800001305000000bad", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidSectionBodiesSize", + "result" : false + } + } + }, + "validInvalid_9" : { + "code" : "0xef000101000302000100030400010000800001305000ef", + "results" : { + "Prague" : { + "exception" : "EOF_InvalidSectionBodiesSize", + "result" : false + } + } + } + } + } +} \ No newline at end of file diff --git a/crates/interpreter/tests/eof.rs b/crates/interpreter/tests/eof.rs new file mode 100644 index 00000000..84bfc347 --- /dev/null +++ b/crates/interpreter/tests/eof.rs @@ -0,0 +1,184 @@ +use revm_interpreter::analysis::{validate_raw_eof, EofError}; +use revm_primitives::{Bytes, Eof}; +use serde::Deserialize; +use std::{ + collections::BTreeMap, + path::{Path, PathBuf}, + time::Instant, +}; +use walkdir::{DirEntry, WalkDir}; + +/* +Types of error: { + FalsePossitive: 1, + Error( + Validation( + OpcodeDisabled, + ), + ): 19, +} +*/ +#[test] +fn eof_run_all_tests() { + let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests"); + run_test(&eof_tests) +} + +/* +Types of error: { + FalsePossitive: 1, +} +Passed tests: 1262/1263 +EOF_EofCreateWithTruncatedContainer TODO +*/ +#[test] +fn eof_validation() { + let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/eof_validation"); + run_test(&eof_tests) +} + +/* +Types of error: { + OpcodeDisabled: 8, +} +Passed tests: 194/202 +Probably same as below. +*/ +#[test] +fn eof_validation_eip5450() { + let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP5450"); + run_test(&eof_tests) +} + +/* +Types of error: { + OpcodeDisabled: 9, +} +Passed tests: 290/299 + */ +// 0x60018080808080fa00 STATICCALL validInvalid - validInvalid_89 +// 0x60018080808080f400 DELEGATECALL validInvalid - validInvalid_88 +// 0x60018080808080f400 CALL validInvalid - validInvalid_86 +// 0x38e4 CODESIZE validInvalid - validInvalid_4 +// 0x60013f00 EXTCODEHASH validInvalid - validInvalid_39 +// 0x60018080803c00 EXTCODECOPY validInvalid - validInvalid_37 +// 0x60013b00 EXTCODESIZE validInvalid - validInvalid_36 +// 0x600180803900 CODECOPY validInvalid - validInvalid_35 +// 0x5a00 GAS validInvalid - validInvalid_60 +// 0xfe opcode is considered valid, should it be disabled? +#[test] +fn eof_validation_eip3670() { + let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP3670"); + run_test(&eof_tests) +} + +/// PASSING ALL +#[test] +fn eof_validation_eip4750() { + let inst = Instant::now(); + let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP4750"); + run_test(&eof_tests); + println!("Elapsed:{:?}", inst.elapsed()) +} + +/// PASSING ALL +#[test] +fn eof_validation_eip3540() { + let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP3540"); + run_test(&eof_tests) +} + +/// PASSING ALL +#[test] +fn eof_validation_eip4200() { + let eof_tests = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/EOFTests/EIP4200"); + run_test(&eof_tests); +} + +pub fn run_test(path: &Path) { + let test_files = find_all_json_tests(path); + let mut test_sum = 0; + let mut passed_tests = 0; + + #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + enum ErrorType { + FalsePositive, + Error(EofError), + } + let mut types_of_error: BTreeMap = BTreeMap::new(); + for test_file in test_files { + let s = std::fs::read_to_string(test_file).unwrap(); + let suite: TestSuite = serde_json::from_str(&s).unwrap(); + for (name, test_unit) in suite.0 { + for (vector_name, test_vector) in test_unit.vectors { + test_sum += 1; + let res = validate_raw_eof(test_vector.code.clone()); + if res.is_ok() != test_vector.results.prague.result { + let eof = Eof::decode(test_vector.code.clone()); + println!( + "\nTest failed: {} - {}\nresult:{:?}\nrevm err_result:{:#?}\nbytes:{:?}\n,eof:{eof:#?}", + name, + vector_name, + test_vector.results.prague, + res.as_ref().err(), + test_vector.code + ); + *types_of_error + .entry( + res.err() + .map(ErrorType::Error) + .unwrap_or(ErrorType::FalsePositive), + ) + .or_default() += 1; + } else { + //println!("Test passed: {} - {}", name, vector_name); + passed_tests += 1; + } + } + } + } + println!("Types of error: {:#?}", types_of_error); + println!("Passed tests: {}/{}", passed_tests, test_sum); +} + +pub fn find_all_json_tests(path: &Path) -> Vec { + WalkDir::new(path) + .into_iter() + .filter_map(|e| e.ok()) + .filter(|e| e.file_name().to_string_lossy().ends_with(".json")) + .map(DirEntry::into_path) + .collect::>() +} + +#[derive(Debug, PartialEq, Eq, Deserialize)] +pub struct TestSuite(pub BTreeMap); + +#[derive(Debug, PartialEq, Eq, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct TestUnit { + /// Test info is optional + #[serde(default, rename = "_info")] + pub info: Option, + + pub vectors: BTreeMap, +} + +#[derive(Debug, PartialEq, Eq, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct TestVector { + code: Bytes, + results: PragueResult, +} + +#[derive(Debug, PartialEq, Eq, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct PragueResult { + #[serde(rename = "Prague")] + prague: Result, +} + +#[derive(Debug, PartialEq, Eq, Deserialize)] +pub struct Result { + result: bool, + exception: Option, +} diff --git a/crates/precompile/src/blake2.rs b/crates/precompile/src/blake2.rs index 48b566bb..057bba74 100644 --- a/crates/precompile/src/blake2.rs +++ b/crates/precompile/src/blake2.rs @@ -81,7 +81,7 @@ pub mod algo { 0x5be0cd19137e2179, ]; - #[inline(always)] + #[inline] #[allow(clippy::many_single_char_names)] /// G function: pub fn g(v: &mut [u64], a: usize, b: usize, c: usize, d: usize, x: u64, y: u64) { diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index fd34bd63..aa3ffadf 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -245,7 +245,7 @@ impl PrecompileSpecId { BYZANTIUM | CONSTANTINOPLE | PETERSBURG => Self::BYZANTIUM, ISTANBUL | MUIR_GLACIER => Self::ISTANBUL, BERLIN | LONDON | ARROW_GLACIER | GRAY_GLACIER | MERGE | SHANGHAI => Self::BERLIN, - CANCUN => Self::CANCUN, + CANCUN | PRAGUE => Self::CANCUN, LATEST => Self::LATEST, #[cfg(feature = "optimism")] BEDROCK | REGOLITH | CANYON => Self::BERLIN, diff --git a/crates/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index 8fc436a9..538a57af 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -1,89 +1,44 @@ -use crate::{hex, keccak256, Bytes, B256, KECCAK_EMPTY}; -use bitvec::{ - prelude::{bitvec, Lsb0}, - vec::BitVec, -}; -use core::fmt::Debug; -use std::{sync::Arc, vec::Vec}; - -/// A map of valid `jump` destinations. -#[derive(Clone, Default, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct JumpMap(pub Arc>); +pub mod eof; +pub mod legacy; -impl Debug for JumpMap { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_struct("JumpMap") - .field("map", &hex::encode(self.0.as_raw_slice())) - .finish() - } -} - -impl JumpMap { - /// Get the raw bytes of the jump map - #[inline] - pub fn as_slice(&self) -> &[u8] { - self.0.as_raw_slice() - } +pub use eof::Eof; +pub use legacy::{JumpTable, LegacyAnalyzedBytecode}; - /// Construct a jump map from raw bytes - #[inline] - pub fn from_slice(slice: &[u8]) -> Self { - Self(Arc::new(BitVec::from_slice(slice))) - } - - /// Check if `pc` is a valid jump destination. - #[inline] - pub fn is_valid(&self, pc: usize) -> bool { - pc < self.0.len() && self.0[pc] - } -} +use crate::{keccak256, Bytes, B256, KECCAK_EMPTY}; /// State of the [`Bytecode`] analysis. #[derive(Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub enum BytecodeState { +pub enum Bytecode { /// No analysis has been performed. - Raw, - /// The bytecode has been checked for validity. - Checked { len: usize }, + LegacyRaw(Bytes), /// The bytecode has been analyzed for valid jump destinations. - Analysed { len: usize, jump_map: JumpMap }, -} - -#[derive(Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct Bytecode { - pub bytecode: Bytes, - pub state: BytecodeState, -} - -impl Debug for Bytecode { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_struct("Bytecode") - .field("bytecode", &self.bytecode) - .field("state", &self.state) - .finish() - } + LegacyAnalyzed(LegacyAnalyzedBytecode), + /// Ethereum Object Format + Eof(Eof), } impl Default for Bytecode { #[inline] fn default() -> Self { - Bytecode::new() + // Creates a new legacy analyzed [`Bytecode`] with exactly one STOP opcode. + Self::new() } } impl Bytecode { - /// Creates a new [`Bytecode`] with exactly one STOP opcode. + // Creates a new legacy analyzed [`Bytecode`] with exactly one STOP opcode. #[inline] pub fn new() -> Self { - Bytecode { - bytecode: Bytes::from_static(&[0]), - state: BytecodeState::Analysed { - len: 0, - jump_map: JumpMap(Arc::new(bitvec![u8, Lsb0; 0])), - }, + Self::LegacyAnalyzed(LegacyAnalyzedBytecode::default()) + } + + /// Return jump table if bytecode is analyzed + #[inline] + pub fn legacy_jump_table(&self) -> Option<&JumpTable> { + match &self { + Self::LegacyAnalyzed(analyzed) => Some(analyzed.jump_table()), + _ => None, } } @@ -96,13 +51,23 @@ impl Bytecode { } } + /// Return reference to the EOF if bytecode is EOF. + pub fn eof(&self) -> Option<&Eof> { + match self { + Self::Eof(eof) => Some(eof), + _ => None, + } + } + + /// Return true if bytecode is EOF. + pub fn is_eof(&self) -> bool { + matches!(self, Self::Eof(_)) + } + /// Creates a new raw [`Bytecode`]. #[inline] pub fn new_raw(bytecode: Bytes) -> Self { - Self { - bytecode, - state: BytecodeState::Raw, - } + Self::LegacyRaw(bytecode) } /// Create new checked bytecode. @@ -111,36 +76,55 @@ impl Bytecode { /// /// Bytecode needs to end with STOP (0x00) opcode as checked bytecode assumes /// that it is safe to iterate over bytecode without checking lengths. - pub unsafe fn new_checked(bytecode: Bytes, len: usize) -> Self { - Self { + pub unsafe fn new_analyzed( + bytecode: Bytes, + original_len: usize, + jump_table: JumpTable, + ) -> Self { + Self::LegacyAnalyzed(LegacyAnalyzedBytecode::new( bytecode, - state: BytecodeState::Checked { len }, - } + original_len, + jump_table, + )) } /// Returns a reference to the bytecode. + /// In case of EOF this will be the first code section. #[inline] - pub fn bytes(&self) -> &Bytes { - &self.bytecode + pub fn bytecode_bytes(&self) -> Bytes { + match self { + Self::LegacyRaw(bytes) => bytes.clone(), + Self::LegacyAnalyzed(analyzed) => analyzed.bytes(), + Self::Eof(eof) => eof + .body + .code(0) + .expect("Valid EOF has at least one code section") + .clone(), + } + } + + /// Returns false if bytecode can't be executed in Interpreter. + pub fn is_execution_ready(&self) -> bool { + !matches!(self, Self::LegacyRaw(_)) } /// Returns a reference to the original bytecode. #[inline] pub fn original_bytes(&self) -> Bytes { - match self.state { - BytecodeState::Raw => self.bytecode.clone(), - BytecodeState::Checked { len } | BytecodeState::Analysed { len, .. } => { - self.bytecode.slice(0..len) - } + match self { + Self::LegacyRaw(bytes) => bytes.clone(), + Self::LegacyAnalyzed(analyzed) => analyzed.original_bytes(), + Self::Eof(eof) => eof.raw().clone(), } } - /// Returns the length of the bytecode. + /// Returns the length of the raw bytes. #[inline] pub fn len(&self) -> usize { - match self.state { - BytecodeState::Raw => self.bytecode.len(), - BytecodeState::Checked { len, .. } | BytecodeState::Analysed { len, .. } => len, + match self { + Self::LegacyRaw(bytes) => bytes.len(), + Self::LegacyAnalyzed(analyzed) => analyzed.original_len(), + Self::Eof(eof) => eof.size(), } } @@ -149,26 +133,4 @@ impl Bytecode { pub fn is_empty(&self) -> bool { self.len() == 0 } - - /// Returns the [`BytecodeState`]. - #[inline] - pub fn state(&self) -> &BytecodeState { - &self.state - } - - pub fn to_checked(self) -> Self { - match self.state { - BytecodeState::Raw => { - let len = self.bytecode.len(); - let mut padded_bytecode = Vec::with_capacity(len + 33); - padded_bytecode.extend_from_slice(&self.bytecode); - padded_bytecode.resize(len + 33, 0); - Self { - bytecode: padded_bytecode.into(), - state: BytecodeState::Checked { len }, - } - } - _ => self, - } - } } diff --git a/crates/primitives/src/bytecode/eof.rs b/crates/primitives/src/bytecode/eof.rs new file mode 100644 index 00000000..67580c15 --- /dev/null +++ b/crates/primitives/src/bytecode/eof.rs @@ -0,0 +1,156 @@ +mod body; +mod decode_helpers; +mod header; +mod types_section; + +pub use body::EofBody; +pub use header::EofHeader; +pub use types_section::TypesSection; + +use crate::Bytes; +use core::cmp::min; +use std::{vec, vec::Vec}; + +/// EOF - Ethereum Object Format. +/// +/// It consist of a header, body and raw original bytes Specified in EIP. +/// Most of body contain Bytes so it references to the raw bytes. +/// +/// If there is a need to create new EOF from scratch, it is recommended to use `EofBody` and +/// use `encode` function to create full [`Eof`] object. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Eof { + pub header: EofHeader, + pub body: EofBody, + pub raw: Bytes, +} + +impl Default for Eof { + fn default() -> Self { + let body = EofBody { + // types section with zero inputs, zero outputs and zero max stack size. + types_section: vec![TypesSection::default()], + // One code section with a STOP byte. + code_section: vec![[0x00].into()], + container_section: vec![], + data_section: Bytes::new(), + is_data_filled: true, + }; + body.into_eof() + } +} + +impl Eof { + /// Returns len of the header and body in bytes. + pub fn size(&self) -> usize { + self.header.size() + self.header.body_size() + } + + /// Return raw EOF bytes. + pub fn raw(&self) -> &Bytes { + &self.raw + } + + /// Returns a slice of the raw bytes. + /// If offset is greater than the length of the raw bytes, an empty slice is returned. + /// If len is greater than the length of the raw bytes, the slice is truncated to the length of the raw bytes. + pub fn data_slice(&self, offset: usize, len: usize) -> &[u8] { + self.body + .data_section + .get(offset..) + .and_then(|bytes| bytes.get(..min(len, bytes.len()))) + .unwrap_or(&[]) + } + + /// Returns a slice of the data section. + pub fn data(&self) -> &[u8] { + &self.body.data_section + } + + /// Slow encode EOF bytes. + pub fn encode_slow(&self) -> Bytes { + let mut buffer: Vec = Vec::with_capacity(self.size()); + self.header.encode(&mut buffer); + self.body.encode(&mut buffer); + buffer.into() + } + + /// Decode EOF from raw bytes. + pub fn decode(raw: Bytes) -> Result { + let (header, _) = EofHeader::decode(&raw)?; + let body = EofBody::decode(&raw, &header)?; + Ok(Self { header, body, raw }) + } +} + +/// EOF decode errors. +#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] +pub enum EofDecodeError { + /// Short input while processing EOF. + MissingInput, + /// Short body while processing EOF. + MissingBodyWithoutData, + /// Body size is more than specified in the header. + DanglingData, + /// Invalid types section data. + InvalidTypesSection, + /// Invalid types section size. + InvalidTypesSectionSize, + /// Invalid EOF magic number. + InvalidEOFMagicNumber, + /// Invalid EOF version. + InvalidEOFVersion, + /// Invalid number for types kind + InvalidTypesKind, + /// Invalid number for code kind + InvalidCodeKind, + /// Invalid terminal code + InvalidTerminalByte, + /// Invalid data kind + InvalidDataKind, + /// Invalid kind after code + InvalidKindAfterCode, + /// Mismatch of code and types sizes. + MismatchCodeAndTypesSize, + /// There should be at least one size. + NonSizes, + /// Missing size. + ShortInputForSizes, + /// Size cant be zero + ZeroSize, + /// Invalid code number. + TooManyCodeSections, + /// Invalid number of code sections. + ZeroCodeSections, + /// Invalid container number. + TooManyContainerSections, +} + +#[cfg(test)] +mod test { + + use super::*; + use crate::bytes; + + #[test] + fn decode_eof() { + let bytes = bytes!("ef000101000402000100010400000000800000fe"); + let eof = Eof::decode(bytes.clone()).unwrap(); + assert_eq!(bytes, eof.encode_slow()); + } + + #[test] + fn data_slice() { + let bytes = bytes!("ef000101000402000100010400000000800000fe"); + let mut eof = Eof::decode(bytes.clone()).unwrap(); + eof.body.data_section = bytes!("01020304"); + assert_eq!(eof.data_slice(0, 1), &[0x01]); + assert_eq!(eof.data_slice(0, 4), &[0x01, 0x02, 0x03, 0x04]); + assert_eq!(eof.data_slice(0, 5), &[0x01, 0x02, 0x03, 0x04]); + assert_eq!(eof.data_slice(1, 2), &[0x02, 0x03]); + assert_eq!(eof.data_slice(10, 2), &[]); + assert_eq!(eof.data_slice(1, 0), &[]); + assert_eq!(eof.data_slice(10, 0), &[]); + } +} diff --git a/crates/primitives/src/bytecode/eof/body.rs b/crates/primitives/src/bytecode/eof/body.rs new file mode 100644 index 00000000..3759372b --- /dev/null +++ b/crates/primitives/src/bytecode/eof/body.rs @@ -0,0 +1,109 @@ +use super::{Eof, EofDecodeError, EofHeader, TypesSection}; +use crate::Bytes; +use std::vec::Vec; + +/// EOF Body, contains types, code, container and data sections. +/// +/// Can be used to create new EOF object. +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct EofBody { + pub types_section: Vec, + pub code_section: Vec, + pub container_section: Vec, + pub data_section: Bytes, + pub is_data_filled: bool, +} + +impl EofBody { + // Get code section + pub fn code(&self, index: usize) -> Option<&Bytes> { + self.code_section.get(index) + } + + /// Create EOF from body. + pub fn into_eof(self) -> Eof { + // TODO add bounds checks. + let header = EofHeader { + types_size: self.types_section.len() as u16 * 4, + code_sizes: self.code_section.iter().map(|x| x.len() as u16).collect(), + container_sizes: self + .container_section + .iter() + .map(|x| x.len() as u16) + .collect(), + data_size: self.data_section.len() as u16, + sum_code_sizes: self.code_section.iter().map(|x| x.len()).sum(), + sum_container_sizes: self.container_section.iter().map(|x| x.len()).sum(), + }; + let mut buffer = Vec::new(); + header.encode(&mut buffer); + self.encode(&mut buffer); + Eof { + header, + body: self, + raw: buffer.into(), + } + } + + /// Encode Body into buffer. + pub fn encode(&self, buffer: &mut Vec) { + for types_section in &self.types_section { + types_section.encode(buffer); + } + + for code_section in &self.code_section { + buffer.extend_from_slice(code_section); + } + + for container_section in &self.container_section { + buffer.extend_from_slice(container_section); + } + + buffer.extend_from_slice(&self.data_section); + } + + /// Decode EOF body from buffer and Header. + pub fn decode(input: &Bytes, header: &EofHeader) -> Result { + let header_len = header.size(); + let partial_body_len = + header.sum_code_sizes + header.sum_container_sizes + header.types_size as usize; + let full_body_len = partial_body_len + header.data_size as usize; + + if input.len() < header_len + partial_body_len { + return Err(EofDecodeError::MissingBodyWithoutData); + } + + if input.len() > header_len + full_body_len { + return Err(EofDecodeError::DanglingData); + } + + let mut body = EofBody::default(); + + let mut types_input = &input[header_len..]; + for _ in 0..header.types_count() { + let (types_section, local_input) = TypesSection::decode(types_input)?; + types_input = local_input; + body.types_section.push(types_section); + } + + // extract code section + let mut start = header_len + header.types_size as usize; + for size in header.code_sizes.iter().map(|x| *x as usize) { + body.code_section.push(input.slice(start..start + size)); + start += size; + } + + // extract container section + for size in header.container_sizes.iter().map(|x| *x as usize) { + body.container_section + .push(input.slice(start..start + size)); + start += size; + } + + body.data_section = input.slice(start..); + body.is_data_filled = body.data_section.len() == header.data_size as usize; + + Ok(body) + } +} diff --git a/crates/primitives/src/bytecode/eof/decode_helpers.rs b/crates/primitives/src/bytecode/eof/decode_helpers.rs new file mode 100644 index 00000000..d2d2eb55 --- /dev/null +++ b/crates/primitives/src/bytecode/eof/decode_helpers.rs @@ -0,0 +1,20 @@ +use super::EofDecodeError; + +/// Consumes a u8 from the input. +#[inline] +pub(crate) fn consume_u8(input: &[u8]) -> Result<(&[u8], u8), EofDecodeError> { + if input.is_empty() { + return Err(EofDecodeError::MissingInput); + } + Ok((&input[1..], input[0])) +} + +/// Consumes a u16 from the input. +#[inline] +pub(crate) fn consume_u16(input: &[u8]) -> Result<(&[u8], u16), EofDecodeError> { + if input.len() < 2 { + return Err(EofDecodeError::MissingInput); + } + let (int_bytes, rest) = input.split_at(2); + Ok((rest, u16::from_be_bytes([int_bytes[0], int_bytes[1]]))) +} diff --git a/crates/primitives/src/bytecode/eof/header.rs b/crates/primitives/src/bytecode/eof/header.rs new file mode 100644 index 00000000..bd7a33d7 --- /dev/null +++ b/crates/primitives/src/bytecode/eof/header.rs @@ -0,0 +1,257 @@ +use super::{ + decode_helpers::{consume_u16, consume_u8}, + EofDecodeError, +}; +use std::vec::Vec; + +/// EOF Header containing +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct EofHeader { + /// Size of EOF types section. + /// types section includes num of input and outputs and max stack size. + pub types_size: u16, + /// Sizes of EOF code section. + /// Code size can't be zero. + pub code_sizes: Vec, + /// EOF Container size. + /// Container size can be zero. + pub container_sizes: Vec, + /// EOF data size. + pub data_size: u16, + /// sum code sizes + pub sum_code_sizes: usize, + /// sum container sizes + pub sum_container_sizes: usize, +} + +const KIND_TERMINAL: u8 = 0; +const KIND_TYPES: u8 = 1; +const KIND_CODE: u8 = 2; +const KIND_CONTAINER: u8 = 3; +const KIND_DATA: u8 = 4; + +#[inline] +fn consume_header_section_size(input: &[u8]) -> Result<(&[u8], Vec, usize), EofDecodeError> { + // num_sections 2 bytes 0x0001-0xFFFF + // 16-bit unsigned big-endian integer denoting the number of the sections + let (input, num_sections) = consume_u16(input)?; + if num_sections == 0 { + return Err(EofDecodeError::NonSizes); + } + let byte_size = (num_sections * 2) as usize; + if input.len() < byte_size { + return Err(EofDecodeError::ShortInputForSizes); + } + let mut sizes = Vec::with_capacity(num_sections as usize); + let mut sum = 0; + for i in 0..num_sections as usize { + // size 2 bytes 0x0001-0xFFFF + // 16-bit unsigned big-endian integer denoting the length of the section content + let code_size = u16::from_be_bytes([input[i * 2], input[i * 2 + 1]]); + if code_size == 0 { + return Err(EofDecodeError::ZeroSize); + } + sum += code_size as usize; + sizes.push(code_size); + } + + Ok((&input[byte_size..], sizes, sum)) +} + +impl EofHeader { + /// Length of the header in bytes. + /// + /// Length is calculated as: + /// magic 2 byte + + /// version 1 byte + + /// types section 3 bytes + + /// code section 3 bytes + + /// num_code_sections * 2 + + /// if num_container_sections != 0 { container section 3 bytes} + + /// num_container_sections * 2 + + /// data section 3 bytes + + /// terminator 1 byte + /// + /// It is minimum 15 bytes (there is at least one code section). + pub fn size(&self) -> usize { + let optional_container_sizes = if self.container_sizes.is_empty() { + 0 + } else { + 3 + self.container_sizes.len() * 2 + }; + 13 + self.code_sizes.len() * 2 + optional_container_sizes + } + + /// Returns number of types. + pub fn types_count(&self) -> usize { + self.types_size as usize / 4 + } + + /// Returns body size. It is sum of code sizes, container sizes and data size. + pub fn body_size(&self) -> usize { + self.sum_code_sizes + self.sum_container_sizes + self.data_size as usize + } + + /// Returns raw size of the EOF. + pub fn eof_size(&self) -> usize { + self.size() + self.body_size() + } + + /// Encodes EOF header into binary form. + pub fn encode(&self, buffer: &mut Vec) { + // magic 2 bytes 0xEF00 EOF prefix + buffer.extend_from_slice(&0xEF00u16.to_be_bytes()); + // version 1 byte 0x01 EOF version + buffer.push(0x01); + // kind_types 1 byte 0x01 kind marker for types size section + buffer.push(KIND_TYPES); + // types_size 2 bytes 0x0004-0xFFFF + buffer.extend_from_slice(&self.types_size.to_be_bytes()); + // kind_code 1 byte 0x02 kind marker for code size section + buffer.push(KIND_CODE); + // code_sections_sizes + buffer.extend_from_slice(&(self.code_sizes.len() as u16).to_be_bytes()); + for size in &self.code_sizes { + buffer.extend_from_slice(&size.to_be_bytes()); + } + // kind_container_or_data 1 byte 0x03 or 0x04 kind marker for container size section or data size section + if self.container_sizes.is_empty() { + buffer.push(KIND_DATA); + } else { + buffer.push(KIND_CONTAINER); + // container_sections_sizes + buffer.extend_from_slice(&(self.container_sizes.len() as u16).to_be_bytes()); + for size in &self.container_sizes { + buffer.extend_from_slice(&size.to_be_bytes()); + } + // kind_data 1 byte 0x04 kind marker for data size section + buffer.push(KIND_DATA); + } + // data_size 2 bytes 0x0000-0xFFFF 16-bit unsigned big-endian integer denoting the length of the data section content + buffer.extend_from_slice(&self.data_size.to_be_bytes()); + // terminator 1 byte 0x00 marks the end of the EofHeader + buffer.push(KIND_TERMINAL); + } + + /// Decodes EOF header from binary form. + pub fn decode(input: &[u8]) -> Result<(Self, &[u8]), EofDecodeError> { + let mut header = EofHeader::default(); + + // magic 2 bytes 0xEF00 EOF prefix + let (input, kind) = consume_u16(input)?; + if kind != 0xEF00 { + return Err(EofDecodeError::InvalidEOFMagicNumber); + } + + // version 1 byte 0x01 EOF version + let (input, version) = consume_u8(input)?; + if version != 0x01 { + return Err(EofDecodeError::InvalidEOFVersion); + } + + // kind_types 1 byte 0x01 kind marker for types size section + let (input, kind_types) = consume_u8(input)?; + if kind_types != KIND_TYPES { + return Err(EofDecodeError::InvalidTypesKind); + } + + // types_size 2 bytes 0x0004-0xFFFF + // 16-bit unsigned big-endian integer denoting the length of the type section content + let (input, types_size) = consume_u16(input)?; + header.types_size = types_size; + + if header.types_size % 4 != 0 { + return Err(EofDecodeError::InvalidTypesSection); + } + + // kind_code 1 byte 0x02 kind marker for code size section + let (input, kind_types) = consume_u8(input)?; + if kind_types != KIND_CODE { + return Err(EofDecodeError::InvalidCodeKind); + } + + // code_sections_sizes + let (input, sizes, sum) = consume_header_section_size(input)?; + + if sizes.len() > 1024 { + return Err(EofDecodeError::TooManyCodeSections); + } + + if sizes.is_empty() { + return Err(EofDecodeError::ZeroCodeSections); + } + + if sizes.len() != (types_size / 4) as usize { + return Err(EofDecodeError::MismatchCodeAndTypesSize); + } + + header.code_sizes = sizes; + header.sum_code_sizes = sum; + + let (input, kind_container_or_data) = consume_u8(input)?; + + let input = match kind_container_or_data { + KIND_CONTAINER => { + // container_sections_sizes + let (input, sizes, sum) = consume_header_section_size(input)?; + // the number of container sections must not exceed 256 + if sizes.len() > 256 { + return Err(EofDecodeError::TooManyContainerSections); + } + header.container_sizes = sizes; + header.sum_container_sizes = sum; + let (input, kind_data) = consume_u8(input)?; + if kind_data != KIND_DATA { + return Err(EofDecodeError::InvalidDataKind); + } + input + } + KIND_DATA => input, + _ => return Err(EofDecodeError::InvalidKindAfterCode), + }; + + // data_size 2 bytes 0x0000-0xFFFF 16-bit + // unsigned big-endian integer denoting the length + // of the data section content (for not yet deployed + // containers this can be more than the actual content, see Data Section Lifecycle) + let (input, data_size) = consume_u16(input)?; + header.data_size = data_size; + + // terminator 1 byte 0x00 marks the end of the EofHeader + let (input, terminator) = consume_u8(input)?; + if terminator != KIND_TERMINAL { + return Err(EofDecodeError::InvalidTerminalByte); + } + + Ok((header, input)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::hex; + + #[test] + fn sanity_header_decode() { + let input = hex!("ef000101000402000100010400000000800000fe"); + let (header, _) = EofHeader::decode(&input).unwrap(); + assert_eq!(header.types_size, 4); + assert_eq!(header.code_sizes, vec![1]); + assert_eq!(header.container_sizes, vec![]); + assert_eq!(header.data_size, 0); + } + + #[test] + fn decode_header_not_terminated() { + let input = hex!("ef0001010004"); + assert_eq!(EofHeader::decode(&input), Err(EofDecodeError::MissingInput)); + } + + #[test] + fn failing_test() { + let input = hex!("ef00010100040200010006030001001404000200008000016000e0000000ef000101000402000100010400000000800000fe"); + let _ = EofHeader::decode(&input).unwrap(); + } +} diff --git a/crates/primitives/src/bytecode/eof/types_section.rs b/crates/primitives/src/bytecode/eof/types_section.rs new file mode 100644 index 00000000..84db61f0 --- /dev/null +++ b/crates/primitives/src/bytecode/eof/types_section.rs @@ -0,0 +1,62 @@ +use super::{ + decode_helpers::{consume_u16, consume_u8}, + EofDecodeError, +}; +use std::vec::Vec; + +/// Types section that contains stack information for matching code section. +#[derive(Debug, Clone, Default, Hash, PartialEq, Eq, Copy)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct TypesSection { + /// inputs - 1 byte - `0x00-0x7F` + /// number of stack elements the code section consumes + pub inputs: u8, + /// outputs - 1 byte - `0x00-0x80` + /// number of stack elements the code section returns or 0x80 for non-returning functions + pub outputs: u8, + /// max_stack_height - 2 bytes - `0x0000-0x03FF` + /// maximum number of elements ever placed onto the stack by the code section + pub max_stack_size: u16, +} + +impl TypesSection { + /// Return the difference between inputs and outputs. + #[inline] + pub fn io_diff(&self) -> i32 { + self.outputs as i32 - self.inputs as i32 + } + + /// Encode the section into the buffer. + #[inline] + pub fn encode(&self, buffer: &mut Vec) { + buffer.push(self.inputs); + buffer.push(self.outputs); + buffer.extend_from_slice(&self.max_stack_size.to_be_bytes()); + } + + /// Decode the section from the input. + #[inline] + pub fn decode(input: &[u8]) -> Result<(Self, &[u8]), EofDecodeError> { + let (input, inputs) = consume_u8(input)?; + let (input, outputs) = consume_u8(input)?; + let (input, max_stack_size) = consume_u16(input)?; + let section = Self { + inputs, + outputs, + max_stack_size, + }; + section.validate()?; + Ok((section, input)) + } + + /// Validate the section. + pub fn validate(&self) -> Result<(), EofDecodeError> { + if self.inputs > 0x7f || self.outputs > 0x80 || self.max_stack_size > 0x03FF { + return Err(EofDecodeError::InvalidTypesSection); + } + if self.inputs as u16 > self.max_stack_size { + return Err(EofDecodeError::InvalidTypesSection); + } + Ok(()) + } +} diff --git a/crates/primitives/src/bytecode/legacy.rs b/crates/primitives/src/bytecode/legacy.rs new file mode 100644 index 00000000..18949f0a --- /dev/null +++ b/crates/primitives/src/bytecode/legacy.rs @@ -0,0 +1,63 @@ +mod jump_map; + +pub use jump_map::JumpTable; + +use crate::Bytes; +use bitvec::{bitvec, order::Lsb0}; +use std::sync::Arc; + +/// Legacy analyzed +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct LegacyAnalyzedBytecode { + /// Bytecode with 32 zero bytes padding. + bytecode: Bytes, + /// Original bytes length. + original_len: usize, + /// Jump table. + jump_table: JumpTable, +} + +impl Default for LegacyAnalyzedBytecode { + #[inline] + fn default() -> Self { + Self { + bytecode: Bytes::from_static(&[0]), + original_len: 0, + jump_table: JumpTable(Arc::new(bitvec![u8, Lsb0; 0])), + } + } +} + +impl LegacyAnalyzedBytecode { + /// Create new analyzed bytecode. + pub fn new(bytecode: Bytes, original_len: usize, jump_table: JumpTable) -> Self { + Self { + bytecode, + original_len, + jump_table, + } + } + + /// Returns bytes of bytecode. + /// + /// Bytes are padded with 32 zero bytes. + pub fn bytes(&self) -> Bytes { + self.bytecode.clone() + } + + /// Original bytes length. + pub fn original_len(&self) -> usize { + self.original_len + } + + /// Original bytes without padding. + pub fn original_bytes(&self) -> Bytes { + self.bytecode.slice(0..self.original_len) + } + + /// Jumptable of analyzed bytes. + pub fn jump_table(&self) -> &JumpTable { + &self.jump_table + } +} diff --git a/crates/primitives/src/bytecode/legacy/jump_map.rs b/crates/primitives/src/bytecode/legacy/jump_map.rs new file mode 100644 index 00000000..af861787 --- /dev/null +++ b/crates/primitives/src/bytecode/legacy/jump_map.rs @@ -0,0 +1,36 @@ +use crate::hex; +use bitvec::vec::BitVec; +use std::{fmt::Debug, sync::Arc}; + +/// A map of valid `jump` destinations. +#[derive(Clone, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct JumpTable(pub Arc>); + +impl Debug for JumpTable { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("JumpTable") + .field("map", &hex::encode(self.0.as_raw_slice())) + .finish() + } +} + +impl JumpTable { + /// Get the raw bytes of the jump map + #[inline] + pub fn as_slice(&self) -> &[u8] { + self.0.as_raw_slice() + } + + /// Construct a jump map from raw bytes + #[inline] + pub fn from_slice(slice: &[u8]) -> Self { + Self(Arc::new(BitVec::from_slice(slice))) + } + + /// Check if `pc` is a valid jump destination. + #[inline] + pub fn is_valid(&self, pc: usize) -> bool { + pc < self.0.len() && self.0[pc] + } +} diff --git a/crates/primitives/src/db.rs b/crates/primitives/src/db.rs index e0db9bda..3b1c6dc8 100644 --- a/crates/primitives/src/db.rs +++ b/crates/primitives/src/db.rs @@ -67,6 +67,12 @@ impl From for WrapDatabaseRef { } } +pub trait DatabaseWithDebugError: Database +where + ::Error: std::fmt::Debug + std::fmt::Display, +{ +} + impl Database for WrapDatabaseRef { type Error = T::Error; diff --git a/crates/primitives/src/env.rs b/crates/primitives/src/env.rs index bd0e52ce..9a4470a9 100644 --- a/crates/primitives/src/env.rs +++ b/crates/primitives/src/env.rs @@ -3,16 +3,17 @@ pub mod handler_cfg; pub use handler_cfg::{CfgEnvWithHandlerCfg, EnvWithHandlerCfg, HandlerCfg}; use crate::{ - calc_blob_gasprice, Account, Address, Bytes, InvalidHeader, InvalidTransaction, Spec, SpecId, - B256, GAS_PER_BLOB, KECCAK_EMPTY, MAX_BLOB_NUMBER_PER_BLOCK, MAX_INITCODE_SIZE, U256, + calc_blob_gasprice, Account, Address, Bytes, HashMap, InvalidHeader, InvalidTransaction, Spec, + SpecId, B256, GAS_PER_BLOB, KECCAK_EMPTY, MAX_BLOB_NUMBER_PER_BLOCK, MAX_INITCODE_SIZE, U256, VERSIONED_HASH_VERSION_KZG, }; use core::cmp::{min, Ordering}; +use core::hash::Hash; use std::boxed::Box; use std::vec::Vec; /// EVM environment configuration. -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Env { /// Configuration of the EVM itself. @@ -184,6 +185,41 @@ impl Env { } } + if SPEC::enabled(SpecId::PRAGUE) { + if !self.tx.eof_initcodes.is_empty() { + // If initcode is set other fields must be empty + if !self.tx.blob_hashes.is_empty() { + return Err(InvalidTransaction::BlobVersionedHashesNotSupported); + } + // EOF Create tx extends EIP-1559 tx. It must have max_fee_per_blob_gas + if self.tx.max_fee_per_blob_gas.is_some() { + return Err(InvalidTransaction::MaxFeePerBlobGasNotSupported); + } + // EOF Create must have a to address + if matches!(self.tx.transact_to, TransactTo::Call(_)) { + return Err(InvalidTransaction::EofCrateShouldHaveToAddress); + } + } else { + // If initcode is set check its bounds. + if self.tx.eof_initcodes.len() > 256 { + return Err(InvalidTransaction::EofInitcodesNumberLimit); + } + if self + .tx + .eof_initcodes_hashed + .iter() + .any(|(_, i)| i.len() >= MAX_INITCODE_SIZE) + { + return Err(InvalidTransaction::EofInitcodesSizeLimit); + } + } + } else { + // Initcode set when not supported. + if !self.tx.eof_initcodes.is_empty() { + return Err(InvalidTransaction::EofInitcodesNotSupported); + } + } + Ok(()) } @@ -247,7 +283,7 @@ impl Env { /// EVM configuration. #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug, Eq, PartialEq, Hash)] +#[derive(Clone, Debug, Eq, PartialEq)] #[non_exhaustive] pub struct CfgEnv { /// Chain ID of the EVM, it will be compared to the transaction's Chain ID. @@ -483,7 +519,7 @@ impl Default for BlockEnv { } /// The transaction environment. -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TxEnv { /// Caller aka Author aka transaction signer. @@ -539,11 +575,33 @@ pub struct TxEnv { /// [EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844 pub max_fee_per_blob_gas: Option, + /// EOF Initcodes for EOF CREATE transaction + /// + /// Incorporated as part of the Prague upgrade via [EOF] + /// + /// [EOF]: https://eips.ethereum.org/EIPS/eip-4844 + pub eof_initcodes: Vec, + + /// Internal Temporary field that stores the hashes of the EOF initcodes. + /// + /// Those are always cleared after the transaction is executed. + /// And calculated/overwritten every time transaction starts. + /// They are calculated from the [`Self::eof_initcodes`] field. + pub eof_initcodes_hashed: HashMap, + #[cfg_attr(feature = "serde", serde(flatten))] #[cfg(feature = "optimism")] + /// Optimism fields. pub optimism: OptimismFields, } +pub enum TxType { + Legacy, + Eip1559, + BlobTx, + EofCreate, +} + impl TxEnv { /// See [EIP-4844], [`Env::calc_data_fee`], and [`Env::calc_max_data_fee`]. /// @@ -575,6 +633,8 @@ impl Default for TxEnv { access_list: Vec::new(), blob_hashes: Vec::new(), max_fee_per_blob_gas: None, + eof_initcodes: Vec::new(), + eof_initcodes_hashed: HashMap::new(), #[cfg(feature = "optimism")] optimism: OptimismFields::default(), } @@ -647,7 +707,7 @@ pub enum TransactTo { /// Simple call to an address. Call(Address), /// Contract creation. - Create(CreateScheme), + Create, } impl TransactTo { @@ -660,15 +720,8 @@ impl TransactTo { /// Creates a contract. #[inline] pub fn create() -> Self { - Self::Create(CreateScheme::Create) - } - - /// Creates a contract with the given salt using `CREATE2`. - #[inline] - pub fn create2(salt: U256) -> Self { - Self::Create(CreateScheme::Create2 { salt }) + Self::Create } - /// Returns `true` if the transaction is `Call`. #[inline] pub fn is_call(&self) -> bool { @@ -678,7 +731,7 @@ impl TransactTo { /// Returns `true` if the transaction is `Create` or `Create2`. #[inline] pub fn is_create(&self) -> bool { - matches!(self, Self::Create(_)) + matches!(self, Self::Create) } } @@ -701,8 +754,6 @@ pub enum CreateScheme { pub enum AnalysisKind { /// Do not perform bytecode analysis. Raw, - /// Check the bytecode for validity. - Check, /// Perform bytecode analysis. #[default] Analyse, diff --git a/crates/primitives/src/env/handler_cfg.rs b/crates/primitives/src/env/handler_cfg.rs index b2894d69..f57a3e8c 100644 --- a/crates/primitives/src/env/handler_cfg.rs +++ b/crates/primitives/src/env/handler_cfg.rs @@ -60,7 +60,7 @@ impl HandlerCfg { } /// Configuration environment with the chain spec id. -#[derive(Clone, Debug, Eq, PartialEq, Hash)] +#[derive(Clone, Debug, Eq, PartialEq)] pub struct CfgEnvWithHandlerCfg { /// Configuration environment. pub cfg_env: CfgEnv, @@ -106,7 +106,7 @@ impl Deref for CfgEnvWithHandlerCfg { } /// Evm environment with the chain spec id. -#[derive(Clone, Debug, Default, Eq, PartialEq, Hash)] +#[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct EnvWithHandlerCfg { /// Evm enironment. pub env: Box, diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 50e6d35d..de906f3d 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -13,6 +13,7 @@ mod bytecode; mod constants; pub mod db; pub mod env; + #[cfg(feature = "c-kzg")] pub mod kzg; pub mod precompile; diff --git a/crates/primitives/src/result.rs b/crates/primitives/src/result.rs index 5a563f7e..516ce251 100644 --- a/crates/primitives/src/result.rs +++ b/crates/primitives/src/result.rs @@ -245,6 +245,14 @@ pub enum InvalidTransaction { TooManyBlobs, /// Blob transaction contains a versioned hash with an incorrect version BlobVersionNotSupported, + /// EOF TxCreate transaction is not supported before Prague hardfork. + EofInitcodesNotSupported, + /// EOF TxCreate transaction max initcode number reached. + EofInitcodesNumberLimit, + /// EOF initcode in TXCreate is too large. + EofInitcodesSizeLimit, + /// EOF crate should have `to` address + EofCrateShouldHaveToAddress, /// System transactions are not supported post-regolith hardfork. /// /// Before the Regolith hardfork, there was a special field in the `Deposit` transaction @@ -333,6 +341,10 @@ impl fmt::Display for InvalidTransaction { Self::BlobCreateTransaction => write!(f, "blob create transaction"), Self::TooManyBlobs => write!(f, "too many blobs"), Self::BlobVersionNotSupported => write!(f, "blob version not supported"), + Self::EofInitcodesNotSupported => write!(f, "EOF initcodes not supported"), + Self::EofCrateShouldHaveToAddress => write!(f, "EOF crate should have `to` address"), + Self::EofInitcodesSizeLimit => write!(f, "EOF initcodes size limit"), + Self::EofInitcodesNumberLimit => write!(f, "EOF initcodes number limit"), #[cfg(feature = "optimism")] Self::DepositSystemTxPostRegolith => { write!( diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index e106e8fd..fbd8d22a 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -10,24 +10,25 @@ pub use SpecId::*; #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, enumn::N)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum SpecId { - FRONTIER = 0, // Frontier 0 + FRONTIER = 0, // Frontier 0 FRONTIER_THAWING = 1, // Frontier Thawing 200000 - HOMESTEAD = 2, // Homestead 1150000 - DAO_FORK = 3, // DAO Fork 1920000 - TANGERINE = 4, // Tangerine Whistle 2463000 + HOMESTEAD = 2, // Homestead 1150000 + DAO_FORK = 3, // DAO Fork 1920000 + TANGERINE = 4, // Tangerine Whistle 2463000 SPURIOUS_DRAGON = 5, // Spurious Dragon 2675000 - BYZANTIUM = 6, // Byzantium 4370000 + BYZANTIUM = 6, // Byzantium 4370000 CONSTANTINOPLE = 7, // Constantinople 7280000 is overwritten with PETERSBURG PETERSBURG = 8, // Petersburg 7280000 ISTANBUL = 9, // Istanbul 9069000 - MUIR_GLACIER = 10, // Muir Glacier 9200000 + MUIR_GLACIER = 10, // Muir Glacier 9200000 BERLIN = 11, // Berlin 12244000 LONDON = 12, // London 12965000 - ARROW_GLACIER = 13, // Arrow Glacier 13773000 - GRAY_GLACIER = 14, // Gray Glacier 15050000 - MERGE = 15, // Paris/Merge 15537394 (TTD: 58750000000000000000000) - SHANGHAI = 16, // Shanghai 17034870 (TS: 1681338455) - CANCUN = 17, // Cancun 19426587 (TS: 1710338135) + ARROW_GLACIER = 13, // Arrow Glacier 13773000 + GRAY_GLACIER = 14, // Gray Glacier 15050000 + MERGE = 15, // Paris/Merge 15537394 (TTD: 58750000000000000000000) + SHANGHAI = 16, // Shanghai 17034870 (Timestamp: 1681338455) + CANCUN = 17, // Cancun 19426587 (Timestamp: 1710338135) + PRAGUE = 18, // Praque TBD #[default] LATEST = u8::MAX, } @@ -62,6 +63,7 @@ pub enum SpecId { CANYON = 19, CANCUN = 20, ECOTONE = 21, + PRAGUE = 22, #[default] LATEST = u8::MAX, } @@ -103,6 +105,7 @@ impl From<&str> for SpecId { "Merge" => Self::MERGE, "Shanghai" => Self::SHANGHAI, "Cancun" => Self::CANCUN, + "Prague" => Self::PRAGUE, #[cfg(feature = "optimism")] "Bedrock" => SpecId::BEDROCK, #[cfg(feature = "optimism")] @@ -137,6 +140,7 @@ impl From for &'static str { SpecId::MERGE => "Merge", SpecId::SHANGHAI => "Shanghai", SpecId::CANCUN => "Cancun", + SpecId::PRAGUE => "Prague", #[cfg(feature = "optimism")] SpecId::BEDROCK => "Bedrock", #[cfg(feature = "optimism")] @@ -190,6 +194,7 @@ spec!(LONDON, LondonSpec); spec!(MERGE, MergeSpec); spec!(SHANGHAI, ShanghaiSpec); spec!(CANCUN, CancunSpec); +spec!(PRAGUE, PragueSpec); spec!(LATEST, LatestSpec); @@ -262,6 +267,10 @@ macro_rules! spec_to_generic { use $crate::LatestSpec as SPEC; $e } + $crate::SpecId::PRAGUE => { + use $crate::PragueSpec as SPEC; + $e + } #[cfg(feature = "optimism")] $crate::SpecId::BEDROCK => { use $crate::BedrockSpec as SPEC; @@ -318,6 +327,7 @@ mod tests { #[cfg(feature = "optimism")] spec_to_generic!(CANYON, assert_eq!(SPEC::SPEC_ID, CANYON)); spec_to_generic!(CANCUN, assert_eq!(SPEC::SPEC_ID, CANCUN)); + spec_to_generic!(PRAGUE, assert_eq!(SPEC::SPEC_ID, PRAGUE)); spec_to_generic!(LATEST, assert_eq!(SPEC::SPEC_ID, LATEST)); } } diff --git a/crates/primitives/src/state.rs b/crates/primitives/src/state.rs index 8f6736bd..d0038f8d 100644 --- a/crates/primitives/src/state.rs +++ b/crates/primitives/src/state.rs @@ -202,7 +202,7 @@ impl Default for AccountInfo { Self { balance: U256::ZERO, code_hash: KECCAK_EMPTY, - code: Some(Bytecode::new()), + code: Some(Bytecode::default()), nonce: 0, } } diff --git a/crates/revm/benches/bench.rs b/crates/revm/benches/bench.rs index 9d073346..d98d3519 100644 --- a/crates/revm/benches/bench.rs +++ b/crates/revm/benches/bench.rs @@ -3,10 +3,8 @@ use criterion::{ }; use revm::{ db::BenchmarkDB, - interpreter::{analysis::to_analysed, BytecodeLocked, Contract, DummyHost, Interpreter}, - primitives::{ - address, bytes, hex, BerlinSpec, Bytecode, BytecodeState, Bytes, TransactTo, U256, - }, + interpreter::{analysis::to_analysed, Contract, DummyHost, Interpreter}, + primitives::{address, bytes, hex, BerlinSpec, Bytecode, Bytes, TransactTo, U256}, Evm, }; use revm_interpreter::{opcode::make_instruction_table, SharedMemory, EMPTY_SHARED_MEMORY}; @@ -37,7 +35,7 @@ fn analysis(c: &mut Criterion) { .build(); bench_transact(&mut g, &mut evm); - let checked = Bytecode::new_raw(contract_data.clone()).to_checked(); + let checked = Bytecode::new_raw(contract_data.clone()); let mut evm = evm .modify() .reset_handler_with_db(BenchmarkDB::new_bytecode(checked)) @@ -91,10 +89,10 @@ fn transfer(c: &mut Criterion) { } fn bench_transact(g: &mut BenchmarkGroup<'_, WallTime>, evm: &mut Evm<'_, EXT, BenchmarkDB>) { - let state = match evm.context.evm.db.0.state { - BytecodeState::Raw => "raw", - BytecodeState::Checked { .. } => "checked", - BytecodeState::Analysed { .. } => "analysed", + let state = match evm.context.evm.db.0 { + Bytecode::LegacyRaw(_) => "raw", + Bytecode::LegacyAnalyzed(_) => "analysed", + Bytecode::Eof(_) => "eof", }; let id = format!("transact/{state}"); g.bench_function(id, |b| b.iter(|| evm.transact().unwrap())); @@ -104,7 +102,7 @@ fn bench_eval(g: &mut BenchmarkGroup<'_, WallTime>, evm: &mut Evm<'static, (), B g.bench_function("eval", |b| { let contract = Contract { input: evm.context.evm.env.tx.data.clone(), - bytecode: BytecodeLocked::try_from(evm.context.evm.db.0.clone()).unwrap(), + bytecode: to_analysed(evm.context.evm.db.0.clone()), ..Default::default() }; let mut shared_memory = SharedMemory::new(); diff --git a/crates/revm/src/context/evm_context.rs b/crates/revm/src/context/evm_context.rs index 5435722e..84b1c4ff 100644 --- a/crates/revm/src/context/evm_context.rs +++ b/crates/revm/src/context/evm_context.rs @@ -1,3 +1,5 @@ +use revm_interpreter::TransferValue; + use super::inner_evm_context::InnerEvmContext; use crate::{ db::Database, @@ -163,7 +165,7 @@ impl EvmContext { let (account, _) = self .inner .journaled_state - .load_code(inputs.contract, &mut self.inner.db)?; + .load_code(inputs.bytecode_address, &mut self.inner.db)?; let code_hash = account.info.code_hash(); let bytecode = account.info.code.clone().unwrap_or_default(); @@ -171,23 +173,28 @@ impl EvmContext { let checkpoint = self.journaled_state.checkpoint(); // Touch address. For "EIP-158 State Clear", this will erase empty accounts. - if inputs.transfer.value == U256::ZERO { - self.load_account(inputs.context.address)?; - self.journaled_state.touch(&inputs.context.address); - } - - // Transfer value from caller to called account - if let Some(result) = self.inner.journaled_state.transfer( - &inputs.transfer.source, - &inputs.transfer.target, - inputs.transfer.value, - &mut self.inner.db, - )? { - self.journaled_state.checkpoint_revert(checkpoint); - return return_result(result); - } + match inputs.value { + // if transfer value is zero, do the touch. + TransferValue::Value(value) if value == U256::ZERO => { + self.load_account(inputs.target_address)?; + self.journaled_state.touch(&inputs.target_address); + } + TransferValue::Value(value) => { + // Transfer value from caller to called account + if let Some(result) = self.inner.journaled_state.transfer( + &inputs.caller, + &inputs.target_address, + value, + &mut self.inner.db, + )? { + self.journaled_state.checkpoint_revert(checkpoint); + return return_result(result); + } + } + _ => {} + }; - if let Some(result) = self.call_precompile(inputs.contract, &inputs.input, gas) { + if let Some(result) = self.call_precompile(inputs.bytecode_address, &inputs.input, gas) { if matches!(result.result, return_ok!()) { self.journaled_state.checkpoint_commit(); } else { @@ -198,12 +205,8 @@ impl EvmContext { inputs.return_memory_offset.clone(), )) } else if !bytecode.is_empty() { - let contract = Contract::new_with_context( - inputs.input.clone(), - bytecode, - code_hash, - &inputs.context, - ); + let contract = + Contract::new_with_context(inputs.input.clone(), bytecode, Some(code_hash), inputs); // Create interpreter and executes call and push new CallStackFrame. Ok(FrameOrResult::new_call_frame( inputs.return_memory_offset.clone(), @@ -220,6 +223,8 @@ impl EvmContext { /// Test utilities for the [`EvmContext`]. #[cfg(any(test, feature = "test-utils"))] pub(crate) mod test_utils { + use revm_interpreter::TransferValue; + use super::*; use crate::{ db::{CacheDB, EmptyDB}, @@ -235,21 +240,14 @@ pub(crate) mod test_utils { /// Creates `CallInputs` that calls a provided contract address from the mock caller. pub fn create_mock_call_inputs(to: Address) -> CallInputs { CallInputs { - contract: to, - transfer: revm_interpreter::Transfer { - source: MOCK_CALLER, - target: to, - value: U256::ZERO, - }, input: Bytes::new(), gas_limit: 0, - context: revm_interpreter::CallContext { - address: MOCK_CALLER, - caller: MOCK_CALLER, - code_address: MOCK_CALLER, - apparent_value: U256::ZERO, - scheme: revm_interpreter::CallScheme::Call, - }, + bytecode_address: to, + target_address: to, + caller: MOCK_CALLER, + value: TransferValue::Value(U256::ZERO), + scheme: revm_interpreter::CallScheme::Call, + is_eof: false, is_static: false, return_memory_offset: 0..0, } @@ -352,7 +350,7 @@ mod tests { let mut evm_context = test_utils::create_empty_evm_context(Box::new(env), db); let contract = address!("dead10000000000000000000000000000001dead"); let mut call_inputs = test_utils::create_mock_call_inputs(contract); - call_inputs.transfer.value = U256::from(1); + call_inputs.value = TransferValue::Value(U256::from(1)); let res = evm_context.make_call_frame(&call_inputs); let Ok(FrameOrResult::Result(result)) = res else { panic!("Expected FrameOrResult::Result"); diff --git a/crates/revm/src/context/inner_evm_context.rs b/crates/revm/src/context/inner_evm_context.rs index 16ffe8a2..63e11467 100644 --- a/crates/revm/src/context/inner_evm_context.rs +++ b/crates/revm/src/context/inner_evm_context.rs @@ -1,19 +1,19 @@ use crate::{ db::Database, interpreter::{ - analysis::to_analysed, gas, return_ok, Contract, CreateInputs, Gas, InstructionResult, - Interpreter, InterpreterResult, MAX_CODE_SIZE, + analysis::to_analysed, gas, return_ok, Contract, CreateInputs, EOFCreateInput, Gas, + InstructionResult, Interpreter, InterpreterResult, LoadAccountResult, SStoreResult, + SelfDestructResult, MAX_CODE_SIZE, }, journaled_state::JournaledState, primitives::{ keccak256, Account, Address, AnalysisKind, Bytecode, Bytes, CreateScheme, EVMError, Env, - HashSet, Spec, + Eof, HashSet, Spec, SpecId::{self, *}, B256, U256, }, FrameOrResult, JournalCheckpoint, CALL_STACK_LIMIT, }; -use revm_interpreter::{SStoreResult, SelfDestructResult}; use std::boxed::Box; /// EVM contexts contains data that EVM needs for execution. @@ -146,7 +146,7 @@ impl InnerEvmContext { pub fn load_account_exist( &mut self, address: Address, - ) -> Result<(bool, bool), EVMError> { + ) -> Result> { self.journaled_state .load_account_exist(address, &mut self.db) } @@ -223,6 +223,114 @@ impl InnerEvmContext { .selfdestruct(address, target, &mut self.db) } + /// Make create frame. + #[inline] + pub fn make_eofcreate_frame( + &mut self, + spec_id: SpecId, + inputs: &EOFCreateInput, + ) -> Result> { + let return_error = |e| { + Ok(FrameOrResult::new_eofcreate_result( + InterpreterResult { + result: e, + gas: Gas::new(inputs.gas_limit), + output: Bytes::new(), + }, + inputs.created_address, + inputs.return_memory_range.clone(), + )) + }; + + // Check depth + if self.journaled_state.depth() > CALL_STACK_LIMIT { + return return_error(InstructionResult::CallTooDeep); + } + + // Fetch balance of caller. + let (caller_balance, _) = self.balance(inputs.caller)?; + + // Check if caller has enough balance to send to the created contract. + if caller_balance < inputs.value { + return return_error(InstructionResult::OutOfFunds); + } + + // Increase nonce of caller and check if it overflows + if self.journaled_state.inc_nonce(inputs.caller).is_none() { + // can't happen on mainnet. + return return_error(InstructionResult::Return); + } + + // Load account so it needs to be marked as warm for access list. + self.journaled_state + .load_account(inputs.created_address, &mut self.db)?; + + // create account, transfer funds and make the journal checkpoint. + let checkpoint = match self.journaled_state.create_account_checkpoint( + inputs.caller, + inputs.created_address, + inputs.value, + spec_id, + ) { + Ok(checkpoint) => checkpoint, + Err(e) => { + return return_error(e); + } + }; + + let contract = Contract::new( + Bytes::new(), + // fine to clone as it is Bytes. + Bytecode::Eof(inputs.eof_init_code.clone()), + None, + inputs.created_address, + inputs.caller, + inputs.value, + ); + + let mut interpreter = Interpreter::new(contract, inputs.gas_limit, false); + // EOF init will enable RETURNCONTRACT opcode. + interpreter.set_is_eof_init(); + + Ok(FrameOrResult::new_eofcreate_frame( + inputs.created_address, + inputs.return_memory_range.clone(), + checkpoint, + interpreter, + )) + } + + /// If error is present revert changes, otherwise save EOF bytecode. + pub fn eofcreate_return( + &mut self, + interpreter_result: &mut InterpreterResult, + address: Address, + journal_checkpoint: JournalCheckpoint, + ) { + // Note we still execute RETURN opcode and return the bytes. + // In EOF those opcodes should abort execution. + // + // In RETURN gas is still protecting us from ddos and in oog, + // behaviour will be same as if it failed on return. + // + // Bytes of RETURN will drained in `insert_eofcreate_outcome`. + if interpreter_result.result != InstructionResult::ReturnContract { + self.journaled_state.checkpoint_revert(journal_checkpoint); + return; + } + + // commit changes reduces depth by -1. + self.journaled_state.checkpoint_commit(); + + // decode bytecode has a performance hit, but it has reasonable restrains. + let bytecode = + Eof::decode(interpreter_result.output.clone()).expect("Eof is already verified"); + + // eof bytecode is going to be hashed. + self.journaled_state + .set_code(address, Bytecode::Eof(bytecode)); + } + /// Make create frame. #[inline] pub fn make_create_frame( @@ -297,7 +405,7 @@ impl InnerEvmContext { let contract = Contract::new( Bytes::new(), bytecode, - init_code_hash, + Some(init_code_hash), created_address, inputs.caller, inputs.value, @@ -385,9 +493,6 @@ impl InnerEvmContext { // Do analysis of bytecode straight away. let bytecode = match self.env.cfg.perf_analyse_created_bytecodes { AnalysisKind::Raw => Bytecode::new_raw(interpreter_result.output.clone()), - AnalysisKind::Check => { - Bytecode::new_raw(interpreter_result.output.clone()).to_checked() - } AnalysisKind::Analyse => { to_analysed(Bytecode::new_raw(interpreter_result.output.clone())) } diff --git a/crates/revm/src/db/emptydb.rs b/crates/revm/src/db/emptydb.rs index 6495ce17..99116128 100644 --- a/crates/revm/src/db/emptydb.rs +++ b/crates/revm/src/db/emptydb.rs @@ -93,7 +93,7 @@ impl DatabaseRef for EmptyDBTyped { #[inline] fn code_by_hash_ref(&self, _code_hash: B256) -> Result { - Ok(Bytecode::new()) + Ok(Bytecode::default()) } #[inline] diff --git a/crates/revm/src/db/in_memory_db.rs b/crates/revm/src/db/in_memory_db.rs index 7ecf5236..00602d78 100644 --- a/crates/revm/src/db/in_memory_db.rs +++ b/crates/revm/src/db/in_memory_db.rs @@ -44,8 +44,8 @@ impl Default for CacheDB { impl CacheDB { pub fn new(db: ExtDB) -> Self { let mut contracts = HashMap::new(); - contracts.insert(KECCAK_EMPTY, Bytecode::new()); - contracts.insert(B256::ZERO, Bytecode::new()); + contracts.insert(KECCAK_EMPTY, Bytecode::default()); + contracts.insert(B256::ZERO, Bytecode::default()); Self { accounts: HashMap::new(), contracts, diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index 3e627d0e..7c888d3d 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -3,8 +3,8 @@ use crate::{ db::{Database, DatabaseCommit, EmptyDB}, handler::Handler, interpreter::{ - opcode::InstructionTables, Host, Interpreter, InterpreterAction, SStoreResult, - SelfDestructResult, SharedMemory, + opcode::InstructionTables, Host, Interpreter, InterpreterAction, LoadAccountResult, + SStoreResult, SelfDestructResult, SharedMemory, }, primitives::{ specification::SpecId, Address, BlockEnv, Bytecode, CfgEnv, EVMError, EVMResult, Env, @@ -274,6 +274,9 @@ impl Evm<'_, EXT, DB> { let frame_or_result = match next_action { InterpreterAction::Call { inputs } => exec.call(&mut self.context, inputs)?, InterpreterAction::Create { inputs } => exec.create(&mut self.context, inputs)?, + InterpreterAction::EOFCreate { inputs } => { + exec.eofcreate(&mut self.context, inputs)? + } InterpreterAction::Return { result } => { // free memory context. shared_memory.free_context(); @@ -293,6 +296,10 @@ impl Evm<'_, EXT, DB> { // return_create FrameResult::Create(exec.create_return(ctx, frame, result)?) } + Frame::EOFCreate(frame) => { + // return_eofcreate + FrameResult::EOFCreate(exec.eofcreate_return(ctx, frame, result)?) + } }) } InterpreterAction::None => unreachable!("InterpreterAction::None is not expected"), @@ -322,6 +329,10 @@ impl Evm<'_, EXT, DB> { // return_create exec.insert_create_outcome(ctx, stack_frame, outcome)? } + FrameResult::EOFCreate(outcome) => { + // return_eofcreate + exec.insert_eofcreate_outcome(ctx, stack_frame, outcome)? + } } } } @@ -352,7 +363,7 @@ impl Evm<'_, EXT, DB> { ctx, CallInputs::new_boxed(&ctx.evm.env.tx, gas_limit).unwrap(), )?, - TransactTo::Create(_) => exec.create( + TransactTo::Create => exec.create( ctx, CreateInputs::new_boxed(&ctx.evm.env.tx, gas_limit).unwrap(), )?, @@ -398,7 +409,7 @@ impl Host for Evm<'_, EXT, DB> { .ok() } - fn load_account(&mut self, address: Address) -> Option<(bool, bool)> { + fn load_account(&mut self, address: Address) -> Option { self.context .evm .load_account_exist(address) diff --git a/crates/revm/src/frame.rs b/crates/revm/src/frame.rs index a48fd3c1..64f19009 100644 --- a/crates/revm/src/frame.rs +++ b/crates/revm/src/frame.rs @@ -4,7 +4,9 @@ use crate::{ JournalCheckpoint, }; use core::ops::Range; -use revm_interpreter::{CallOutcome, CreateOutcome, Gas, InstructionResult, InterpreterResult}; +use revm_interpreter::{ + CallOutcome, CreateOutcome, EOFCreateOutcome, Gas, InstructionResult, InterpreterResult, +}; use std::boxed::Box; /// Call CallStackFrame. @@ -24,6 +26,14 @@ pub struct CreateFrame { pub frame_data: FrameData, } +/// Eof Create Frame. +#[derive(Debug)] +pub struct EOFCreateFrame { + pub created_address: Address, + pub return_memory_range: Range, + pub frame_data: FrameData, +} + #[derive(Debug)] pub struct FrameData { /// Journal checkpoint. @@ -37,11 +47,13 @@ pub struct FrameData { pub enum Frame { Call(Box), Create(Box), + EOFCreate(Box), } pub enum FrameResult { Call(CallOutcome), Create(CreateOutcome), + EOFCreate(EOFCreateOutcome), } impl FrameResult { @@ -51,6 +63,7 @@ impl FrameResult { match self { FrameResult::Call(outcome) => outcome.result, FrameResult::Create(outcome) => outcome.result, + FrameResult::EOFCreate(outcome) => outcome.result, } } @@ -62,6 +75,9 @@ impl FrameResult { FrameResult::Create(outcome) => { Output::Create(outcome.result.output.clone(), outcome.address) } + FrameResult::EOFCreate(_) => { + panic!("EOFCreate can't be called from external world."); + } } } @@ -71,6 +87,7 @@ impl FrameResult { match self { FrameResult::Call(outcome) => &outcome.result.gas, FrameResult::Create(outcome) => &outcome.result.gas, + FrameResult::EOFCreate(outcome) => &outcome.result.gas, } } @@ -80,6 +97,7 @@ impl FrameResult { match self { FrameResult::Call(outcome) => &mut outcome.result.gas, FrameResult::Create(outcome) => &mut outcome.result.gas, + FrameResult::EOFCreate(outcome) => &mut outcome.result.gas, } } @@ -89,6 +107,7 @@ impl FrameResult { match self { FrameResult::Call(outcome) => &outcome.result, FrameResult::Create(outcome) => &outcome.result, + FrameResult::EOFCreate(outcome) => &outcome.result, } } @@ -98,6 +117,7 @@ impl FrameResult { match self { FrameResult::Call(outcome) => &mut outcome.result, FrameResult::Create(outcome) => &mut outcome.result, + FrameResult::EOFCreate(outcome) => &mut outcome.result, } } @@ -168,6 +188,7 @@ impl Frame { match self { Frame::Call(call_frame) => call_frame.frame_data, Frame::Create(create_frame) => create_frame.frame_data, + Frame::EOFCreate(eof_create_frame) => eof_create_frame.frame_data, } } @@ -176,6 +197,7 @@ impl Frame { match self { Self::Call(call_frame) => &call_frame.frame_data, Self::Create(create_frame) => &create_frame.frame_data, + Self::EOFCreate(eof_create_frame) => &eof_create_frame.frame_data, } } @@ -184,6 +206,7 @@ impl Frame { match self { Self::Call(call_frame) => &mut call_frame.frame_data, Self::Create(create_frame) => &mut create_frame.frame_data, + Self::EOFCreate(eof_create_frame) => &mut eof_create_frame.frame_data, } } @@ -208,6 +231,22 @@ impl FrameOrResult { Self::Frame(Frame::new_create(created_address, checkpoint, interpreter)) } + pub fn new_eofcreate_frame( + created_address: Address, + return_memory_range: Range, + checkpoint: JournalCheckpoint, + interpreter: Interpreter, + ) -> Self { + Self::Frame(Frame::EOFCreate(Box::new(EOFCreateFrame { + created_address, + return_memory_range, + frame_data: FrameData { + checkpoint, + interpreter, + }, + }))) + } + /// Creates new call frame. pub fn new_call_frame( return_memory_range: Range, @@ -232,6 +271,18 @@ impl FrameOrResult { })) } + pub fn new_eofcreate_result( + interpreter_result: InterpreterResult, + address: Address, + return_memory_range: Range, + ) -> Self { + FrameOrResult::Result(FrameResult::EOFCreate(EOFCreateOutcome { + result: interpreter_result, + address, + return_memory_range, + })) + } + pub fn new_call_result( interpreter_result: InterpreterResult, memory_offset: Range, diff --git a/crates/revm/src/handler/handle_types/execution.rs b/crates/revm/src/handler/handle_types/execution.rs index f4300de9..d13dd205 100644 --- a/crates/revm/src/handler/handle_types/execution.rs +++ b/crates/revm/src/handler/handle_types/execution.rs @@ -1,4 +1,5 @@ use crate::{ + frame::EOFCreateFrame, handler::mainnet, interpreter::{CallInputs, CreateInputs, SharedMemory}, primitives::{db::Database, EVMError, Spec}, @@ -6,7 +7,9 @@ use crate::{ }; use std::{boxed::Box, sync::Arc}; -use revm_interpreter::{CallOutcome, CreateOutcome, InterpreterResult}; +use revm_interpreter::{ + CallOutcome, CreateOutcome, EOFCreateInput, EOFCreateOutcome, InterpreterResult, +}; /// Handles first frame return handle. pub type LastFrameReturnHandle<'a, EXT, DB> = Arc< @@ -73,6 +76,35 @@ pub type InsertCreateOutcomeHandle<'a, EXT, DB> = Arc< + 'a, >; +/// Handle EOF sub create. +pub type FrameEOFCreateHandle<'a, EXT, DB> = Arc< + dyn Fn( + &mut Context, + Box, + ) -> Result::Error>> + + 'a, +>; + +/// Handle EOF create return +pub type FrameEOFCreateReturnHandle<'a, EXT, DB> = Arc< + dyn Fn( + &mut Context, + Box, + InterpreterResult, + ) -> Result::Error>> + + 'a, +>; + +/// Insert EOF crate outcome to the parent +pub type InsertEOFCreateOutcomeHandle<'a, EXT, DB> = Arc< + dyn Fn( + &mut Context, + &mut Frame, + EOFCreateOutcome, + ) -> Result<(), EVMError<::Error>> + + 'a, +>; + /// Handles related to stack frames. pub struct ExecutionHandler<'a, EXT, DB: Database> { /// Handles last frame return, modified gas for refund and @@ -90,6 +122,12 @@ pub struct ExecutionHandler<'a, EXT, DB: Database> { pub create_return: FrameCreateReturnHandle<'a, EXT, DB>, /// Insert create outcome. pub insert_create_outcome: InsertCreateOutcomeHandle<'a, EXT, DB>, + /// Frame EOFCreate + pub eofcreate: FrameEOFCreateHandle<'a, EXT, DB>, + /// EOFCreate return + pub eofcreate_return: FrameEOFCreateReturnHandle<'a, EXT, DB>, + /// Insert EOFCreate outcome. + pub insert_eofcreate_outcome: InsertEOFCreateOutcomeHandle<'a, EXT, DB>, } impl<'a, EXT: 'a, DB: Database + 'a> ExecutionHandler<'a, EXT, DB> { @@ -103,6 +141,9 @@ impl<'a, EXT: 'a, DB: Database + 'a> ExecutionHandler<'a, EXT, DB> { create: Arc::new(mainnet::create::), create_return: Arc::new(mainnet::create_return::), insert_create_outcome: Arc::new(mainnet::insert_create_outcome), + eofcreate: Arc::new(mainnet::eofcreate::), + eofcreate_return: Arc::new(mainnet::eofcreate_return::), + insert_eofcreate_outcome: Arc::new(mainnet::insert_eofcreate_outcome), } } } @@ -182,4 +223,36 @@ impl<'a, EXT, DB: Database> ExecutionHandler<'a, EXT, DB> { ) -> Result<(), EVMError> { (self.insert_create_outcome)(context, frame, outcome) } + + /// Call Create frame + #[inline] + pub fn eofcreate( + &self, + context: &mut Context, + inputs: Box, + ) -> Result> { + (self.eofcreate)(context, inputs) + } + + /// Call handler for create return. + #[inline] + pub fn eofcreate_return( + &self, + context: &mut Context, + frame: Box, + interpreter_result: InterpreterResult, + ) -> Result> { + (self.eofcreate_return)(context, frame, interpreter_result) + } + + /// Call handler for inserting create outcome. + #[inline] + pub fn insert_eofcreate_outcome( + &self, + context: &mut Context, + frame: &mut Frame, + outcome: EOFCreateOutcome, + ) -> Result<(), EVMError> { + (self.insert_eofcreate_outcome)(context, frame, outcome) + } } diff --git a/crates/revm/src/handler/mainnet.rs b/crates/revm/src/handler/mainnet.rs index 605e4f7c..f02a8167 100644 --- a/crates/revm/src/handler/mainnet.rs +++ b/crates/revm/src/handler/mainnet.rs @@ -6,8 +6,9 @@ mod pre_execution; mod validation; pub use execution::{ - call, call_return, create, create_return, frame_return_with_refund_flag, insert_call_outcome, - insert_create_outcome, last_frame_return, + call, call_return, create, create_return, eofcreate, eofcreate_return, + frame_return_with_refund_flag, insert_call_outcome, insert_create_outcome, + insert_eofcreate_outcome, last_frame_return, }; pub use post_execution::{end, output, reimburse_caller, reward_beneficiary}; pub use pre_execution::{deduct_caller, deduct_caller_inner, load_accounts, load_precompiles}; diff --git a/crates/revm/src/handler/mainnet/execution.rs b/crates/revm/src/handler/mainnet/execution.rs index f5c0eb29..c4985b54 100644 --- a/crates/revm/src/handler/mainnet/execution.rs +++ b/crates/revm/src/handler/mainnet/execution.rs @@ -1,5 +1,6 @@ use crate::{ db::Database, + frame::EOFCreateFrame, interpreter::{ return_ok, return_revert, CallInputs, CreateInputs, CreateOutcome, Gas, InstructionResult, SharedMemory, @@ -7,7 +8,7 @@ use crate::{ primitives::{EVMError, Env, Spec, SpecId}, CallFrame, Context, CreateFrame, Frame, FrameOrResult, FrameResult, }; -use revm_interpreter::{CallOutcome, InterpreterResult}; +use revm_interpreter::{CallOutcome, EOFCreateInput, EOFCreateOutcome, InterpreterResult}; use std::boxed::Box; /// Helper function called inside [`last_frame_return`] @@ -136,6 +137,47 @@ pub fn insert_create_outcome( Ok(()) } +/// Handle frame sub create. +#[inline] +pub fn eofcreate( + context: &mut Context, + inputs: Box, +) -> Result> { + context.evm.make_eofcreate_frame(SPEC::SPEC_ID, &inputs) +} + +#[inline] +pub fn eofcreate_return( + context: &mut Context, + frame: Box, + mut interpreter_result: InterpreterResult, +) -> Result> { + context.evm.eofcreate_return::( + &mut interpreter_result, + frame.created_address, + frame.frame_data.checkpoint, + ); + Ok(EOFCreateOutcome::new( + interpreter_result, + frame.created_address, + frame.return_memory_range, + )) +} + +#[inline] +pub fn insert_eofcreate_outcome( + context: &mut Context, + frame: &mut Frame, + outcome: EOFCreateOutcome, +) -> Result<(), EVMError> { + core::mem::replace(&mut context.evm.error, Ok(()))?; + frame + .frame_data_mut() + .interpreter + .insert_eofcreate_outcome(outcome); + Ok(()) +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/revm/src/handler/mainnet/validation.rs b/crates/revm/src/handler/mainnet/validation.rs index 176e0e82..22dfb5f4 100644 --- a/crates/revm/src/handler/mainnet/validation.rs +++ b/crates/revm/src/handler/mainnet/validation.rs @@ -42,9 +42,10 @@ pub fn validate_initial_tx_gas( let input = &env.tx.data; let is_create = env.tx.transact_to.is_create(); let access_list = &env.tx.access_list; + let initcodes = &env.tx.eof_initcodes; let initial_gas_spend = - gas::validate_initial_tx_gas(SPEC::SPEC_ID, input, is_create, access_list); + gas::validate_initial_tx_gas(SPEC::SPEC_ID, input, is_create, access_list, initcodes); // Additional check to see if limit is big enough to cover initial gas. if initial_gas_spend > env.tx.gas_limit { diff --git a/crates/revm/src/inspector.rs b/crates/revm/src/inspector.rs index dbbd1876..170a42cd 100644 --- a/crates/revm/src/inspector.rs +++ b/crates/revm/src/inspector.rs @@ -1,5 +1,5 @@ use crate::{ - interpreter::{CallInputs, CreateInputs, Interpreter}, + interpreter::{CallInputs, CreateInputs, EOFCreateInput, EOFCreateOutcome, Interpreter}, primitives::{db::Database, Address, Log, U256}, EvmContext, }; @@ -135,6 +135,27 @@ pub trait Inspector { outcome } + fn eofcreate( + &mut self, + context: &mut EvmContext, + inputs: &mut EOFCreateInput, + ) -> Option { + let _ = context; + let _ = inputs; + None + } + + fn eofcreate_end( + &mut self, + context: &mut EvmContext, + inputs: &EOFCreateInput, + outcome: EOFCreateOutcome, + ) -> EOFCreateOutcome { + let _ = context; + let _ = inputs; + outcome + } + /// Called when a contract has been self-destructed with funds transferred to target. #[inline] fn selfdestruct(&mut self, contract: Address, target: Address, value: U256) { diff --git a/crates/revm/src/inspector/customprinter.rs b/crates/revm/src/inspector/customprinter.rs index 5e8c948b..ac7dd265 100644 --- a/crates/revm/src/inspector/customprinter.rs +++ b/crates/revm/src/inspector/customprinter.rs @@ -3,10 +3,11 @@ use revm_interpreter::CallOutcome; use revm_interpreter::CreateOutcome; +use revm_interpreter::OpCode; use crate::{ inspectors::GasInspector, - interpreter::{opcode, CallInputs, CreateInputs, Interpreter}, + interpreter::{CallInputs, CreateInputs, Interpreter}, primitives::{Address, U256}, Database, EvmContext, Inspector, }; @@ -28,7 +29,7 @@ impl Inspector for CustomPrintTracer { // all other information can be obtained from interp. fn step(&mut self, interp: &mut Interpreter, context: &mut EvmContext) { let opcode = interp.current_opcode(); - let opcode_str = opcode::OPCODE_JUMPMAP[opcode as usize]; + let name = OpCode::name_by_op(opcode); let gas_remaining = self.gas_inspector.gas_remaining(); @@ -40,7 +41,7 @@ impl Inspector for CustomPrintTracer { interp.program_counter(), gas_remaining, gas_remaining, - opcode_str.unwrap_or("UNKNOWN"), + name, opcode, interp.gas.refunded(), interp.gas.refunded(), @@ -79,11 +80,12 @@ impl Inspector for CustomPrintTracer { inputs: &mut CallInputs, ) -> Option { println!( - "SM CALL: {:?}, context:{:?}, is_static:{:?}, transfer:{:?}, input_size:{:?}", - inputs.contract, - inputs.context, + "SM Address: {:?}, caller:{:?},target:{:?} is_static:{:?}, transfer:{:?}, input_size:{:?}", + inputs.bytecode_address, + inputs.caller, + inputs.target_address, inputs.is_static, - inputs.transfer, + inputs.value, inputs.input.len(), ); None diff --git a/crates/revm/src/inspector/eip3155.rs b/crates/revm/src/inspector/eip3155.rs index ca1f6cc5..cbc4b817 100644 --- a/crates/revm/src/inspector/eip3155.rs +++ b/crates/revm/src/inspector/eip3155.rs @@ -1,12 +1,12 @@ use crate::{ inspectors::GasInspector, interpreter::{ - opcode, CallInputs, CallOutcome, CreateInputs, CreateOutcome, Interpreter, - InterpreterResult, + CallInputs, CallOutcome, CreateInputs, CreateOutcome, Interpreter, InterpreterResult, }, primitives::{db::Database, hex, HashMap, B256, U256}, EvmContext, Inspector, }; +use revm_interpreter::OpCode; use serde::Serialize; use std::io::Write; @@ -176,7 +176,6 @@ impl TracerEip3155 { context.inner.env().tx.gas_limit - self.gas_inspector.gas_remaining(), ), pass: result.is_ok(), - time: None, fork: Some(spec_name.to_string()), }; @@ -223,7 +222,7 @@ impl Inspector for TracerEip3155 { refund: hex_number(self.refunded as u64), mem_size: self.mem_size.to_string(), - op_name: opcode::OPCODE_JUMPMAP[self.opcode as usize], + op_name: OpCode::new(self.opcode).map(|i| i.info().name), error: if !interp.instruction_result.is_ok() { Some(format!("{:?}", interp.instruction_result)) } else { diff --git a/crates/revm/src/inspector/handler_register.rs b/crates/revm/src/inspector/handler_register.rs index 0cf496a4..65a60dae 100644 --- a/crates/revm/src/inspector/handler_register.rs +++ b/crates/revm/src/inspector/handler_register.rs @@ -16,7 +16,7 @@ pub trait GetInspector { } impl> GetInspector for INSP { - #[inline(always)] + #[inline] fn get_inspector(&mut self) -> &mut impl Inspector { self } @@ -132,6 +132,7 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector>( // inputs in *_end Inspector calls. let call_input_stack = Rc::>>::new(RefCell::new(Vec::new())); let create_input_stack = Rc::>>::new(RefCell::new(Vec::new())); + let eofcreate_input_stack = Rc::>>::new(RefCell::new(Vec::new())); // Create handler let create_input_stack_inner = create_input_stack.clone(); @@ -178,6 +179,8 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector>( }, ); + // TODO(EOF) EOF create call. + // call outcome let call_input_stack_inner = call_input_stack.clone(); let old_handle = handler.execution.insert_call_outcome.clone(); @@ -203,6 +206,8 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector>( old_handle(ctx, frame, outcome) }); + // TODO(EOF) EOF create handle. + // last frame outcome let old_handle = handler.execution.last_frame_return.clone(); handler.execution.last_frame_return = Arc::new(move |ctx, frame_result| { @@ -216,6 +221,11 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector>( let create_inputs = create_input_stack.borrow_mut().pop().unwrap(); *outcome = inspector.create_end(&mut ctx.evm, &create_inputs, outcome.clone()); } + FrameResult::EOFCreate(outcome) => { + let eofcreate_inputs = eofcreate_input_stack.borrow_mut().pop().unwrap(); + *outcome = + inspector.eofcreate_end(&mut ctx.evm, &eofcreate_inputs, outcome.clone()); + } } old_handle(ctx, frame_result) }); diff --git a/crates/revm/src/journaled_state.rs b/crates/revm/src/journaled_state.rs index 9fb0e4ca..a5eee7e2 100644 --- a/crates/revm/src/journaled_state.rs +++ b/crates/revm/src/journaled_state.rs @@ -5,7 +5,7 @@ use crate::primitives::{ }; use core::mem; use revm_interpreter::primitives::SpecId; -use revm_interpreter::SStoreResult; +use revm_interpreter::{LoadAccountResult, SStoreResult}; use std::vec::Vec; /// JournalState is internal EVM state that is used to contain state and track changes to that state. @@ -460,7 +460,7 @@ impl JournaledState { target: Address, db: &mut DB, ) -> Result> { - let (is_cold, target_exists) = self.load_account_exist(target, db)?; + let load_result = self.load_account_exist(target, db)?; if address != target { // Both accounts are loaded before this point, `address` as we execute its contract. @@ -508,8 +508,8 @@ impl JournaledState { Ok(SelfDestructResult { had_value: balance != U256::ZERO, - is_cold, - target_exists, + is_cold: load_result.is_cold, + target_exists: !load_result.is_empty, previously_destroyed, }) } @@ -581,19 +581,20 @@ impl JournaledState { &mut self, address: Address, db: &mut DB, - ) -> Result<(bool, bool), EVMError> { + ) -> Result> { let spec = self.spec; let (acc, is_cold) = self.load_account(address, db)?; let is_spurious_dragon_enabled = SpecId::enabled(spec, SPURIOUS_DRAGON); - let exist = if is_spurious_dragon_enabled { - !acc.is_empty() + let is_empty = if is_spurious_dragon_enabled { + acc.is_empty() } else { - let is_existing = !acc.is_loaded_as_not_existing(); - let is_touched = acc.is_touched(); - is_existing || is_touched + let loaded_not_existing = acc.is_loaded_as_not_existing(); + let is_not_touched = !acc.is_touched(); + loaded_not_existing && is_not_touched }; - Ok((is_cold, exist)) + + Ok(LoadAccountResult { is_empty, is_cold }) } /// Loads code. @@ -606,7 +607,7 @@ impl JournaledState { let (acc, is_cold) = self.load_account(address, db)?; if acc.info.code.is_none() { if acc.info.code_hash == KECCAK_EMPTY { - let empty = Bytecode::new(); + let empty = Bytecode::default(); acc.info.code = Some(empty); } else { let code = db diff --git a/documentation/src/crates/primitives/bytecode.md b/documentation/src/crates/primitives/bytecode.md index 03f7356a..5696488c 100644 --- a/documentation/src/crates/primitives/bytecode.md +++ b/documentation/src/crates/primitives/bytecode.md @@ -1,9 +1,9 @@ # Bytecode -This module defines structures and methods to manipulate Ethereum bytecode and manage its state. It's built around three main components: `JumpMap`, `BytecodeState`, and `Bytecode`. +This module defines structures and methods to manipulate Ethereum bytecode and manage its state. It's built around three main components: `JumpTable`, `BytecodeState`, and `Bytecode`. -The `JumpMap` structure stores a map of valid `jump` destinations within a given Ethereum bytecode sequence. It is essentially an `Arc` (Atomic Reference Counter) wrapping a `BitVec` (bit vector), which can be accessed and modified using the defined methods, such as `as_slice()`, `from_slice()`, and `is_valid()`. +The `JumpTable` structure stores a map of valid `jump` destinations within a given Ethereum bytecode sequence. It is essentially an `Arc` (Atomic Reference Counter) wrapping a `BitVec` (bit vector), which can be accessed and modified using the defined methods, such as `as_slice()`, `from_slice()`, and `is_valid()`. -The `BytecodeState` is an enumeration, capturing the three possible states of the bytecode: `Raw`, `Checked`, and `Analysed`. In the `Checked` and `Analysed` states, additional data is provided, such as the length of the bytecode and, in the `Analysed` state, a `JumpMap`. +The `BytecodeState` is an enumeration, capturing the three possible states of the bytecode: `Raw`, `Checked`, and `Analysed`. In the `Checked` and `Analysed` states, additional data is provided, such as the length of the bytecode and, in the `Analysed` state, a `JumpTable`. The `Bytecode` struct holds the actual bytecode, its hash, and its current state (`BytecodeState`). It provides several methods to interact with the bytecode, such as getting the length of the bytecode, checking if it's empty, retrieving its state, and converting the bytecode to a checked state. It also provides methods to create new instances of the `Bytecode` struct in different states. From cf96ce8ace3c4e63255554411127d0eb8b7c9ecc Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Wed, 10 Apr 2024 01:54:56 +0200 Subject: [PATCH 016/105] feat(revme): add --keep-going to statetest command (#1277) --- bins/revme/src/cmd/statetest.rs | 10 ++- bins/revme/src/cmd/statetest/runner.rs | 105 ++++++++++++++++--------- 2 files changed, 75 insertions(+), 40 deletions(-) diff --git a/bins/revme/src/cmd/statetest.rs b/bins/revme/src/cmd/statetest.rs index 1284f41a..cc082cb0 100644 --- a/bins/revme/src/cmd/statetest.rs +++ b/bins/revme/src/cmd/statetest.rs @@ -29,6 +29,8 @@ pub struct Cmd { /// It will stop second run of evm on failure. #[structopt(short = "o", long)] json_outcome: bool, + #[structopt(long, alias = "no-fail-fast")] + keep_going: bool, } impl Cmd { @@ -37,7 +39,13 @@ impl Cmd { for path in &self.path { println!("\nRunning tests in {}...", path.display()); let test_files = find_all_json_tests(path); - run(test_files, self.single_thread, self.json, self.json_outcome)? + run( + test_files, + self.single_thread, + self.json, + self.json_outcome, + self.keep_going, + )? } Ok(()) } diff --git a/bins/revme/src/cmd/statetest/runner.rs b/bins/revme/src/cmd/statetest/runner.rs index f2a58b61..2094056a 100644 --- a/bins/revme/src/cmd/statetest/runner.rs +++ b/bins/revme/src/cmd/statetest/runner.rs @@ -19,8 +19,10 @@ use std::{ convert::Infallible, io::{stderr, stdout}, path::{Path, PathBuf}, - sync::atomic::Ordering, - sync::{atomic::AtomicBool, Arc, Mutex}, + sync::{ + atomic::{AtomicBool, AtomicUsize, Ordering}, + Arc, Mutex, + }, time::{Duration, Instant}, }; use thiserror::Error; @@ -35,33 +37,35 @@ pub struct TestError { #[derive(Debug, Error)] pub enum TestErrorKind { - #[error("logs root mismatch: expected {expected:?}, got {got:?}")] + #[error("logs root mismatch: got {got}, expected {expected}")] LogsRootMismatch { got: B256, expected: B256 }, - #[error("state root mismatch: expected {expected:?}, got {got:?}")] + #[error("state root mismatch: got {got}, expected {expected}")] StateRootMismatch { got: B256, expected: B256 }, - #[error("Unknown private key: {0:?}")] + #[error("unknown private key: {0:?}")] UnknownPrivateKey(B256), - #[error("Unexpected exception: {got_exception:?} but test expects:{expected_exception:?}")] + #[error("unexpected exception: got {got_exception:?}, expected {expected_exception:?}")] UnexpectedException { expected_exception: Option, got_exception: Option, }, - #[error("Unexpected output: {got_output:?} but test expects:{expected_output:?}")] + #[error("unexpected output: got {got_output:?}, expected {expected_output:?}")] UnexpectedOutput { expected_output: Option, got_output: Option, }, #[error(transparent)] SerdeDeserialize(#[from] serde_json::Error), + #[error("thread panicked")] + Panic, } pub fn find_all_json_tests(path: &Path) -> Vec { WalkDir::new(path) .into_iter() - .filter_map(|e| e.ok()) - .filter(|e| e.file_name().to_string_lossy().ends_with(".json")) + .filter_map(Result::ok) + .filter(|e| e.path().extension() == Some("json".as_ref())) .map(DirEntry::into_path) - .collect::>() + .collect() } fn skip_test(path: &Path) -> bool { @@ -120,19 +124,26 @@ fn check_evm_execution( let print_json_output = |error: Option| { if print_json_outcome { let json = json!({ - "stateRoot": state_root, - "logsRoot": logs_root, - "output": exec_result.as_ref().ok().and_then(|r| r.output().cloned()).unwrap_or_default(), - "gasUsed": exec_result.as_ref().ok().map(|r| r.gas_used()).unwrap_or_default(), - "pass": error.is_none(), - "errorMsg": error.unwrap_or_default(), - "evmResult": exec_result.as_ref().err().map(|e| e.to_string()).unwrap_or("Ok".to_string()), - "postLogsHash": logs_root, - "fork": evm.handler.cfg().spec_id, - "test": test_name, - "d": test.indexes.data, - "g": test.indexes.gas, - "v": test.indexes.value, + "stateRoot": state_root, + "logsRoot": logs_root, + "output": exec_result.as_ref().ok().and_then(|r| r.output().cloned()).unwrap_or_default(), + "gasUsed": exec_result.as_ref().ok().map(|r| r.gas_used()).unwrap_or_default(), + "pass": error.is_none(), + "errorMsg": error.unwrap_or_default(), + "evmResult": match exec_result { + Ok(r) => match r { + ExecutionResult::Success { reason, .. } => format!("Success: {reason:?}"), + ExecutionResult::Revert { .. } => "Revert".to_string(), + ExecutionResult::Halt { reason, .. } => format!("Halt: {reason:?}"), + }, + Err(e) => e.to_string(), + }, + "postLogsHash": logs_root, + "fork": evm.handler.cfg().spec_id, + "test": test_name, + "d": test.indexes.data, + "g": test.indexes.gas, + "v": test.indexes.value, }); eprintln!("{json}"); } @@ -443,6 +454,7 @@ pub fn run( mut single_thread: bool, trace: bool, mut print_outcome: bool, + keep_going: bool, ) -> Result<(), TestError> { // trace implies print_outcome if trace { @@ -454,7 +466,7 @@ pub fn run( } let n_files = test_files.len(); - let endjob = Arc::new(AtomicBool::new(false)); + let n_errors = Arc::new(AtomicUsize::new(0)); let console_bar = Arc::new(ProgressBar::with_draw_target( Some(n_files as u64), ProgressDrawTarget::stdout(), @@ -470,14 +482,14 @@ pub fn run( let mut handles = Vec::with_capacity(num_threads); for i in 0..num_threads { let queue = queue.clone(); - let endjob = endjob.clone(); + let n_errors = n_errors.clone(); let console_bar = console_bar.clone(); let elapsed = elapsed.clone(); let thread = std::thread::Builder::new().name(format!("runner-{i}")); let f = move || loop { - if endjob.load(Ordering::SeqCst) { + if !keep_going && n_errors.load(Ordering::SeqCst) > 0 { return Ok(()); } @@ -491,20 +503,27 @@ pub fn run( (prev_idx, test_path) }; + console_bar.inc(1); if let Err(err) = execute_test_suite(&test_path, &elapsed, trace, print_outcome) { - endjob.store(true, Ordering::SeqCst); - return Err(err); + n_errors.fetch_add(1, Ordering::SeqCst); + if !keep_going { + return Err(err); + } } - console_bar.inc(1); }; handles.push(thread.spawn(f).unwrap()); } // join all threads before returning an error - let mut errors = Vec::new(); - for handle in handles { - if let Err(e) = handle.join().unwrap() { - errors.push(e); + let mut thread_errors = Vec::new(); + for (i, handle) in handles.into_iter().enumerate() { + match handle.join() { + Ok(Ok(())) => {} + Ok(Err(e)) => thread_errors.push(e), + Err(_) => thread_errors.push(TestError { + name: format!("thread {i} panicked"), + kind: TestErrorKind::Panic, + }), } } console_bar.finish(); @@ -513,17 +532,25 @@ pub fn run( "Finished execution. Total CPU time: {:.6}s", elapsed.lock().unwrap().as_secs_f64() ); - if errors.is_empty() { + + let n_errors = n_errors.load(Ordering::SeqCst); + let n_thread_errors = thread_errors.len(); + if n_errors == 0 && n_thread_errors == 0 { println!("All tests passed!"); Ok(()) } else { - let n = errors.len(); - if n > 1 { - println!("{n} threads returned an error, out of {num_threads} total:"); - for error in &errors { + println!("Encountered {n_errors} errors out of {n_files} total tests"); + + if n_thread_errors == 0 { + std::process::exit(1); + } + + if n_thread_errors > 1 { + println!("{n_thread_errors} threads returned an error, out of {num_threads} total:"); + for error in &thread_errors { println!("{error}"); } } - Err(errors.swap_remove(0)) + Err(thread_errors.swap_remove(0)) } } From cfc4511fe148296394c19c9ab3fb46f663218413 Mon Sep 17 00:00:00 2001 From: Jonathan Becker Date: Tue, 9 Apr 2024 20:03:21 -0400 Subject: [PATCH 017/105] docs(inspectors): change `serde` to `serde-json` for `TracerEip3155` (#1285) --- documentation/src/crates/revm/inspector.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/src/crates/revm/inspector.md b/documentation/src/crates/revm/inspector.md index d17a4e32..d9bdfe8b 100644 --- a/documentation/src/crates/revm/inspector.md +++ b/documentation/src/crates/revm/inspector.md @@ -14,7 +14,7 @@ There are several built-in inspectors in this module: - `TracerEip3155`: This is an inspector that conforms to the [EIP-3155](https://eips.ethereum.org/EIPS/eip-3155) standard for tracing Ethereum transactions. It's used to generate detailed trace data of transaction execution, which can be useful for debugging, analysis, or for building tools that need to understand the inner workings of Ethereum transactions. - This is only available when both `std` and `serde` features are enabled. + This is only available when both `std` and `serde-json` features are enabled. ## Inspector trait From e0f72a07d15557fd1f6e432cf87b989b5076f231 Mon Sep 17 00:00:00 2001 From: Wodann Date: Sat, 13 Apr 2024 07:07:59 -0500 Subject: [PATCH 018/105] feat: add flag to force hashbrown usage (#1284) * feat: add flag to force hashbrown usage * misc: propagate hashbrown feature flag --- crates/interpreter/Cargo.toml | 1 + crates/precompile/Cargo.toml | 1 + crates/primitives/Cargo.toml | 1 + crates/primitives/src/lib.rs | 2 +- crates/revm/Cargo.toml | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/interpreter/Cargo.toml b/crates/interpreter/Cargo.toml index e828fb07..3f2fa561 100644 --- a/crates/interpreter/Cargo.toml +++ b/crates/interpreter/Cargo.toml @@ -35,6 +35,7 @@ required-features = ["serde"] [features] default = ["std"] std = ["serde?/std", "revm-primitives/std"] +hashbrown = ["revm-primitives/hashbrown"] serde = ["dep:serde", "revm-primitives/serde"] arbitrary = ["std", "revm-primitives/arbitrary"] asm-keccak = ["revm-primitives/asm-keccak"] diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index 72844309..3d1c8e71 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -48,6 +48,7 @@ std = [ "c-kzg?/std", "secp256k1?/std", ] +hashbrown = ["revm-primitives/hashbrown"] asm-keccak = ["revm-primitives/asm-keccak"] optimism = ["revm-primitives/optimism"] diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 7542c929..b9fbb9fc 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -53,6 +53,7 @@ std = [ "bitvec/std", "bitflags/std", ] +hashbrown = [] serde = [ "dep:serde", "alloy-primitives/serde", diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index de906f3d..2ce1a8e5 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -31,7 +31,7 @@ pub use constants::*; pub use env::*; cfg_if::cfg_if! { - if #[cfg(feature = "std")] { + if #[cfg(all(not(feature = "hashbrown"), feature = "std"))] { pub use std::collections::{hash_map, hash_set, HashMap, HashSet}; use hashbrown as _; } else { diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 73c7c34f..f8be0f7e 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -64,6 +64,7 @@ std = [ "revm-interpreter/std", "revm-precompile/std", ] +hashbrown = ["revm-interpreter/hashbrown", "revm-precompile/hashbrown"] serde = ["dep:serde", "revm-interpreter/serde"] serde-json = ["serde", "dep:serde_json"] arbitrary = ["revm-interpreter/arbitrary"] From fa9e1270d7ec0e4a3b40d7261c36d30dd55bb547 Mon Sep 17 00:00:00 2001 From: n0b0dy Date: Sat, 13 Apr 2024 20:10:37 +0800 Subject: [PATCH 019/105] feat(revm): make `FrameOrResult` serializable (#1282) * feat(revm): make `FrameOrResult` serializable This commit make all structs under `FrameOrResult` serializable, which is useful when trying to save execution state inside an inspector during transaction execution. The modified structs include: * revm: `FrameOrResult`, `FrameResult`, `Frame`, `FrameData`, `CallFrame`, `CreateFrame`, `JournalCheckpoint` * interpreter: `BytecodeLocked`, `Contract`, `Gas`, `CreateOutcome`, `CallOutcome`, `Interpreter` * style(interpreter): make clippy happy * fix(interpreter): fix missing conflict * style(interpreter): make clippy happy --- Cargo.lock | 10 + crates/interpreter/Cargo.toml | 2 +- crates/interpreter/src/function_stack.rs | 2 + crates/interpreter/src/gas.rs | 1 + crates/interpreter/src/interpreter.rs | 3 + .../interpreter/src/interpreter/contract.rs | 1 + crates/interpreter/src/interpreter/serde.rs | 242 ++++++++++++++++++ crates/interpreter/src/interpreter_action.rs | 1 + .../src/interpreter_action/call_outcome.rs | 1 + .../src/interpreter_action/create_outcome.rs | 1 + .../interpreter_action/eof_create_inputs.rs | 1 + .../interpreter_action/eof_create_outcome.rs | 1 + crates/revm/src/frame.rs | 7 + crates/revm/src/journaled_state.rs | 1 + 14 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 crates/interpreter/src/interpreter/serde.rs diff --git a/Cargo.lock b/Cargo.lock index d008a35c..10b8c1f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -622,6 +622,15 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bit-set" version = "0.5.3" @@ -2868,6 +2877,7 @@ dependencies = [ name = "revm-interpreter" version = "4.0.0" dependencies = [ + "bincode", "revm-primitives", "serde", "serde_json", diff --git a/crates/interpreter/Cargo.toml b/crates/interpreter/Cargo.toml index 3f2fa561..e9fe68cb 100644 --- a/crates/interpreter/Cargo.toml +++ b/crates/interpreter/Cargo.toml @@ -25,13 +25,13 @@ serde = { version = "1.0", default-features = false, features = [ [dev-dependencies] walkdir = "2.5" serde_json = { version = "1.0"} +bincode = "1.3" [[test]] name = "eof" path = "tests/eof.rs" required-features = ["serde"] - [features] default = ["std"] std = ["serde?/std", "revm-primitives/std"] diff --git a/crates/interpreter/src/function_stack.rs b/crates/interpreter/src/function_stack.rs index ef786cd6..3f0f5d64 100644 --- a/crates/interpreter/src/function_stack.rs +++ b/crates/interpreter/src/function_stack.rs @@ -2,6 +2,7 @@ use std::vec::Vec; /// Function return frame. /// Needed information for returning from a function. #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FunctionReturnFrame { /// The index of the code container that this frame is executing. pub idx: usize, @@ -18,6 +19,7 @@ impl FunctionReturnFrame { /// Function Stack #[derive(Debug, Default)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FunctionStack { pub return_stack: Vec, pub current_code_idx: usize, diff --git a/crates/interpreter/src/gas.rs b/crates/interpreter/src/gas.rs index 94c440f4..387f4737 100644 --- a/crates/interpreter/src/gas.rs +++ b/crates/interpreter/src/gas.rs @@ -8,6 +8,7 @@ pub use constants::*; /// Represents the state of gas during execution. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Gas { /// The initial gas limit. This is constant throughout execution. limit: u64, diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index 6d0b6320..1d415772 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -1,5 +1,7 @@ pub mod analysis; mod contract; +#[cfg(feature = "serde")] +pub mod serde; mod shared_memory; mod stack; @@ -68,6 +70,7 @@ impl Default for Interpreter { /// The result of an interpreter operation. #[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))] pub struct InterpreterResult { /// The result of the instruction execution. pub result: InstructionResult, diff --git a/crates/interpreter/src/interpreter/contract.rs b/crates/interpreter/src/interpreter/contract.rs index 5959c7cf..f8625e85 100644 --- a/crates/interpreter/src/interpreter/contract.rs +++ b/crates/interpreter/src/interpreter/contract.rs @@ -6,6 +6,7 @@ use crate::{ /// EVM contract information. #[derive(Clone, Debug, Default)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Contract { /// Contracts data pub input: Bytes, diff --git a/crates/interpreter/src/interpreter/serde.rs b/crates/interpreter/src/interpreter/serde.rs new file mode 100644 index 00000000..eb4d8524 --- /dev/null +++ b/crates/interpreter/src/interpreter/serde.rs @@ -0,0 +1,242 @@ +use crate::{ + Contract, FunctionStack, Gas, InstructionResult, InterpreterAction, SharedMemory, Stack, +}; + +use super::Interpreter; +use revm_primitives::Bytes; +use serde::de::{self, MapAccess, Visitor}; +use serde::ser::SerializeStruct; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use std::fmt; + +impl Serialize for Interpreter { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state = serializer.serialize_struct("Interpreter", 8)?; + // Convert the instruction pointer to a usize for serialization + let program_counter = self.program_counter(); + state.serialize_field("program_counter", &program_counter)?; + state.serialize_field("gas", &self.gas)?; + state.serialize_field("contract", &self.contract)?; + state.serialize_field("instruction_result", &self.instruction_result)?; + state.serialize_field("bytecode", &self.bytecode)?; + state.serialize_field("is_eof", &self.is_eof)?; + state.serialize_field("is_eof_init", &self.is_eof_init)?; + state.serialize_field("shared_memory", &self.shared_memory)?; + state.serialize_field("stack", &self.stack)?; + state.serialize_field("function_stack", &self.function_stack)?; + state.serialize_field("return_data_buffer", &self.return_data_buffer)?; + state.serialize_field("is_static", &self.is_static)?; + state.serialize_field("next_action", &self.next_action)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for Interpreter { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct InterpreterVisitor; + + #[derive(serde::Deserialize)] + #[serde(field_identifier, rename_all = "lowercase")] + enum InterpreterFields { + ProgramCounter, + Gas, + Contract, + InstructionResult, + Bytecode, + IsEof, + IsEofInit, + SharedMemory, + Stack, + FunctionStack, + ReturnDataBuffer, + IsStatic, + NextAction, + } + + #[allow(clippy::too_many_arguments)] + fn rebuild_interp( + program_counter: isize, + gas: Gas, + contract: Contract, + instruction_result: InstructionResult, + bytecode: Bytes, + is_eof: bool, + is_eof_init: bool, + shared_memory: SharedMemory, + stack: Stack, + function_stack: FunctionStack, + return_data_buffer: Bytes, + is_static: bool, + next_action: InterpreterAction, + ) -> Result { + // Reconstruct the instruction pointer from usize + if program_counter < 0 || program_counter >= bytecode.len() as isize { + return Err("program_counter index out of range"); + } + + // SAFETY: range of program_counter checked above + let instruction_pointer = unsafe { bytecode.as_ptr().offset(program_counter) }; + + // Construct and return the Interpreter instance + Ok(Interpreter { + instruction_pointer, + gas, + contract, + instruction_result, + bytecode, + is_eof, + is_eof_init, + shared_memory, + stack, + function_stack, + return_data_buffer, + is_static, + next_action, + }) + } + + impl<'de> Visitor<'de> for InterpreterVisitor { + type Value = Interpreter; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("struct Interpreter") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: de::SeqAccess<'de>, + { + macro_rules! extract_field { + ($i:ident, $idx:expr) => { + let $i = seq + .next_element()? + .ok_or_else(|| de::Error::invalid_length($idx, &self))?; + }; + } + extract_field!(instruction_pointer, 0); + extract_field!(gas, 1); + extract_field!(contract, 2); + extract_field!(instruction_result, 3); + extract_field!(bytecode, 4); + extract_field!(is_eof, 5); + extract_field!(is_eof_init, 6); + extract_field!(shared_memory, 7); + extract_field!(stack, 8); + extract_field!(function_stack, 9); + extract_field!(return_data_buffer, 10); + extract_field!(is_static, 11); + extract_field!(next_action, 12); + rebuild_interp( + instruction_pointer, + gas, + contract, + instruction_result, + bytecode, + is_eof, + is_eof_init, + shared_memory, + stack, + function_stack, + return_data_buffer, + is_static, + next_action, + ) + .map_err(de::Error::custom) + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + macro_rules! parse_map { + ( $(($enum:pat, $var_name:ident)),* ) => { + $( + let mut $var_name = None; + )* + while let Some(key) = map.next_key()? { + match key { + $( + $enum => { + $var_name = Some(map.next_value()?); + } + )* + } + } + $( + let $var_name = $var_name.ok_or_else(|| de::Error::missing_field(stringify!($var_name)))?; + )* + }; + } + parse_map!( + (InterpreterFields::ProgramCounter, program_counter), + (InterpreterFields::Gas, gas), + (InterpreterFields::Contract, contract), + (InterpreterFields::InstructionResult, instruction_result), + (InterpreterFields::Bytecode, bytecode), + (InterpreterFields::IsEof, is_eof), + (InterpreterFields::IsEofInit, is_eof_init), + (InterpreterFields::SharedMemory, shared_memory), + (InterpreterFields::Stack, stack), + (InterpreterFields::FunctionStack, function_stack), + (InterpreterFields::ReturnDataBuffer, return_data_buffer), + (InterpreterFields::IsStatic, is_static), + (InterpreterFields::NextAction, next_action) + ); + + rebuild_interp( + program_counter, + gas, + contract, + instruction_result, + bytecode, + is_eof, + is_eof_init, + shared_memory, + stack, + function_stack, + return_data_buffer, + is_static, + next_action, + ) + .map_err(de::Error::custom) + } + } + + const FIELDS: &[&str] = &[ + "program_counter", + "gas", + "contract", + "instruction_result", + "bytecode", + "is_eof", + "is_eof_init", + "shared_memory", + "stack", + "function_stack", + "return_data_buffer", + "is_static", + "next_action", + ]; + + deserializer.deserialize_struct("Interpreter", FIELDS, InterpreterVisitor) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_serde() { + let interp = Interpreter::new(Contract::default(), u64::MAX, false); + let serialized = bincode::serialize(&interp).unwrap(); + let de: Interpreter = bincode::deserialize(&serialized).unwrap(); + assert_eq!(interp.program_counter(), de.program_counter()); + } +} diff --git a/crates/interpreter/src/interpreter_action.rs b/crates/interpreter/src/interpreter_action.rs index a6a3aa21..25dc1448 100644 --- a/crates/interpreter/src/interpreter_action.rs +++ b/crates/interpreter/src/interpreter_action.rs @@ -16,6 +16,7 @@ use crate::InterpreterResult; use std::boxed::Box; #[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum InterpreterAction { /// CALL, CALLCODE, DELEGATECALL, STATICCALL /// or EOF EXT instuction called. diff --git a/crates/interpreter/src/interpreter_action/call_outcome.rs b/crates/interpreter/src/interpreter_action/call_outcome.rs index c7efc9c5..f51c01fc 100644 --- a/crates/interpreter/src/interpreter_action/call_outcome.rs +++ b/crates/interpreter/src/interpreter_action/call_outcome.rs @@ -12,6 +12,7 @@ use revm_primitives::Bytes; /// * `result` - The result of the interpreter's execution, including output data and gas usage. /// * `memory_offset` - The range in memory where the output data is located. #[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct CallOutcome { pub result: InterpreterResult, pub memory_offset: Range, diff --git a/crates/interpreter/src/interpreter_action/create_outcome.rs b/crates/interpreter/src/interpreter_action/create_outcome.rs index db43eb76..5cdfcf41 100644 --- a/crates/interpreter/src/interpreter_action/create_outcome.rs +++ b/crates/interpreter/src/interpreter_action/create_outcome.rs @@ -6,6 +6,7 @@ use revm_primitives::{Address, Bytes}; /// This struct holds the result of the operation along with an optional address. /// It provides methods to determine the next action based on the result of the operation. #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct CreateOutcome { // The result of the interpreter operation. pub result: InterpreterResult, diff --git a/crates/interpreter/src/interpreter_action/eof_create_inputs.rs b/crates/interpreter/src/interpreter_action/eof_create_inputs.rs index a5ce043c..25dac1e0 100644 --- a/crates/interpreter/src/interpreter_action/eof_create_inputs.rs +++ b/crates/interpreter/src/interpreter_action/eof_create_inputs.rs @@ -3,6 +3,7 @@ use core::ops::Range; /// Inputs for EOF create call. #[derive(Debug, Default, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct EOFCreateInput { /// Caller of Eof Craate pub caller: Address, diff --git a/crates/interpreter/src/interpreter_action/eof_create_outcome.rs b/crates/interpreter/src/interpreter_action/eof_create_outcome.rs index 031e1180..9ec669a0 100644 --- a/crates/interpreter/src/interpreter_action/eof_create_outcome.rs +++ b/crates/interpreter/src/interpreter_action/eof_create_outcome.rs @@ -8,6 +8,7 @@ use revm_primitives::{Address, Bytes}; /// This struct holds the result of the operation along with an optional address. /// It provides methods to determine the next action based on the result of the operation. #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct EOFCreateOutcome { /// The result of the interpreter operation. pub result: InterpreterResult, diff --git a/crates/revm/src/frame.rs b/crates/revm/src/frame.rs index 64f19009..72576505 100644 --- a/crates/revm/src/frame.rs +++ b/crates/revm/src/frame.rs @@ -11,6 +11,7 @@ use std::boxed::Box; /// Call CallStackFrame. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct CallFrame { /// Call frame has return memory range where output will be stored. pub return_memory_range: Range, @@ -19,6 +20,7 @@ pub struct CallFrame { } #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct CreateFrame { /// Create frame has a created address. pub created_address: Address, @@ -28,6 +30,7 @@ pub struct CreateFrame { /// Eof Create Frame. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct EOFCreateFrame { pub created_address: Address, pub return_memory_range: Range, @@ -35,6 +38,7 @@ pub struct EOFCreateFrame { } #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FrameData { /// Journal checkpoint. pub checkpoint: JournalCheckpoint, @@ -44,12 +48,14 @@ pub struct FrameData { /// Call stack frame. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum Frame { Call(Box), Create(Box), EOFCreate(Box), } +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FrameResult { Call(CallOutcome), Create(CreateOutcome), @@ -129,6 +135,7 @@ impl FrameResult { } /// Contains either a frame or a result. +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FrameOrResult { /// Boxed call or create frame. Frame(Frame), diff --git a/crates/revm/src/journaled_state.rs b/crates/revm/src/journaled_state.rs index a5eee7e2..18899509 100644 --- a/crates/revm/src/journaled_state.rs +++ b/crates/revm/src/journaled_state.rs @@ -836,6 +836,7 @@ pub enum JournalEntry { /// SubRoutine checkpoint that will help us to go back from this #[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct JournalCheckpoint { log_i: usize, journal_i: usize, From 7957c020a1171e083cbdfc860c3eff988d076f18 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Sat, 13 Apr 2024 14:11:45 +0200 Subject: [PATCH 020/105] feat: add `Bytecode::original_bytecode_slice` to match `BytecodeLocked` (#1286) --- crates/primitives/src/bytecode.rs | 12 +++++++++++- crates/primitives/src/bytecode/legacy.rs | 7 ++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/crates/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index 538a57af..e36afa48 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -47,7 +47,7 @@ impl Bytecode { if self.is_empty() { KECCAK_EMPTY } else { - keccak256(&self.original_bytes()) + keccak256(self.original_byte_slice()) } } @@ -118,6 +118,16 @@ impl Bytecode { } } + /// Returns the original bytecode as a byte slice. + #[inline] + pub fn original_byte_slice(&self) -> &[u8] { + match self { + Self::LegacyRaw(bytes) => bytes, + Self::LegacyAnalyzed(analyzed) => analyzed.original_byte_slice(), + Self::Eof(eof) => eof.raw(), + } + } + /// Returns the length of the raw bytes. #[inline] pub fn len(&self) -> usize { diff --git a/crates/primitives/src/bytecode/legacy.rs b/crates/primitives/src/bytecode/legacy.rs index 18949f0a..3e6f2d2b 100644 --- a/crates/primitives/src/bytecode/legacy.rs +++ b/crates/primitives/src/bytecode/legacy.rs @@ -53,7 +53,12 @@ impl LegacyAnalyzedBytecode { /// Original bytes without padding. pub fn original_bytes(&self) -> Bytes { - self.bytecode.slice(0..self.original_len) + self.bytecode.slice(..self.original_len) + } + + /// Original bytes without padding. + pub fn original_byte_slice(&self) -> &[u8] { + &self.bytecode[..self.original_len] } /// Jumptable of analyzed bytes. From 5d25c4d932e912619bd3ca5622b431f7896858a6 Mon Sep 17 00:00:00 2001 From: Mihir Wadekar Date: Sat, 13 Apr 2024 05:12:07 -0700 Subject: [PATCH 021/105] fix: Drops check for .json when testing a single file (#1301) --- bins/revme/src/cmd/statetest/runner.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/bins/revme/src/cmd/statetest/runner.rs b/bins/revme/src/cmd/statetest/runner.rs index 2094056a..72562356 100644 --- a/bins/revme/src/cmd/statetest/runner.rs +++ b/bins/revme/src/cmd/statetest/runner.rs @@ -60,12 +60,16 @@ pub enum TestErrorKind { } pub fn find_all_json_tests(path: &Path) -> Vec { - WalkDir::new(path) - .into_iter() - .filter_map(Result::ok) - .filter(|e| e.path().extension() == Some("json".as_ref())) - .map(DirEntry::into_path) - .collect() + if path.is_file() { + vec![path.to_path_buf()] + } else { + WalkDir::new(path) + .into_iter() + .filter_map(Result::ok) + .filter(|e| e.path().extension() == Some("json".as_ref())) + .map(DirEntry::into_path) + .collect() + } } fn skip_test(path: &Path) -> bool { From f4f4745e00b1c2907b6a3527eee3765bc1603b58 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Sat, 13 Apr 2024 14:13:15 +0200 Subject: [PATCH 022/105] fix: correct some stack IO (#1302) * fix: correct some stack IO * chore: remove dead code --- crates/interpreter/src/instructions/opcode.rs | 998 ------------------ crates/interpreter/src/opcode.rs | 6 +- 2 files changed, 3 insertions(+), 1001 deletions(-) delete mode 100644 crates/interpreter/src/instructions/opcode.rs diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs deleted file mode 100644 index 58aea317..00000000 --- a/crates/interpreter/src/instructions/opcode.rs +++ /dev/null @@ -1,998 +0,0 @@ -//! EVM opcode definitions and utilities. - -use super::*; -use crate::{ - gas, - primitives::{Spec, SpecId}, - Host, Interpreter, -}; -use core::fmt; -use std::boxed::Box; - -/// EVM opcode function signature. -pub type Instruction = fn(&mut Interpreter, &mut H); - -/// Instruction table is list of instruction function pointers mapped to -/// 256 EVM opcodes. -pub type InstructionTable = [Instruction; 256]; - -/// EVM opcode function signature. -pub type BoxedInstruction<'a, H> = Box; - -/// A table of instructions. -pub type BoxedInstructionTable<'a, H> = [BoxedInstruction<'a, H>; 256]; - -/// Instruction set that contains plain instruction table that contains simple `fn` function pointer. -/// and Boxed `Fn` variant that contains `Box` function pointer that can be used with closured. -/// -/// Note that `Plain` variant gives us 10-20% faster Interpreter execution. -/// -/// Boxed variant can be used to wrap plain function pointer with closure. -pub enum InstructionTables<'a, H: ?Sized> { - Plain(InstructionTable), - Boxed(BoxedInstructionTable<'a, H>), -} - -impl InstructionTables<'_, H> { - /// Creates a plain instruction table for the given spec. - #[inline] - pub const fn new_plain() -> Self { - Self::Plain(make_instruction_table::()) - } -} - -impl<'a, H: Host + ?Sized + 'a> InstructionTables<'a, H> { - /// Inserts a boxed instruction into the table with the specified index. - /// - /// This will convert the table into the [BoxedInstructionTable] variant if it is currently a - /// plain instruction table, before inserting the instruction. - #[inline] - pub fn insert_boxed(&mut self, opcode: u8, instruction: BoxedInstruction<'a, H>) { - // first convert the table to boxed variant - self.convert_boxed(); - - // now we can insert the instruction - match self { - Self::Plain(_) => { - unreachable!("we already converted the table to boxed variant"); - } - Self::Boxed(table) => { - table[opcode as usize] = Box::new(instruction); - } - } - } - - /// Inserts the instruction into the table with the specified index. - #[inline] - pub fn insert(&mut self, opcode: u8, instruction: Instruction) { - match self { - Self::Plain(table) => { - table[opcode as usize] = instruction; - } - Self::Boxed(table) => { - table[opcode as usize] = Box::new(instruction); - } - } - } - - /// Converts the current instruction table to a boxed variant. If the table is already boxed, - /// this is a no-op. - #[inline] - pub fn convert_boxed(&mut self) { - match self { - Self::Plain(table) => { - *self = Self::Boxed(core::array::from_fn(|i| { - let instruction: BoxedInstruction<'a, H> = Box::new(table[i]); - instruction - })); - } - Self::Boxed(_) => {} - }; - } -} - -/// Make instruction table. -#[inline] -pub const fn make_instruction_table() -> InstructionTable { - // Force const-eval of the table creation, making this function trivial. - // TODO: Replace this with a `const {}` block once it is stable. - struct ConstTable { - _host: core::marker::PhantomData, - _spec: core::marker::PhantomData, - } - impl ConstTable { - const NEW: InstructionTable = { - let mut tables: InstructionTable = [control::unknown; 256]; - let mut i = 0; - while i < 256 { - tables[i] = instruction::(i as u8); - i += 1; - } - tables - }; - } - ConstTable::::NEW -} - -/// Make boxed instruction table that calls `outer` closure for every instruction. -#[inline] -pub fn make_boxed_instruction_table<'a, H, SPEC, FN>( - table: InstructionTable, - mut outer: FN, -) -> BoxedInstructionTable<'a, H> -where - H: Host + ?Sized, - SPEC: Spec + 'a, - FN: FnMut(Instruction) -> BoxedInstruction<'a, H>, -{ - core::array::from_fn(|i| outer(table[i])) -} - -macro_rules! opcodes { - ($($val:literal => $name:ident => $f:expr),* $(,)?) => { - // Constants for each opcode. This also takes care of duplicate names. - $( - #[doc = concat!("The `", stringify!($val), "` (\"", stringify!($name),"\") opcode.")] - pub const $name: u8 = $val; - )* - impl OpCode {$( - #[doc = concat!("The `", stringify!($val), "` (\"", stringify!($name),"\") opcode.")] - pub const $name: Self = Self($val); - )*} - - /// Maps each opcode to its name. - pub const OPCODE_JUMPMAP: [Option<&'static str>; 256] = { - let mut map = [None; 256]; - let mut prev: u8 = 0; - $( - let val: u8 = $val; - assert!(val == 0 || val > prev, "opcodes must be sorted in ascending order"); - prev = val; - map[$val] = Some(stringify!($name)); - )* - let _ = prev; - map - }; - - /// Returns the instruction function for the given opcode and spec. - pub const fn instruction(opcode: u8) -> Instruction { - match opcode { - $($name => $f,)* - _ => control::unknown, - } - } - }; -} - -// When adding new opcodes: -// 1. add the opcode to the list below; make sure it's sorted by opcode value -// 2. add its gas info in the `opcode_gas_info` function below -// 3. implement the opcode in the corresponding module; -// the function signature must be the exact same as the others -opcodes! { - 0x00 => STOP => control::stop, - - 0x01 => ADD => arithmetic::wrapping_add, - 0x02 => MUL => arithmetic::wrapping_mul, - 0x03 => SUB => arithmetic::wrapping_sub, - 0x04 => DIV => arithmetic::div, - 0x05 => SDIV => arithmetic::sdiv, - 0x06 => MOD => arithmetic::rem, - 0x07 => SMOD => arithmetic::smod, - 0x08 => ADDMOD => arithmetic::addmod, - 0x09 => MULMOD => arithmetic::mulmod, - 0x0A => EXP => arithmetic::exp::, - 0x0B => SIGNEXTEND => arithmetic::signextend, - // 0x0C - // 0x0D - // 0x0E - // 0x0F - 0x10 => LT => bitwise::lt, - 0x11 => GT => bitwise::gt, - 0x12 => SLT => bitwise::slt, - 0x13 => SGT => bitwise::sgt, - 0x14 => EQ => bitwise::eq, - 0x15 => ISZERO => bitwise::iszero, - 0x16 => AND => bitwise::bitand, - 0x17 => OR => bitwise::bitor, - 0x18 => XOR => bitwise::bitxor, - 0x19 => NOT => bitwise::not, - 0x1A => BYTE => bitwise::byte, - 0x1B => SHL => bitwise::shl::, - 0x1C => SHR => bitwise::shr::, - 0x1D => SAR => bitwise::sar::, - // 0x1E - // 0x1F - 0x20 => KECCAK256 => system::keccak256, - // 0x21 - // 0x22 - // 0x23 - // 0x24 - // 0x25 - // 0x26 - // 0x27 - // 0x28 - // 0x29 - // 0x2A - // 0x2B - // 0x2C - // 0x2D - // 0x2E - // 0x2F - 0x30 => ADDRESS => system::address, - 0x31 => BALANCE => host::balance::, - 0x32 => ORIGIN => host_env::origin, - 0x33 => CALLER => system::caller, - 0x34 => CALLVALUE => system::callvalue, - 0x35 => CALLDATALOAD => system::calldataload, - 0x36 => CALLDATASIZE => system::calldatasize, - 0x37 => CALLDATACOPY => system::calldatacopy, - 0x38 => CODESIZE => system::codesize, - 0x39 => CODECOPY => system::codecopy, - - 0x3A => GASPRICE => host_env::gasprice, - 0x3B => EXTCODESIZE => host::extcodesize::, - 0x3C => EXTCODECOPY => host::extcodecopy::, - 0x3D => RETURNDATASIZE => system::returndatasize::, - 0x3E => RETURNDATACOPY => system::returndatacopy::, - 0x3F => EXTCODEHASH => host::extcodehash::, - 0x40 => BLOCKHASH => host::blockhash, - 0x41 => COINBASE => host_env::coinbase, - 0x42 => TIMESTAMP => host_env::timestamp, - 0x43 => NUMBER => host_env::number, - 0x44 => DIFFICULTY => host_env::difficulty::, - 0x45 => GASLIMIT => host_env::gaslimit, - 0x46 => CHAINID => host_env::chainid::, - 0x47 => SELFBALANCE => host::selfbalance::, - 0x48 => BASEFEE => host_env::basefee::, - 0x49 => BLOBHASH => host_env::blob_hash::, - 0x4A => BLOBBASEFEE => host_env::blob_basefee::, - // 0x4B - // 0x4C - // 0x4D - // 0x4E - // 0x4F - 0x50 => POP => stack::pop, - 0x51 => MLOAD => memory::mload, - 0x52 => MSTORE => memory::mstore, - 0x53 => MSTORE8 => memory::mstore8, - 0x54 => SLOAD => host::sload::, - 0x55 => SSTORE => host::sstore::, - 0x56 => JUMP => control::jump, - 0x57 => JUMPI => control::jumpi, - 0x58 => PC => control::pc, - 0x59 => MSIZE => memory::msize, - 0x5A => GAS => system::gas, - 0x5B => JUMPDEST => control::jumpdest, - 0x5C => TLOAD => host::tload::, - 0x5D => TSTORE => host::tstore::, - 0x5E => MCOPY => memory::mcopy::, - - 0x5F => PUSH0 => stack::push0::, - 0x60 => PUSH1 => stack::push::<1, H>, - 0x61 => PUSH2 => stack::push::<2, H>, - 0x62 => PUSH3 => stack::push::<3, H>, - 0x63 => PUSH4 => stack::push::<4, H>, - 0x64 => PUSH5 => stack::push::<5, H>, - 0x65 => PUSH6 => stack::push::<6, H>, - 0x66 => PUSH7 => stack::push::<7, H>, - 0x67 => PUSH8 => stack::push::<8, H>, - 0x68 => PUSH9 => stack::push::<9, H>, - 0x69 => PUSH10 => stack::push::<10, H>, - 0x6A => PUSH11 => stack::push::<11, H>, - 0x6B => PUSH12 => stack::push::<12, H>, - 0x6C => PUSH13 => stack::push::<13, H>, - 0x6D => PUSH14 => stack::push::<14, H>, - 0x6E => PUSH15 => stack::push::<15, H>, - 0x6F => PUSH16 => stack::push::<16, H>, - 0x70 => PUSH17 => stack::push::<17, H>, - 0x71 => PUSH18 => stack::push::<18, H>, - 0x72 => PUSH19 => stack::push::<19, H>, - 0x73 => PUSH20 => stack::push::<20, H>, - 0x74 => PUSH21 => stack::push::<21, H>, - 0x75 => PUSH22 => stack::push::<22, H>, - 0x76 => PUSH23 => stack::push::<23, H>, - 0x77 => PUSH24 => stack::push::<24, H>, - 0x78 => PUSH25 => stack::push::<25, H>, - 0x79 => PUSH26 => stack::push::<26, H>, - 0x7A => PUSH27 => stack::push::<27, H>, - 0x7B => PUSH28 => stack::push::<28, H>, - 0x7C => PUSH29 => stack::push::<29, H>, - 0x7D => PUSH30 => stack::push::<30, H>, - 0x7E => PUSH31 => stack::push::<31, H>, - 0x7F => PUSH32 => stack::push::<32, H>, - - 0x80 => DUP1 => stack::dup::<1, H>, - 0x81 => DUP2 => stack::dup::<2, H>, - 0x82 => DUP3 => stack::dup::<3, H>, - 0x83 => DUP4 => stack::dup::<4, H>, - 0x84 => DUP5 => stack::dup::<5, H>, - 0x85 => DUP6 => stack::dup::<6, H>, - 0x86 => DUP7 => stack::dup::<7, H>, - 0x87 => DUP8 => stack::dup::<8, H>, - 0x88 => DUP9 => stack::dup::<9, H>, - 0x89 => DUP10 => stack::dup::<10, H>, - 0x8A => DUP11 => stack::dup::<11, H>, - 0x8B => DUP12 => stack::dup::<12, H>, - 0x8C => DUP13 => stack::dup::<13, H>, - 0x8D => DUP14 => stack::dup::<14, H>, - 0x8E => DUP15 => stack::dup::<15, H>, - 0x8F => DUP16 => stack::dup::<16, H>, - - 0x90 => SWAP1 => stack::swap::<1, H>, - 0x91 => SWAP2 => stack::swap::<2, H>, - 0x92 => SWAP3 => stack::swap::<3, H>, - 0x93 => SWAP4 => stack::swap::<4, H>, - 0x94 => SWAP5 => stack::swap::<5, H>, - 0x95 => SWAP6 => stack::swap::<6, H>, - 0x96 => SWAP7 => stack::swap::<7, H>, - 0x97 => SWAP8 => stack::swap::<8, H>, - 0x98 => SWAP9 => stack::swap::<9, H>, - 0x99 => SWAP10 => stack::swap::<10, H>, - 0x9A => SWAP11 => stack::swap::<11, H>, - 0x9B => SWAP12 => stack::swap::<12, H>, - 0x9C => SWAP13 => stack::swap::<13, H>, - 0x9D => SWAP14 => stack::swap::<14, H>, - 0x9E => SWAP15 => stack::swap::<15, H>, - 0x9F => SWAP16 => stack::swap::<16, H>, - - 0xA0 => LOG0 => host::log::<0, H>, - 0xA1 => LOG1 => host::log::<1, H>, - 0xA2 => LOG2 => host::log::<2, H>, - 0xA3 => LOG3 => host::log::<3, H>, - 0xA4 => LOG4 => host::log::<4, H>, - // 0xA5 - // 0xA6 - // 0xA7 - // 0xA8 - // 0xA9 - // 0xAA - // 0xAB - // 0xAC - // 0xAD - // 0xAE - // 0xAF - // 0xB0 - // 0xB1 - // 0xB2 - // 0xB3 - // 0xB4 - // 0xB5 - // 0xB6 - // 0xB7 - // 0xB8 - // 0xB9 - // 0xBA - // 0xBB - // 0xBC - // 0xBD - // 0xBE - // 0xBF - // 0xC0 - // 0xC1 - // 0xC2 - // 0xC3 - // 0xC4 - // 0xC5 - // 0xC6 - // 0xC7 - // 0xC8 - // 0xC9 - // 0xCA - // 0xCB - // 0xCC - // 0xCD - // 0xCE - // 0xCF - // 0xD0 - // 0xD1 - // 0xD2 - // 0xD3 - // 0xD4 - // 0xD5 - // 0xD6 - // 0xD7 - // 0xD8 - // 0xD9 - // 0xDA - // 0xDB - // 0xDC - // 0xDD - // 0xDE - // 0xDF - // 0xE0 - // 0xE1 - // 0xE2 - // 0xE3 - // 0xE4 - // 0xE5 - // 0xE6 - // 0xE7 - // 0xE8 - // 0xE9 - // 0xEA - // 0xEB - // 0xEC - // 0xED - // 0xEE - // 0xEF - 0xF0 => CREATE => host::create::, - 0xF1 => CALL => host::call::, - 0xF2 => CALLCODE => host::call_code::, - 0xF3 => RETURN => control::ret, - 0xF4 => DELEGATECALL => host::delegate_call::, - 0xF5 => CREATE2 => host::create::, - // 0xF6 - // 0xF7 - // 0xF8 - // 0xF9 - 0xFA => STATICCALL => host::static_call::, - // 0xFB - // 0xFC - 0xFD => REVERT => control::revert::, - 0xFE => INVALID => control::invalid, - 0xFF => SELFDESTRUCT => host::selfdestruct::, -} - -/// An EVM opcode. -/// -/// This is always a valid opcode, as declared in the [`opcode`][self] module or the -/// [`OPCODE_JUMPMAP`] constant. -#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[repr(transparent)] -pub struct OpCode(u8); - -impl fmt::Debug for OpCode { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "OpCode::{self}") - } -} - -impl fmt::Display for OpCode { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let n = self.get(); - if let Some(val) = OPCODE_JUMPMAP[n as usize] { - f.write_str(val) - } else { - write!(f, "UNKNOWN(0x{n:02X})") - } - } -} - -impl OpCode { - /// Instantiate a new opcode from a u8. - #[inline] - pub const fn new(opcode: u8) -> Option { - match OPCODE_JUMPMAP[opcode as usize] { - Some(_) => Some(Self(opcode)), - None => None, - } - } - - /// Instantiate a new opcode from a u8 without checking if it is valid. - /// - /// # Safety - /// - /// All code using `Opcode` values assume that they are valid opcodes, so providing an invalid - /// opcode may cause undefined behavior. - #[inline] - pub unsafe fn new_unchecked(opcode: u8) -> Self { - Self(opcode) - } - - /// Returns the opcode as a string. - #[inline] - pub const fn as_str(self) -> &'static str { - if let Some(str) = OPCODE_JUMPMAP[self.0 as usize] { - str - } else { - "unknown" - } - } - - /// Returns the opcode as a u8. - #[inline] - pub const fn get(self) -> u8 { - self.0 - } - - /// Returns true if the opcode modifies memory. - /// - /// - #[inline] - pub const fn modifies_memory(&self) -> bool { - matches!( - *self, - OpCode::EXTCODECOPY - | OpCode::MLOAD - | OpCode::MSTORE - | OpCode::MSTORE8 - | OpCode::MCOPY - | OpCode::CODECOPY - | OpCode::CALLDATACOPY - | OpCode::RETURNDATACOPY - | OpCode::CALL - | OpCode::CALLCODE - | OpCode::DELEGATECALL - | OpCode::STATICCALL - ) - } -} - -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct OpInfo { - /// Data contains few information packed inside u32: - /// IS_JUMP (1bit) | IS_GAS_BLOCK_END (1bit) | IS_PUSH (1bit) | gas (29bits) - data: u32, -} - -const JUMP_MASK: u32 = 0x80000000; -const GAS_BLOCK_END_MASK: u32 = 0x40000000; -const IS_PUSH_MASK: u32 = 0x20000000; -const GAS_MASK: u32 = 0x1FFFFFFF; - -impl OpInfo { - /// Creates a new empty [`OpInfo`]. - pub const fn none() -> Self { - Self { data: 0 } - } - - /// Creates a new dynamic gas [`OpInfo`]. - pub const fn dynamic_gas() -> Self { - Self { data: 0 } - } - - /// Creates a new gas block end [`OpInfo`]. - pub const fn gas_block_end(gas: u64) -> Self { - Self { - data: gas as u32 | GAS_BLOCK_END_MASK, - } - } - - /// Creates a new [`OpInfo`] with the given gas value. - pub const fn gas(gas: u64) -> Self { - Self { data: gas as u32 } - } - - /// Creates a new push [`OpInfo`]. - pub const fn push_opcode() -> Self { - Self { - data: gas::VERYLOW as u32 | IS_PUSH_MASK, - } - } - - /// Creates a new jumpdest [`OpInfo`]. - pub const fn jumpdest() -> Self { - Self { - data: JUMP_MASK | GAS_BLOCK_END_MASK, - } - } - - /// Returns whether the opcode is a jump. - #[inline] - pub fn is_jump(self) -> bool { - self.data & JUMP_MASK == JUMP_MASK - } - - /// Returns whether the opcode is a gas block end. - #[inline] - pub fn is_gas_block_end(self) -> bool { - self.data & GAS_BLOCK_END_MASK == GAS_BLOCK_END_MASK - } - - /// Returns whether the opcode is a push. - #[inline] - pub fn is_push(self) -> bool { - self.data & IS_PUSH_MASK == IS_PUSH_MASK - } - - /// Returns the gas cost of the opcode. - #[inline] - pub fn get_gas(self) -> u32 { - self.data & GAS_MASK - } -} - -const fn opcode_gas_info(opcode: u8, spec: SpecId) -> OpInfo { - match opcode { - STOP => OpInfo::gas_block_end(0), - ADD => OpInfo::gas(gas::VERYLOW), - MUL => OpInfo::gas(gas::LOW), - SUB => OpInfo::gas(gas::VERYLOW), - DIV => OpInfo::gas(gas::LOW), - SDIV => OpInfo::gas(gas::LOW), - MOD => OpInfo::gas(gas::LOW), - SMOD => OpInfo::gas(gas::LOW), - ADDMOD => OpInfo::gas(gas::MID), - MULMOD => OpInfo::gas(gas::MID), - EXP => OpInfo::dynamic_gas(), - SIGNEXTEND => OpInfo::gas(gas::LOW), - 0x0C => OpInfo::none(), - 0x0D => OpInfo::none(), - 0x0E => OpInfo::none(), - 0x0F => OpInfo::none(), - LT => OpInfo::gas(gas::VERYLOW), - GT => OpInfo::gas(gas::VERYLOW), - SLT => OpInfo::gas(gas::VERYLOW), - SGT => OpInfo::gas(gas::VERYLOW), - EQ => OpInfo::gas(gas::VERYLOW), - ISZERO => OpInfo::gas(gas::VERYLOW), - AND => OpInfo::gas(gas::VERYLOW), - OR => OpInfo::gas(gas::VERYLOW), - XOR => OpInfo::gas(gas::VERYLOW), - NOT => OpInfo::gas(gas::VERYLOW), - BYTE => OpInfo::gas(gas::VERYLOW), - SHL => OpInfo::gas(if SpecId::enabled(spec, SpecId::CONSTANTINOPLE) { - gas::VERYLOW - } else { - 0 - }), - SHR => OpInfo::gas(if SpecId::enabled(spec, SpecId::CONSTANTINOPLE) { - gas::VERYLOW - } else { - 0 - }), - SAR => OpInfo::gas(if SpecId::enabled(spec, SpecId::CONSTANTINOPLE) { - gas::VERYLOW - } else { - 0 - }), - 0x1E => OpInfo::none(), - 0x1F => OpInfo::none(), - KECCAK256 => OpInfo::dynamic_gas(), - 0x21 => OpInfo::none(), - 0x22 => OpInfo::none(), - 0x23 => OpInfo::none(), - 0x24 => OpInfo::none(), - 0x25 => OpInfo::none(), - 0x26 => OpInfo::none(), - 0x27 => OpInfo::none(), - 0x28 => OpInfo::none(), - 0x29 => OpInfo::none(), - 0x2A => OpInfo::none(), - 0x2B => OpInfo::none(), - 0x2C => OpInfo::none(), - 0x2D => OpInfo::none(), - 0x2E => OpInfo::none(), - 0x2F => OpInfo::none(), - ADDRESS => OpInfo::gas(gas::BASE), - BALANCE => OpInfo::dynamic_gas(), - ORIGIN => OpInfo::gas(gas::BASE), - CALLER => OpInfo::gas(gas::BASE), - CALLVALUE => OpInfo::gas(gas::BASE), - CALLDATALOAD => OpInfo::gas(gas::VERYLOW), - CALLDATASIZE => OpInfo::gas(gas::BASE), - CALLDATACOPY => OpInfo::dynamic_gas(), - CODESIZE => OpInfo::gas(gas::BASE), - CODECOPY => OpInfo::dynamic_gas(), - GASPRICE => OpInfo::gas(gas::BASE), - EXTCODESIZE => OpInfo::gas(if SpecId::enabled(spec, SpecId::BERLIN) { - gas::WARM_STORAGE_READ_COST // add only part of gas - } else if SpecId::enabled(spec, SpecId::TANGERINE) { - 700 - } else { - 20 - }), - EXTCODECOPY => OpInfo::gas(if SpecId::enabled(spec, SpecId::BERLIN) { - gas::WARM_STORAGE_READ_COST // add only part of gas - } else if SpecId::enabled(spec, SpecId::TANGERINE) { - 700 - } else { - 20 - }), - RETURNDATASIZE => OpInfo::gas(if SpecId::enabled(spec, SpecId::BYZANTIUM) { - gas::BASE - } else { - 0 - }), - RETURNDATACOPY => OpInfo::dynamic_gas(), - EXTCODEHASH => OpInfo::gas(if SpecId::enabled(spec, SpecId::BERLIN) { - gas::WARM_STORAGE_READ_COST // add only part of gas - } else if SpecId::enabled(spec, SpecId::ISTANBUL) { - 700 - } else if SpecId::enabled(spec, SpecId::PETERSBURG) { - 400 // constantinople - } else { - 0 // not enabled - }), - BLOCKHASH => OpInfo::gas(gas::BLOCKHASH), - COINBASE => OpInfo::gas(gas::BASE), - TIMESTAMP => OpInfo::gas(gas::BASE), - NUMBER => OpInfo::gas(gas::BASE), - DIFFICULTY => OpInfo::gas(gas::BASE), - GASLIMIT => OpInfo::gas(gas::BASE), - CHAINID => OpInfo::gas(if SpecId::enabled(spec, SpecId::ISTANBUL) { - gas::BASE - } else { - 0 - }), - SELFBALANCE => OpInfo::gas(if SpecId::enabled(spec, SpecId::ISTANBUL) { - gas::LOW - } else { - 0 - }), - BASEFEE => OpInfo::gas(if SpecId::enabled(spec, SpecId::LONDON) { - gas::BASE - } else { - 0 - }), - BLOBHASH => OpInfo::gas(if SpecId::enabled(spec, SpecId::CANCUN) { - gas::VERYLOW - } else { - 0 - }), - BLOBBASEFEE => OpInfo::gas(if SpecId::enabled(spec, SpecId::CANCUN) { - gas::BASE - } else { - 0 - }), - 0x4B => OpInfo::none(), - 0x4C => OpInfo::none(), - 0x4D => OpInfo::none(), - 0x4E => OpInfo::none(), - 0x4F => OpInfo::none(), - POP => OpInfo::gas(gas::BASE), - MLOAD => OpInfo::gas(gas::VERYLOW), - MSTORE => OpInfo::gas(gas::VERYLOW), - MSTORE8 => OpInfo::gas(gas::VERYLOW), - SLOAD => OpInfo::dynamic_gas(), - SSTORE => OpInfo::gas_block_end(0), - JUMP => OpInfo::gas_block_end(gas::MID), - JUMPI => OpInfo::gas_block_end(gas::HIGH), - PC => OpInfo::gas(gas::BASE), - MSIZE => OpInfo::gas(gas::BASE), - GAS => OpInfo::gas_block_end(gas::BASE), - // gas::JUMPDEST gas is calculated in function call - JUMPDEST => OpInfo::jumpdest(), - TLOAD => OpInfo::gas(if SpecId::enabled(spec, SpecId::CANCUN) { - gas::WARM_STORAGE_READ_COST - } else { - 0 - }), - TSTORE => OpInfo::gas(if SpecId::enabled(spec, SpecId::CANCUN) { - gas::WARM_STORAGE_READ_COST - } else { - 0 - }), - MCOPY => OpInfo::dynamic_gas(), - - PUSH0 => OpInfo::gas(if SpecId::enabled(spec, SpecId::SHANGHAI) { - gas::BASE - } else { - 0 - }), - PUSH1 => OpInfo::push_opcode(), - PUSH2 => OpInfo::push_opcode(), - PUSH3 => OpInfo::push_opcode(), - PUSH4 => OpInfo::push_opcode(), - PUSH5 => OpInfo::push_opcode(), - PUSH6 => OpInfo::push_opcode(), - PUSH7 => OpInfo::push_opcode(), - PUSH8 => OpInfo::push_opcode(), - PUSH9 => OpInfo::push_opcode(), - PUSH10 => OpInfo::push_opcode(), - PUSH11 => OpInfo::push_opcode(), - PUSH12 => OpInfo::push_opcode(), - PUSH13 => OpInfo::push_opcode(), - PUSH14 => OpInfo::push_opcode(), - PUSH15 => OpInfo::push_opcode(), - PUSH16 => OpInfo::push_opcode(), - PUSH17 => OpInfo::push_opcode(), - PUSH18 => OpInfo::push_opcode(), - PUSH19 => OpInfo::push_opcode(), - PUSH20 => OpInfo::push_opcode(), - PUSH21 => OpInfo::push_opcode(), - PUSH22 => OpInfo::push_opcode(), - PUSH23 => OpInfo::push_opcode(), - PUSH24 => OpInfo::push_opcode(), - PUSH25 => OpInfo::push_opcode(), - PUSH26 => OpInfo::push_opcode(), - PUSH27 => OpInfo::push_opcode(), - PUSH28 => OpInfo::push_opcode(), - PUSH29 => OpInfo::push_opcode(), - PUSH30 => OpInfo::push_opcode(), - PUSH31 => OpInfo::push_opcode(), - PUSH32 => OpInfo::push_opcode(), - - DUP1 => OpInfo::gas(gas::VERYLOW), - DUP2 => OpInfo::gas(gas::VERYLOW), - DUP3 => OpInfo::gas(gas::VERYLOW), - DUP4 => OpInfo::gas(gas::VERYLOW), - DUP5 => OpInfo::gas(gas::VERYLOW), - DUP6 => OpInfo::gas(gas::VERYLOW), - DUP7 => OpInfo::gas(gas::VERYLOW), - DUP8 => OpInfo::gas(gas::VERYLOW), - DUP9 => OpInfo::gas(gas::VERYLOW), - DUP10 => OpInfo::gas(gas::VERYLOW), - DUP11 => OpInfo::gas(gas::VERYLOW), - DUP12 => OpInfo::gas(gas::VERYLOW), - DUP13 => OpInfo::gas(gas::VERYLOW), - DUP14 => OpInfo::gas(gas::VERYLOW), - DUP15 => OpInfo::gas(gas::VERYLOW), - DUP16 => OpInfo::gas(gas::VERYLOW), - - SWAP1 => OpInfo::gas(gas::VERYLOW), - SWAP2 => OpInfo::gas(gas::VERYLOW), - SWAP3 => OpInfo::gas(gas::VERYLOW), - SWAP4 => OpInfo::gas(gas::VERYLOW), - SWAP5 => OpInfo::gas(gas::VERYLOW), - SWAP6 => OpInfo::gas(gas::VERYLOW), - SWAP7 => OpInfo::gas(gas::VERYLOW), - SWAP8 => OpInfo::gas(gas::VERYLOW), - SWAP9 => OpInfo::gas(gas::VERYLOW), - SWAP10 => OpInfo::gas(gas::VERYLOW), - SWAP11 => OpInfo::gas(gas::VERYLOW), - SWAP12 => OpInfo::gas(gas::VERYLOW), - SWAP13 => OpInfo::gas(gas::VERYLOW), - SWAP14 => OpInfo::gas(gas::VERYLOW), - SWAP15 => OpInfo::gas(gas::VERYLOW), - SWAP16 => OpInfo::gas(gas::VERYLOW), - - LOG0 => OpInfo::dynamic_gas(), - LOG1 => OpInfo::dynamic_gas(), - LOG2 => OpInfo::dynamic_gas(), - LOG3 => OpInfo::dynamic_gas(), - LOG4 => OpInfo::dynamic_gas(), - 0xA5 => OpInfo::none(), - 0xA6 => OpInfo::none(), - 0xA7 => OpInfo::none(), - 0xA8 => OpInfo::none(), - 0xA9 => OpInfo::none(), - 0xAA => OpInfo::none(), - 0xAB => OpInfo::none(), - 0xAC => OpInfo::none(), - 0xAD => OpInfo::none(), - 0xAE => OpInfo::none(), - 0xAF => OpInfo::none(), - 0xB0 => OpInfo::none(), - 0xB1 => OpInfo::none(), - 0xB2 => OpInfo::none(), - 0xB3 => OpInfo::none(), - 0xB4 => OpInfo::none(), - 0xB5 => OpInfo::none(), - 0xB6 => OpInfo::none(), - 0xB7 => OpInfo::none(), - 0xB8 => OpInfo::none(), - 0xB9 => OpInfo::none(), - 0xBA => OpInfo::none(), - 0xBB => OpInfo::none(), - 0xBC => OpInfo::none(), - 0xBD => OpInfo::none(), - 0xBE => OpInfo::none(), - 0xBF => OpInfo::none(), - 0xC0 => OpInfo::none(), - 0xC1 => OpInfo::none(), - 0xC2 => OpInfo::none(), - 0xC3 => OpInfo::none(), - 0xC4 => OpInfo::none(), - 0xC5 => OpInfo::none(), - 0xC6 => OpInfo::none(), - 0xC7 => OpInfo::none(), - 0xC8 => OpInfo::none(), - 0xC9 => OpInfo::none(), - 0xCA => OpInfo::none(), - 0xCB => OpInfo::none(), - 0xCC => OpInfo::none(), - 0xCD => OpInfo::none(), - 0xCE => OpInfo::none(), - 0xCF => OpInfo::none(), - 0xD0 => OpInfo::none(), - 0xD1 => OpInfo::none(), - 0xD2 => OpInfo::none(), - 0xD3 => OpInfo::none(), - 0xD4 => OpInfo::none(), - 0xD5 => OpInfo::none(), - 0xD6 => OpInfo::none(), - 0xD7 => OpInfo::none(), - 0xD8 => OpInfo::none(), - 0xD9 => OpInfo::none(), - 0xDA => OpInfo::none(), - 0xDB => OpInfo::none(), - 0xDC => OpInfo::none(), - 0xDD => OpInfo::none(), - 0xDE => OpInfo::none(), - 0xDF => OpInfo::none(), - 0xE0 => OpInfo::none(), - 0xE1 => OpInfo::none(), - 0xE2 => OpInfo::none(), - 0xE3 => OpInfo::none(), - 0xE4 => OpInfo::none(), - 0xE5 => OpInfo::none(), - 0xE6 => OpInfo::none(), - 0xE7 => OpInfo::none(), - 0xE8 => OpInfo::none(), - 0xE9 => OpInfo::none(), - 0xEA => OpInfo::none(), - 0xEB => OpInfo::none(), - 0xEC => OpInfo::none(), - 0xED => OpInfo::none(), - 0xEE => OpInfo::none(), - 0xEF => OpInfo::none(), - CREATE => OpInfo::gas_block_end(0), - CALL => OpInfo::gas_block_end(0), - CALLCODE => OpInfo::gas_block_end(0), - RETURN => OpInfo::gas_block_end(0), - DELEGATECALL => OpInfo::gas_block_end(0), - CREATE2 => OpInfo::gas_block_end(0), - 0xF6 => OpInfo::none(), - 0xF7 => OpInfo::none(), - 0xF8 => OpInfo::none(), - 0xF9 => OpInfo::none(), - STATICCALL => OpInfo::gas_block_end(0), - 0xFB => OpInfo::none(), - 0xFC => OpInfo::none(), - REVERT => OpInfo::gas_block_end(0), - INVALID => OpInfo::gas_block_end(0), - SELFDESTRUCT => OpInfo::gas_block_end(0), - } -} - -const fn make_gas_table(spec: SpecId) -> [OpInfo; 256] { - let mut table = [OpInfo::none(); 256]; - let mut i = 0; - while i < 256 { - table[i] = opcode_gas_info(i as u8, spec); - i += 1; - } - table -} - -/// Returns a lookup table of opcode gas info for the given [`SpecId`]. -#[inline] -pub const fn spec_opcode_gas(spec_id: SpecId) -> &'static [OpInfo; 256] { - macro_rules! gas_maps { - ($($id:ident),* $(,)?) => { - match spec_id { - $( - SpecId::$id => { - const TABLE: &[OpInfo; 256] = &make_gas_table(SpecId::$id); - TABLE - } - )* - #[cfg(feature = "optimism")] - SpecId::BEDROCK => { - const TABLE: &[OpInfo;256] = &make_gas_table(SpecId::BEDROCK); - TABLE - } - #[cfg(feature = "optimism")] - SpecId::REGOLITH => { - const TABLE: &[OpInfo;256] = &make_gas_table(SpecId::REGOLITH); - TABLE - } - #[cfg(feature = "optimism")] - SpecId::CANYON => { - const TABLE: &[OpInfo;256] = &make_gas_table(SpecId::CANYON); - TABLE - } - #[cfg(feature = "optimism")] - SpecId::ECOTONE => { - const TABLE: &[OpInfo;256] = &make_gas_table(SpecId::ECOTONE); - TABLE - } - } - }; - } - - gas_maps!( - FRONTIER, - FRONTIER_THAWING, - HOMESTEAD, - DAO_FORK, - TANGERINE, - SPURIOUS_DRAGON, - BYZANTIUM, - CONSTANTINOPLE, - PETERSBURG, - ISTANBUL, - MUIR_GLACIER, - BERLIN, - LONDON, - ARROW_GLACIER, - GRAY_GLACIER, - MERGE, - SHANGHAI, - CANCUN, - LATEST, - ) -} diff --git a/crates/interpreter/src/opcode.rs b/crates/interpreter/src/opcode.rs index 401c7c37..7e5ade81 100644 --- a/crates/interpreter/src/opcode.rs +++ b/crates/interpreter/src/opcode.rs @@ -433,7 +433,7 @@ opcodes! { 0x34 => CALLVALUE => system::callvalue => stack_io<0, 1>; 0x35 => CALLDATALOAD => system::calldataload => stack_io<1, 1>; 0x36 => CALLDATASIZE => system::calldatasize => stack_io<0, 1>; - 0x37 => CALLDATACOPY => system::calldatacopy => stack_io<3, 1>; + 0x37 => CALLDATACOPY => system::calldatacopy => stack_io<3, 0>; 0x38 => CODESIZE => system::codesize => stack_io<0, 1>, not_eof; 0x39 => CODECOPY => system::codecopy => stack_io<3, 0>, not_eof; @@ -623,12 +623,12 @@ opcodes! { 0xED => TXCREATE => contract::txcreate:: => stack_io<5, 1>; 0xEE => RETURNCONTRACT => contract::return_contract:: => stack_io<2, 0>, imm_size<1>, terminating; // 0xEF - 0xF0 => CREATE => contract::create:: => stack_io<4, 1>, not_eof; + 0xF0 => CREATE => contract::create:: => stack_io<3, 1>, not_eof; 0xF1 => CALL => contract::call:: => stack_io<7, 1>, not_eof; 0xF2 => CALLCODE => contract::call_code:: => stack_io<7, 1>, not_eof; 0xF3 => RETURN => control::ret => stack_io<2, 0>, terminating; 0xF4 => DELEGATECALL => contract::delegate_call:: => stack_io<6, 1>, not_eof; - 0xF5 => CREATE2 => contract::create:: => stack_io<5, 1>, not_eof; + 0xF5 => CREATE2 => contract::create:: => stack_io<4, 1>, not_eof; // 0xF6 0xF7 => RETURNDATALOAD => system::returndataload:: => stack_io<1, 1>; 0xF8 => EXTCALL => contract::extcall:: => stack_io<4, 1>; From 72356e3b21737517ad52b0a5e7fbc0adc57dd47d Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Tue, 16 Apr 2024 21:22:16 +0200 Subject: [PATCH 023/105] chore(interpreter): rename wrapping_* opcodes (#1306) --- crates/interpreter/src/instructions/arithmetic.rs | 6 +++--- crates/interpreter/src/opcode.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/interpreter/src/instructions/arithmetic.rs b/crates/interpreter/src/instructions/arithmetic.rs index 8d1e5127..34c98a34 100644 --- a/crates/interpreter/src/instructions/arithmetic.rs +++ b/crates/interpreter/src/instructions/arithmetic.rs @@ -5,19 +5,19 @@ use crate::{ Host, Interpreter, }; -pub fn wrapping_add(interpreter: &mut Interpreter, _host: &mut H) { +pub fn add(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = op1.wrapping_add(*op2); } -pub fn wrapping_mul(interpreter: &mut Interpreter, _host: &mut H) { +pub fn mul(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); *op2 = op1.wrapping_mul(*op2); } -pub fn wrapping_sub(interpreter: &mut Interpreter, _host: &mut H) { +pub fn sub(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); *op2 = op1.wrapping_sub(*op2); diff --git a/crates/interpreter/src/opcode.rs b/crates/interpreter/src/opcode.rs index 7e5ade81..883ceed7 100644 --- a/crates/interpreter/src/opcode.rs +++ b/crates/interpreter/src/opcode.rs @@ -379,9 +379,9 @@ pub const fn stack_io(mut opcode: OpCodeInfo) -> OpCod opcodes! { 0x00 => STOP => control::stop => stack_io<0,0>, terminating; - 0x01 => ADD => arithmetic::wrapping_add => stack_io<2, 1>; - 0x02 => MUL => arithmetic::wrapping_mul => stack_io<2, 1>; - 0x03 => SUB => arithmetic::wrapping_sub => stack_io<2, 1>; + 0x01 => ADD => arithmetic::add => stack_io<2, 1>; + 0x02 => MUL => arithmetic::mul => stack_io<2, 1>; + 0x03 => SUB => arithmetic::sub => stack_io<2, 1>; 0x04 => DIV => arithmetic::div => stack_io<2, 1>; 0x05 => SDIV => arithmetic::sdiv => stack_io<2, 1>; 0x06 => MOD => arithmetic::rem => stack_io<2, 1>; From cc1b9f74ce6f8f3b8d299c7bbcaac4c6d67681dc Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Tue, 16 Apr 2024 21:22:39 +0200 Subject: [PATCH 024/105] chore: fix some warnings (#1305) --- crates/interpreter/src/function_stack.rs | 1 + crates/interpreter/src/instructions/stack.rs | 2 +- crates/interpreter/src/instructions/system.rs | 4 ++-- crates/revm/src/context/evm_context.rs | 14 ++++---------- crates/revm/src/db/states/bundle_state.rs | 1 - 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/crates/interpreter/src/function_stack.rs b/crates/interpreter/src/function_stack.rs index 3f0f5d64..e6482d8e 100644 --- a/crates/interpreter/src/function_stack.rs +++ b/crates/interpreter/src/function_stack.rs @@ -1,4 +1,5 @@ use std::vec::Vec; + /// Function return frame. /// Needed information for returning from a function. #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] diff --git a/crates/interpreter/src/instructions/stack.rs b/crates/interpreter/src/instructions/stack.rs index fa6c1be9..dfd2a58b 100644 --- a/crates/interpreter/src/instructions/stack.rs +++ b/crates/interpreter/src/instructions/stack.rs @@ -90,7 +90,7 @@ mod test { use crate::{ opcode::{make_instruction_table, DUPN, EXCHANGE, SWAPN}, primitives::{Bytecode, Bytes, PragueSpec}, - DummyHost, Gas, InstructionResult, Interpreter, + DummyHost, Gas, InstructionResult, }; #[test] diff --git a/crates/interpreter/src/instructions/system.rs b/crates/interpreter/src/instructions/system.rs index a5cec536..477d4079 100644 --- a/crates/interpreter/src/instructions/system.rs +++ b/crates/interpreter/src/instructions/system.rs @@ -164,8 +164,8 @@ mod test { use super::*; use crate::{ opcode::{make_instruction_table, RETURNDATALOAD}, - primitives::{bytes, Bytecode, PragueSpec, U256}, - DummyHost, Gas, Interpreter, + primitives::{bytes, Bytecode, PragueSpec}, + DummyHost, Gas, }; #[test] diff --git a/crates/revm/src/context/evm_context.rs b/crates/revm/src/context/evm_context.rs index 84b1c4ff..a313226b 100644 --- a/crates/revm/src/context/evm_context.rs +++ b/crates/revm/src/context/evm_context.rs @@ -223,16 +223,12 @@ impl EvmContext { /// Test utilities for the [`EvmContext`]. #[cfg(any(test, feature = "test-utils"))] pub(crate) mod test_utils { - use revm_interpreter::TransferValue; - use super::*; use crate::{ db::{CacheDB, EmptyDB}, journaled_state::JournaledState, - primitives::{address, Address, Bytes, Env, HashSet, SpecId, B256, U256}, - InnerEvmContext, + primitives::{address, SpecId, B256}, }; - use std::boxed::Box; /// Mock caller address. pub const MOCK_CALLER: Address = address!("0000000000000000000000000000000000000000"); @@ -310,15 +306,13 @@ pub(crate) mod test_utils { #[cfg(test)] mod tests { use super::*; - use test_utils::*; - use crate::{ db::{CacheDB, EmptyDB}, - interpreter::InstructionResult, - primitives::{address, Bytecode, Bytes, Env, U256}, - Frame, FrameOrResult, JournalEntry, + primitives::{address, Bytecode}, + Frame, JournalEntry, }; use std::boxed::Box; + use test_utils::*; // Tests that the `EVMContext::make_call_frame` function returns an error if the // call stack is too deep. diff --git a/crates/revm/src/db/states/bundle_state.rs b/crates/revm/src/db/states/bundle_state.rs index 0b5a6da5..5f189041 100644 --- a/crates/revm/src/db/states/bundle_state.rs +++ b/crates/revm/src/db/states/bundle_state.rs @@ -697,7 +697,6 @@ impl BundleState { mod tests { use super::*; use crate::{db::StorageWithOriginalValues, TransitionAccount}; - use revm_interpreter::primitives::KECCAK_EMPTY; #[test] fn transition_states() { From 9cfd14442734d879795a9d4f9fe505418b9bfa58 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Tue, 16 Apr 2024 21:27:22 +0200 Subject: [PATCH 025/105] perf(interpreter): remove EOF branch in CODE{SIZE,COPY} (#1308) --- crates/interpreter/src/instructions/system.rs | 4 ++++ crates/primitives/src/bytecode.rs | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/interpreter/src/instructions/system.rs b/crates/interpreter/src/instructions/system.rs index 477d4079..b7fbe01b 100644 --- a/crates/interpreter/src/instructions/system.rs +++ b/crates/interpreter/src/instructions/system.rs @@ -31,6 +31,8 @@ pub fn caller(interpreter: &mut Interpreter, _host: &mut H) { pub fn codesize(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::BASE); + // Inform the optimizer that the bytecode cannot be EOF to remove a bounds check. + assume!(!interpreter.contract.bytecode.is_eof()); push!(interpreter, U256::from(interpreter.contract.bytecode.len())); } @@ -45,6 +47,8 @@ pub fn codecopy(interpreter: &mut Interpreter, _host: &mut H) let code_offset = as_usize_saturated!(code_offset); resize_memory!(interpreter, memory_offset, len); + // Inform the optimizer that the bytecode cannot be EOF to remove a bounds check. + assume!(!interpreter.contract.bytecode.is_eof()); // Note: this can't panic because we resized memory to fit. interpreter.shared_memory.set_data( memory_offset, diff --git a/crates/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index e36afa48..6236c3ea 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -52,7 +52,8 @@ impl Bytecode { } /// Return reference to the EOF if bytecode is EOF. - pub fn eof(&self) -> Option<&Eof> { + #[inline] + pub const fn eof(&self) -> Option<&Eof> { match self { Self::Eof(eof) => Some(eof), _ => None, @@ -60,7 +61,8 @@ impl Bytecode { } /// Return true if bytecode is EOF. - pub fn is_eof(&self) -> bool { + #[inline] + pub const fn is_eof(&self) -> bool { matches!(self, Self::Eof(_)) } From aec666a3efbc1cb161fef9b4525f238c01bdbe69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 22:01:47 +0200 Subject: [PATCH 026/105] chore(deps): bump anyhow from 1.0.81 to 1.0.82 (#1293) Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.81 to 1.0.82. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.81...1.0.82) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- crates/revm/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 10b8c1f8..d7dcdf72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -355,9 +355,9 @@ checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" [[package]] name = "arbitrary" diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index f8be0f7e..8510a9ed 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -47,7 +47,7 @@ alloy-transport = {git = "https://github.com/alloy-rs/alloy.git", optional = tru [dev-dependencies] ethers-contract = { version = "2.0.14", default-features = false } -anyhow = "1.0.81" +anyhow = "1.0.82" criterion = "0.5" indicatif = "0.17" From 688c36ca4525cc44aa7c547b7b0f22a9490c4f2f Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Tue, 16 Apr 2024 22:02:45 +0200 Subject: [PATCH 027/105] chore(interpreter): rename some macros (#1304) --- crates/interpreter/src/instructions/contract.rs | 14 +++++++------- crates/interpreter/src/instructions/control.rs | 12 ++++++------ crates/interpreter/src/instructions/data.rs | 8 ++++---- crates/interpreter/src/instructions/host.rs | 8 ++++---- crates/interpreter/src/instructions/macros.rs | 6 +++--- crates/interpreter/src/instructions/stack.rs | 6 +++--- crates/interpreter/src/instructions/system.rs | 2 +- 7 files changed, 28 insertions(+), 28 deletions(-) diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index 4d3924be..f5e040a2 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -39,7 +39,7 @@ pub fn resize_memory( /// EOF Create instruction pub fn eofcreate(interpreter: &mut Interpreter, _host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); gas!(interpreter, EOF_CREATE_GAS); let initcontainer_index = unsafe { *interpreter.instruction_pointer }; pop!(interpreter, value, salt, data_offset, data_size); @@ -92,7 +92,7 @@ pub fn eofcreate(interpreter: &mut Interpreter, _host: &mut H) } pub fn txcreate(interpreter: &mut Interpreter, host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); gas!(interpreter, EOF_CREATE_GAS); pop!( interpreter, @@ -171,7 +171,7 @@ pub fn txcreate(interpreter: &mut Interpreter, host: &mut H) { } pub fn return_contract(interpreter: &mut Interpreter, _host: &mut H) { - error_on_not_init_eof!(interpreter); + require_init_eof!(interpreter); let deploy_container_index = unsafe { read_u16(interpreter.instruction_pointer) }; pop!(interpreter, aux_data_offset, aux_data_size); let aux_data_size = as_usize_or_fail!(interpreter, aux_data_size); @@ -280,7 +280,7 @@ pub fn extcall_gas_calc( } pub fn extcall(interpreter: &mut Interpreter, host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); pop_address!(interpreter, target_address); // input call @@ -315,7 +315,7 @@ pub fn extcall(interpreter: &mut Interpreter, host } pub fn extdcall(interpreter: &mut Interpreter, host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); pop_address!(interpreter, target_address); // input call @@ -348,7 +348,7 @@ pub fn extdcall(interpreter: &mut Interpreter, hos } pub fn extscall(interpreter: &mut Interpreter, host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); pop_address!(interpreter, target_address); // input call @@ -382,7 +382,7 @@ pub fn create( interpreter: &mut Interpreter, host: &mut H, ) { - error_on_static_call!(interpreter); + require_non_staticcall!(interpreter); // EIP-1014: Skinny CREATE2 if IS_CREATE2 { diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index 02e2de7d..f1c5417a 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -6,7 +6,7 @@ use crate::{ }; pub fn rjump(interpreter: &mut Interpreter, _host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); gas!(interpreter, gas::BASE); let offset = unsafe { read_i16(interpreter.instruction_pointer) } as isize; // In spec it is +3 but pointer is already incremented in @@ -15,7 +15,7 @@ pub fn rjump(interpreter: &mut Interpreter, _host: &mut H) { } pub fn rjumpi(interpreter: &mut Interpreter, _host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); gas!(interpreter, gas::CONDITION_JUMP_GAS); pop!(interpreter, condition); // In spec it is +3 but pointer is already incremented in @@ -29,7 +29,7 @@ pub fn rjumpi(interpreter: &mut Interpreter, _host: &mut H) { } pub fn rjumpv(interpreter: &mut Interpreter, _host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); gas!(interpreter, gas::CONDITION_JUMP_GAS); pop!(interpreter, case); let case = as_isize_saturated!(case); @@ -83,7 +83,7 @@ pub fn jumpdest_or_nop(interpreter: &mut Interpreter, _host: & } pub fn callf(interpreter: &mut Interpreter, _host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); gas!(interpreter, gas::LOW); let idx = unsafe { read_u16(interpreter.instruction_pointer) } as usize; @@ -104,7 +104,7 @@ pub fn callf(interpreter: &mut Interpreter, _host: &mut H) { } pub fn retf(interpreter: &mut Interpreter, _host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); gas!(interpreter, gas::RETF_GAS); let Some(fframe) = interpreter.function_stack.pop() else { @@ -115,7 +115,7 @@ pub fn retf(interpreter: &mut Interpreter, _host: &mut H) { } pub fn jumpf(interpreter: &mut Interpreter, _host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); gas!(interpreter, gas::LOW); let idx = unsafe { read_u16(interpreter.instruction_pointer) } as usize; diff --git a/crates/interpreter/src/instructions/data.rs b/crates/interpreter/src/instructions/data.rs index 1475d24c..5d18a898 100644 --- a/crates/interpreter/src/instructions/data.rs +++ b/crates/interpreter/src/instructions/data.rs @@ -7,7 +7,7 @@ use crate::{ }; pub fn data_load(interpreter: &mut Interpreter, _host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); gas!(interpreter, DATA_LOAD_GAS); pop_top!(interpreter, offset); @@ -27,7 +27,7 @@ pub fn data_load(interpreter: &mut Interpreter, _host: &mut H) } pub fn data_loadn(interpreter: &mut Interpreter, _host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); gas!(interpreter, VERYLOW); let offset = unsafe { read_u16(interpreter.instruction_pointer) } as usize; @@ -48,7 +48,7 @@ pub fn data_loadn(interpreter: &mut Interpreter, _host: &mut H } pub fn data_size(interpreter: &mut Interpreter, _host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); gas!(interpreter, BASE); let data_size = interpreter.eof().expect("eof").header.data_size; @@ -56,7 +56,7 @@ pub fn data_size(interpreter: &mut Interpreter, _host: &mut H) } pub fn data_copy(interpreter: &mut Interpreter, _host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); gas!(interpreter, VERYLOW); pop!(interpreter, mem_offset, offset, size); diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index 77fdf0df..bad571de 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -133,7 +133,7 @@ pub fn sload(interpreter: &mut Interpreter, host: } pub fn sstore(interpreter: &mut Interpreter, host: &mut H) { - error_on_static_call!(interpreter); + require_non_staticcall!(interpreter); pop!(interpreter, index, value); let Some(SStoreResult { @@ -160,7 +160,7 @@ pub fn sstore(interpreter: &mut Interpreter, host: /// Store value to transient storage pub fn tstore(interpreter: &mut Interpreter, host: &mut H) { check!(interpreter, CANCUN); - error_on_static_call!(interpreter); + require_non_staticcall!(interpreter); gas!(interpreter, gas::WARM_STORAGE_READ_COST); pop!(interpreter, index, value); @@ -180,7 +180,7 @@ pub fn tload(interpreter: &mut Interpreter, host: } pub fn log(interpreter: &mut Interpreter, host: &mut H) { - error_on_static_call!(interpreter); + require_non_staticcall!(interpreter); pop!(interpreter, offset, len); let len = as_usize_or_fail!(interpreter, len); @@ -213,7 +213,7 @@ pub fn log(interpreter: &mut Interpreter, host } pub fn selfdestruct(interpreter: &mut Interpreter, host: &mut H) { - error_on_static_call!(interpreter); + require_non_staticcall!(interpreter); pop_address!(interpreter, target); let Some(res) = host.selfdestruct(interpreter.contract.target_address, target) else { diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index a50dddfc..214a6c79 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -2,7 +2,7 @@ /// Fails the instruction if the current call is static. #[macro_export] -macro_rules! error_on_static_call { +macro_rules! require_non_staticcall { ($interp:expr) => { if $interp.is_static { $interp.instruction_result = $crate::InstructionResult::StateChangeDuringStaticCall; @@ -13,7 +13,7 @@ macro_rules! error_on_static_call { /// Error if the current call is executing EOF. #[macro_export] -macro_rules! error_on_disabled_eof { +macro_rules! require_eof { ($interp:expr) => { if !$interp.is_eof { $interp.instruction_result = $crate::InstructionResult::EOFOpcodeDisabledInLegacy; @@ -24,7 +24,7 @@ macro_rules! error_on_disabled_eof { /// Error if not init eof call. #[macro_export] -macro_rules! error_on_not_init_eof { +macro_rules! require_init_eof { ($interp:expr) => { if !$interp.is_eof_init { $interp.instruction_result = $crate::InstructionResult::ReturnContractInNotInitEOF; diff --git a/crates/interpreter/src/instructions/stack.rs b/crates/interpreter/src/instructions/stack.rs index dfd2a58b..d75067e1 100644 --- a/crates/interpreter/src/instructions/stack.rs +++ b/crates/interpreter/src/instructions/stack.rs @@ -52,7 +52,7 @@ pub fn swap(interpreter: &mut Interpreter, _ho } pub fn dupn(interpreter: &mut Interpreter, _host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); gas!(interpreter, gas::VERYLOW); let imm = unsafe { *interpreter.instruction_pointer }; if let Err(result) = interpreter.stack.dup(imm as usize + 1) { @@ -62,7 +62,7 @@ pub fn dupn(interpreter: &mut Interpreter, _host: &mut H) { } pub fn swapn(interpreter: &mut Interpreter, _host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); gas!(interpreter, gas::VERYLOW); let imm = unsafe { *interpreter.instruction_pointer }; if let Err(result) = interpreter.stack.swap(imm as usize + 1) { @@ -72,7 +72,7 @@ pub fn swapn(interpreter: &mut Interpreter, _host: &mut H) { } pub fn exchange(interpreter: &mut Interpreter, _host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); gas!(interpreter, gas::VERYLOW); let imm = unsafe { *interpreter.instruction_pointer }; let n = (imm >> 4) + 1; diff --git a/crates/interpreter/src/instructions/system.rs b/crates/interpreter/src/instructions/system.rs index b7fbe01b..0887a874 100644 --- a/crates/interpreter/src/instructions/system.rs +++ b/crates/interpreter/src/instructions/system.rs @@ -145,7 +145,7 @@ pub fn returndatacopy(interpreter: &mut Interprete /// Part of EOF ``. pub fn returndataload(interpreter: &mut Interpreter, _host: &mut H) { - error_on_disabled_eof!(interpreter); + require_eof!(interpreter); gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, offset); let offset_usize = as_usize_or_fail!(interpreter, offset); From 41beddfcf6d89d66a359dece2082cc5944bf7623 Mon Sep 17 00:00:00 2001 From: Iaroslav Mazur Date: Fri, 19 Apr 2024 23:41:48 +0300 Subject: [PATCH 028/105] docs: fix the Instruction Table link (#1337) --- documentation/src/crates/revm/handler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/src/crates/revm/handler.md b/documentation/src/crates/revm/handler.md index 5e9c14fb..c6239d62 100644 --- a/documentation/src/crates/revm/handler.md +++ b/documentation/src/crates/revm/handler.md @@ -8,7 +8,7 @@ Functions can be grouped in five categories and are marked in that way in the co * Pre-execution functions: [`PreExecutionHandler`](https://github.com/bluealloy/revm/blob/main/crates/revm/src/handler/handle_types/pre_execution.rs) * Execution functions: [`ExecutionHandler`](https://github.com/bluealloy/revm/blob/main/crates/revm/src/handler/handle_types/execution.rs) * Post-execution functions: [`PostExecutionHandler`](https://github.com/bluealloy/revm/blob/main/crates/revm/src/handler/handle_types/post_execution.rs) -* Instruction table: [`InstructionTable`](https://github.com/bluealloy/revm/blob/main/crates/interpreter/src/instructions/opcode.rs) +* Instruction table: [`InstructionTable`](https://github.com/bluealloy/revm/blob/main/crates/interpreter/src/opcode.rs) ### Handle Registers From 43199ddd3c1211eb8d4c37b352cec2383903d32d Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 19 Apr 2024 22:42:20 +0200 Subject: [PATCH 029/105] chore: weekly dependabot (#1325) --- .github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7654431f..4eed0dcc 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,4 +8,4 @@ updates: - package-ecosystem: cargo directory: "/" schedule: - interval: "daily" + interval: "weekly" From e987d2b151fd3bfa9babc97aaeabac0f137b0329 Mon Sep 17 00:00:00 2001 From: Iaroslav Mazur Date: Fri, 19 Apr 2024 23:46:09 +0300 Subject: [PATCH 030/105] chore: update GitHub Actions to Node 20 (#1338) --- .github/workflows/book.yml | 2 +- .github/workflows/cachegrind.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml index 218ac0b8..10894c4d 100644 --- a/.github/workflows/book.yml +++ b/.github/workflows/book.yml @@ -104,7 +104,7 @@ jobs: . - name: Upload artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: github-pages path: ${{ runner.temp }}/artifact.tar diff --git a/.github/workflows/cachegrind.yml b/.github/workflows/cachegrind.yml index 1e21cc7a..ad79a05a 100644 --- a/.github/workflows/cachegrind.yml +++ b/.github/workflows/cachegrind.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup | Rust uses: dtolnay/rust-toolchain@stable From bcdc652cac5940ed8b3521519d590b9371660521 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Sun, 21 Apr 2024 09:21:59 +0200 Subject: [PATCH 031/105] Implement `with_chain_id` for `CfgEnv` (#1327) * Implement with_chain_id for CfgEnv * cargo fmt * fix comments --- crates/primitives/src/env.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/primitives/src/env.rs b/crates/primitives/src/env.rs index 9a4470a9..9d0bc100 100644 --- a/crates/primitives/src/env.rs +++ b/crates/primitives/src/env.rs @@ -338,6 +338,11 @@ pub struct CfgEnv { } impl CfgEnv { + pub fn with_chain_id(mut self, chain_id: u64) -> Self { + self.chain_id = chain_id; + self + } + #[cfg(feature = "optional_eip3607")] pub fn is_eip3607_disabled(&self) -> bool { self.disable_eip3607 From 76e22baff8b54b5969e1424b99a23a906e9ab3b5 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Sun, 21 Apr 2024 09:32:06 +0200 Subject: [PATCH 032/105] feat: add helper methods to CallInputs (#1345) --- .../interpreter/src/instructions/contract.rs | 18 +-- crates/interpreter/src/interpreter_action.rs | 2 +- .../src/interpreter_action/call_inputs.rs | 147 ++++++++++++++---- crates/interpreter/src/lib.rs | 4 +- crates/revm/src/context/evm_context.rs | 10 +- 5 files changed, 137 insertions(+), 44 deletions(-) diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index f5e040a2..acb896f4 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -11,8 +11,8 @@ use crate::{ instructions::utility::read_u16, interpreter::Interpreter, primitives::{Address, Bytes, Eof, Spec, SpecId::*, B256, U256}, - CallInputs, CallScheme, CreateInputs, CreateScheme, EOFCreateInput, Host, InstructionResult, - InterpreterAction, InterpreterResult, LoadAccountResult, TransferValue, MAX_INITCODE_SIZE, + CallInputs, CallScheme, CallValue, CreateInputs, CreateScheme, EOFCreateInput, Host, + InstructionResult, InterpreterAction, InterpreterResult, LoadAccountResult, MAX_INITCODE_SIZE, }; use core::{cmp::max, ops::Range}; use std::boxed::Box; @@ -304,7 +304,7 @@ pub fn extcall(interpreter: &mut Interpreter, host target_address, caller: interpreter.contract.target_address, bytecode_address: target_address, - value: TransferValue::Value(value), + value: CallValue::Transfer(value), scheme: CallScheme::Call, is_static: interpreter.is_static, is_eof: true, @@ -336,7 +336,7 @@ pub fn extdcall(interpreter: &mut Interpreter, hos target_address, caller: interpreter.contract.target_address, bytecode_address: target_address, - value: TransferValue::ApparentValue(interpreter.contract.call_value), + value: CallValue::Apparent(interpreter.contract.call_value), // TODO(EOF) should be EofDelegateCall? scheme: CallScheme::DelegateCall, is_static: interpreter.is_static, @@ -368,7 +368,7 @@ pub fn extscall(interpreter: &mut Interpreter, host: &mut H) { target_address, caller: interpreter.contract.target_address, bytecode_address: target_address, - value: TransferValue::Value(U256::ZERO), + value: CallValue::Transfer(U256::ZERO), scheme: CallScheme::Call, is_static: interpreter.is_static, is_eof: true, @@ -494,7 +494,7 @@ pub fn call(interpreter: &mut Interpreter, host: & target_address: to, caller: interpreter.contract.target_address, bytecode_address: to, - value: TransferValue::Value(value), + value: CallValue::Transfer(value), scheme: CallScheme::Call, is_static: interpreter.is_static, is_eof: false, @@ -545,7 +545,7 @@ pub fn call_code(interpreter: &mut Interpreter, ho target_address: interpreter.contract.target_address, caller: interpreter.contract.target_address, bytecode_address: to, - value: TransferValue::Value(value), + value: CallValue::Transfer(value), scheme: CallScheme::CallCode, is_static: interpreter.is_static, is_eof: false, @@ -586,7 +586,7 @@ pub fn delegate_call(interpreter: &mut Interpreter target_address: interpreter.contract.target_address, caller: interpreter.contract.caller, bytecode_address: to, - value: TransferValue::ApparentValue(interpreter.contract.call_value), + value: CallValue::Apparent(interpreter.contract.call_value), scheme: CallScheme::DelegateCall, is_static: interpreter.is_static, is_eof: false, @@ -627,7 +627,7 @@ pub fn static_call(interpreter: &mut Interpreter, target_address: to, caller: interpreter.contract.target_address, bytecode_address: to, - value: TransferValue::Value(U256::ZERO), + value: CallValue::Transfer(U256::ZERO), scheme: CallScheme::StaticCall, is_static: true, is_eof: false, diff --git a/crates/interpreter/src/interpreter_action.rs b/crates/interpreter/src/interpreter_action.rs index 25dc1448..0581e220 100644 --- a/crates/interpreter/src/interpreter_action.rs +++ b/crates/interpreter/src/interpreter_action.rs @@ -5,7 +5,7 @@ mod create_outcome; mod eof_create_inputs; mod eof_create_outcome; -pub use call_inputs::{CallInputs, CallScheme, TransferValue}; +pub use call_inputs::{CallInputs, CallScheme, CallValue}; pub use call_outcome::CallOutcome; pub use create_inputs::{CreateInputs, CreateScheme}; pub use create_outcome::CreateOutcome; diff --git a/crates/interpreter/src/interpreter_action/call_inputs.rs b/crates/interpreter/src/interpreter_action/call_inputs.rs index 5f9cb32a..196f7b1a 100644 --- a/crates/interpreter/src/interpreter_action/call_inputs.rs +++ b/crates/interpreter/src/interpreter_action/call_inputs.rs @@ -9,45 +9,54 @@ pub struct CallInputs { /// The call data of the call. pub input: Bytes, /// The return memory offset where the output of the call is written. - /// For EOF this range is invalid as EOF does write output to memory. + /// + /// In EOF, this range is invalid as EOF calls do not write output to memory. pub return_memory_offset: Range, /// The gas limit of the call. pub gas_limit: u64, - /// The account address of bytecode that is going to be executed. + /// The account address of bytecode that is going to be executed. + /// + /// Previously `context.code_address`. pub bytecode_address: Address, /// Target address, this account storage is going to be modified. + /// + /// Previously `context.address`. pub target_address: Address, /// This caller is invoking the call. + /// + /// Previously `context.caller`. pub caller: Address, - /// Value that is transferred in Ether. + /// Call value. + /// + /// NOTE: This value may not necessarily be transferred from caller to callee, see [`CallValue`]. /// - /// If enum is [`TransferValue::Value`] balance is transferer from `caller` to the `target_address`. + /// Previously `transfer.value` or `context.apparent_value`. + pub value: CallValue, + /// The call scheme. /// - /// If enum is [`TransferValue::ApparentValue`] balance transfer is **not** - /// done and apparent value is used by CALLVALUE opcode. Used by delegate call. - pub value: TransferValue, - /// The scheme used for the call. Call, callcode, delegatecall or staticcall. + /// Previously `context.scheme`. pub scheme: CallScheme, - /// Whether this is a static call. + /// Whether the call is initiated inside a static call. pub is_static: bool, - /// Call is initiated from EOF bytecode. + /// Whether the call is initiated from EOF bytecode. pub is_eof: bool, } impl CallInputs { /// Creates new call inputs. + /// + /// Returns `None` if the transaction is not a call. pub fn new(tx_env: &TxEnv, gas_limit: u64) -> Option { let TransactTo::Call(target_address) = tx_env.transact_to else { return None; }; - Some(CallInputs { input: tx_env.data.clone(), gas_limit, target_address, bytecode_address: target_address, caller: tx_env.caller, - value: TransferValue::Value(tx_env.value), + value: CallValue::Transfer(tx_env.value), scheme: CallScheme::Call, is_static: false, is_eof: false, @@ -55,19 +64,61 @@ impl CallInputs { }) } - /// Returns boxed call inputs. + /// Creates new boxed call inputs. + /// + /// Returns `None` if the transaction is not a call. pub fn new_boxed(tx_env: &TxEnv, gas_limit: u64) -> Option> { Self::new(tx_env, gas_limit).map(Box::new) } - /// Return call value - pub fn call_value(&self) -> U256 { - let (TransferValue::Value(value) | TransferValue::ApparentValue(value)) = self.value; - value + /// Returns `true` if the call will transfer a non-zero value. + #[inline] + pub fn transfers_value(&self) -> bool { + self.value.transfer().is_some_and(|x| x > U256::ZERO) + } + + /// Returns the transfer value. + /// + /// This is the value that is transferred from caller to callee, see [`CallValue`]. + #[inline] + pub const fn transfer_value(&self) -> Option { + self.value.transfer() + } + + /// Returns the **apparent** call value. + /// + /// This value is not actually transferred, see [`CallValue`]. + #[inline] + pub const fn apparent_value(&self) -> Option { + self.value.apparent() + } + + /// Returns the address of the transfer source account. + /// + /// This is only meaningful if `transfers_value` is `true`. + #[inline] + pub const fn transfer_from(&self) -> Address { + self.caller + } + + /// Returns the address of the transfer target account. + /// + /// This is only meaningful if `transfers_value` is `true`. + #[inline] + pub const fn transfer_to(&self) -> Address { + self.target_address + } + + /// Returns the call value, regardless of the transfer value type. + /// + /// NOTE: this value may not necessarily be transferred from caller to callee, see [`CallValue`]. + #[inline] + pub const fn call_value(&self) -> U256 { + self.value.get() } } -/// Call schemes. +/// Call scheme. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum CallScheme { @@ -81,19 +132,61 @@ pub enum CallScheme { StaticCall, } -/// Transfered value from caller to callee. +/// Call value. #[derive(Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub enum TransferValue { - /// Transfer value from caller to callee. - Value(U256), - /// For delegate call, the value is not transferred but - /// apparent value is used for CALLVALUE opcode - ApparentValue(U256), +pub enum CallValue { + /// Concrete value, transferred from caller to callee at the end of the transaction. + Transfer(U256), + /// Apparent value, that is **not** actually transferred. + /// + /// Set when in a `DELEGATECALL` call type, and used by the `CALLVALUE` opcode. + Apparent(U256), } -impl Default for TransferValue { +impl Default for CallValue { + #[inline] fn default() -> Self { - TransferValue::Value(U256::ZERO) + CallValue::Transfer(U256::ZERO) + } +} + +impl CallValue { + /// Returns the call value, regardless of the type. + #[inline] + pub const fn get(&self) -> U256 { + match *self { + Self::Transfer(value) | Self::Apparent(value) => value, + } + } + + /// Returns the transferred value, if any. + #[inline] + pub const fn transfer(&self) -> Option { + match *self { + Self::Transfer(transfer) => Some(transfer), + Self::Apparent(_) => None, + } + } + + /// Returns whether the call value will be transferred. + #[inline] + pub const fn is_transfer(&self) -> bool { + matches!(self, Self::Transfer(_)) + } + + /// Returns the apparent value, if any. + #[inline] + pub const fn apparent(&self) -> Option { + match *self { + Self::Transfer(_) => None, + Self::Apparent(apparent) => Some(apparent), + } + } + + /// Returns whether the call value is apparent, and not actually transferred. + #[inline] + pub const fn is_apparent(&self) -> bool { + matches!(self, Self::Apparent(_)) } } diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index 7d749fb9..50507409 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -38,8 +38,8 @@ pub use interpreter::{ EMPTY_SHARED_MEMORY, STACK_LIMIT, }; pub use interpreter_action::{ - CallInputs, CallOutcome, CallScheme, CreateInputs, CreateOutcome, CreateScheme, EOFCreateInput, - EOFCreateOutcome, InterpreterAction, TransferValue, + CallInputs, CallOutcome, CallScheme, CallValue, CreateInputs, CreateOutcome, CreateScheme, + EOFCreateInput, EOFCreateOutcome, InterpreterAction, }; pub use opcode::{Instruction, OpCode, OPCODE_INFO_JUMPTABLE}; pub use primitives::{MAX_CODE_SIZE, MAX_INITCODE_SIZE}; diff --git a/crates/revm/src/context/evm_context.rs b/crates/revm/src/context/evm_context.rs index a313226b..b92d711d 100644 --- a/crates/revm/src/context/evm_context.rs +++ b/crates/revm/src/context/evm_context.rs @@ -1,4 +1,4 @@ -use revm_interpreter::TransferValue; +use revm_interpreter::CallValue; use super::inner_evm_context::InnerEvmContext; use crate::{ @@ -175,11 +175,11 @@ impl EvmContext { // Touch address. For "EIP-158 State Clear", this will erase empty accounts. match inputs.value { // if transfer value is zero, do the touch. - TransferValue::Value(value) if value == U256::ZERO => { + CallValue::Transfer(value) if value == U256::ZERO => { self.load_account(inputs.target_address)?; self.journaled_state.touch(&inputs.target_address); } - TransferValue::Value(value) => { + CallValue::Transfer(value) => { // Transfer value from caller to called account if let Some(result) = self.inner.journaled_state.transfer( &inputs.caller, @@ -241,7 +241,7 @@ pub(crate) mod test_utils { bytecode_address: to, target_address: to, caller: MOCK_CALLER, - value: TransferValue::Value(U256::ZERO), + value: CallValue::Transfer(U256::ZERO), scheme: revm_interpreter::CallScheme::Call, is_eof: false, is_static: false, @@ -344,7 +344,7 @@ mod tests { let mut evm_context = test_utils::create_empty_evm_context(Box::new(env), db); let contract = address!("dead10000000000000000000000000000001dead"); let mut call_inputs = test_utils::create_mock_call_inputs(contract); - call_inputs.value = TransferValue::Value(U256::from(1)); + call_inputs.value = CallValue::Transfer(U256::from(1)); let res = evm_context.make_call_frame(&call_inputs); let Ok(FrameOrResult::Result(result)) = res else { panic!("Expected FrameOrResult::Result"); From 1ca3d39f6a9e9778f8eb0fcb74fe529345a531b4 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 21 Apr 2024 11:32:31 +0400 Subject: [PATCH 033/105] fix(revme): Print one json outcome in statetest (#1347) --- bins/revme/src/cmd/statetest/runner.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bins/revme/src/cmd/statetest/runner.rs b/bins/revme/src/cmd/statetest/runner.rs index 72562356..c9f8aede 100644 --- a/bins/revme/src/cmd/statetest/runner.rs +++ b/bins/revme/src/cmd/statetest/runner.rs @@ -369,7 +369,9 @@ pub fn execute_test_suite( let (e, exec_result) = if trace { let mut evm = evm .modify() - .reset_handler_with_external_context(TracerEip3155::new(Box::new(stderr()))) + .reset_handler_with_external_context( + TracerEip3155::new(Box::new(stderr())).without_summary(), + ) .append_handler_register(inspector_handle_register) .build(); From 16b3f21a142dcc1e60c8e1a52c36f50c09bd0bb5 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 29 Apr 2024 12:49:55 +0200 Subject: [PATCH 034/105] refactor: shrink OpCodeInfo and add more methods (#1307) * refactor: shrink OpCodeInfo and add more methods * review * Update crates/interpreter/src/opcode.rs * Update crates/interpreter/src/opcode.rs --- .../interpreter/src/interpreter/analysis.rs | 14 +- crates/interpreter/src/opcode.rs | 599 ++++++++++-------- crates/interpreter/src/opcode/eof_printer.rs | 12 +- .../src/bytecode/eof/types_section.rs | 4 +- crates/revm/src/inspector/eip3155.rs | 2 +- 5 files changed, 364 insertions(+), 267 deletions(-) diff --git a/crates/interpreter/src/interpreter/analysis.rs b/crates/interpreter/src/interpreter/analysis.rs index bc2d96d2..2b2d89f7 100644 --- a/crates/interpreter/src/interpreter/analysis.rs +++ b/crates/interpreter/src/interpreter/analysis.rs @@ -304,7 +304,7 @@ pub fn validate_eof_code( return Err(EofValidationError::UnknownOpcode); }; - if !opcode.is_eof { + if opcode.is_disabled_in_eof() { // Opcode is disabled in EOF return Err(EofValidationError::OpcodeDisabled); } @@ -324,18 +324,18 @@ pub fn validate_eof_code( // opcode after termination was not accessed. return Err(EofValidationError::InstructionNotForwardAccessed); } - is_after_termination = opcode.is_terminating_opcode; + is_after_termination = opcode.is_terminating(); // mark immediate as non-jumpable. RJUMPV is special case covered later. - if opcode.immediate_size != 0 { + if opcode.immediate_size() != 0 { // check if the opcode immediate are within the bounds of the code - if i + opcode.immediate_size as usize >= code.len() { + if i + opcode.immediate_size() as usize >= code.len() { // Malfunctional code return Err(EofValidationError::MissingImmediateBytes); } // mark immediate bytes as non-jumpable. - for imm in 1..opcode.immediate_size as usize + 1 { + for imm in 1..opcode.immediate_size() as usize + 1 { // SAFETY: immediate size is checked above. jumps[i + imm].mark_as_immediate()?; } @@ -343,7 +343,7 @@ pub fn validate_eof_code( // IO diff used to generate next instruction smallest/biggest value. let mut stack_io_diff = opcode.io_diff() as i32; // how many stack items are required for this opcode. - let mut stack_requirement = opcode.inputs as i32; + let mut stack_requirement = opcode.inputs() as i32; // additional immediate bytes for RJUMPV, it has dynamic vtable. let mut rjumpv_additional_immediates = 0; // If opcodes is RJUMP, RJUMPI or RJUMPV then this will have absolute jumpdest. @@ -534,7 +534,7 @@ pub fn validate_eof_code( } // additional immediate are from RJUMPV vtable. - i += 1 + opcode.immediate_size as usize + rjumpv_additional_immediates; + i += 1 + opcode.immediate_size() as usize + rjumpv_additional_immediates; } // last opcode should be terminating diff --git a/crates/interpreter/src/opcode.rs b/crates/interpreter/src/opcode.rs index 883ceed7..eb4ff273 100644 --- a/crates/interpreter/src/opcode.rs +++ b/crates/interpreter/src/opcode.rs @@ -3,7 +3,7 @@ pub mod eof_printer; use crate::{instructions::*, primitives::Spec, Host, Interpreter}; -use core::fmt; +use core::{fmt, ptr::NonNull}; use std::boxed::Box; /// EVM opcode function signature. @@ -137,7 +137,7 @@ impl fmt::Display for OpCode { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let n = self.get(); if let Some(val) = OPCODE_INFO_JUMPTABLE[n as usize] { - f.write_str(val.name) + f.write_str(val.name()) } else { write!(f, "UNKNOWN(0x{n:02X})") } @@ -186,7 +186,7 @@ impl OpCode { } } - /// Returns true if the opcode is a push instruction. + /// Returns true if the opcode is a `PUSH` instruction. #[inline] pub const fn is_push(self) -> bool { self.0 >= PUSH1 && self.0 <= PUSH32 @@ -214,9 +214,10 @@ impl OpCode { } /// Returns the opcode as a string. + #[doc(alias = "name")] #[inline] pub const fn as_str(self) -> &'static str { - self.info().name + self.info().name() } /// Returns the opcode name. @@ -229,21 +230,26 @@ impl OpCode { } } - /// Returns inputs for the given opcode. + /// Returns the number of input stack elements. + #[inline] pub const fn inputs(&self) -> u8 { - self.info().inputs + self.info().inputs() } - /// Returns outputs for the given opcode. + /// Returns the number of output stack elements. + #[inline] pub const fn outputs(&self) -> u8 { - self.info().outputs + self.info().outputs() } - /// Returns a difference between input and output. + /// Calculates the difference between the number of input and output stack elements. + #[inline] pub const fn io_diff(&self) -> i16 { self.info().io_diff() } + /// Returns the opcode information for the given opcode. + #[inline] pub const fn info_by_op(opcode: u8) -> Option { if let Some(opcode) = Self::new(opcode) { Some(opcode.info()) @@ -252,16 +258,18 @@ impl OpCode { } } + /// Returns the opcode information. #[inline] pub const fn info(&self) -> OpCodeInfo { if let Some(t) = OPCODE_INFO_JUMPTABLE[self.0 as usize] { t } else { - panic!("unreachable, all opcodes are defined") + panic!("opcode not found") } } - /// Returns a tuple of input and output. + /// Returns the number of both input and output stack elements. + /// /// Can be slightly faster that calling `inputs` and `outputs` separately. pub const fn input_output(&self) -> (u8, u8) { let info = self.info(); @@ -276,43 +284,140 @@ impl OpCode { } /// Information about opcode, such as name, and stack inputs and outputs. -#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct OpCodeInfo { - pub name: &'static str, - pub inputs: u8, - pub outputs: u8, - // TODO make this a bitfield - pub is_eof: bool, - // If the opcode is return from execution. aka STOP,RETURN, .. - pub is_terminating_opcode: bool, - /// Size of opcode with its intermediate bytes. + /// Invariant: `(name_ptr, name_len)` is a `&'static str`. It is a shorted variant of `str` as + /// the name length is always less than 256 characters. + name_ptr: NonNull, + name_len: u8, + /// Stack inputs. + inputs: u8, + /// Stack outputs. + outputs: u8, + /// Number of intermediate bytes. /// - /// RJUMPV is special case where the bytes len is depending on bytecode value, - /// for RJUMV size will be set to one byte while minimum is two. - pub immediate_size: u8, + /// RJUMPV is a special case where the bytes len depends on bytecode value, + /// for RJUMV size will be set to one byte as it is the minimum immediate size. + immediate_size: u8, + /// Used by EOF verification. All not EOF opcodes are marked false. + not_eof: bool, + /// If the opcode stops execution. aka STOP, RETURN, .. + terminating: bool, +} + +impl fmt::Debug for OpCodeInfo { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("OpCodeInfo") + .field("name", &self.name()) + .field("inputs", &self.inputs()) + .field("outputs", &self.outputs()) + .field("not_eof", &self.is_disabled_in_eof()) + .field("terminating", &self.is_terminating()) + .field("immediate_size", &self.immediate_size()) + .finish() + } } impl OpCodeInfo { + /// Creates a new opcode info with the given name and default values. pub const fn new(name: &'static str) -> Self { + assert!(name.len() < 256, "opcode name is too long"); Self { - name, + name_ptr: unsafe { NonNull::new_unchecked(name.as_ptr().cast_mut()) }, + name_len: name.len() as u8, inputs: 0, outputs: 0, - is_eof: true, - is_terminating_opcode: false, + not_eof: false, + terminating: false, immediate_size: 0, } } + /// Returns the opcode name. + #[inline] + pub const fn name(&self) -> &'static str { + // SAFETY: `self.name_*` can only be initialized with a valid `&'static str`. + unsafe { + // TODO: Use `str::from_raw_parts` when it's stable. + let slice = core::slice::from_raw_parts(self.name_ptr.as_ptr(), self.name_len as usize); + core::str::from_utf8_unchecked(slice) + } + } + + /// Calculates the difference between the number of input and output stack elements. + #[inline] pub const fn io_diff(&self) -> i16 { self.outputs as i16 - self.inputs as i16 } + + /// Returns the number of input stack elements. + #[inline] + pub const fn inputs(&self) -> u8 { + self.inputs + } + + /// Returns the number of output stack elements. + #[inline] + pub const fn outputs(&self) -> u8 { + self.outputs + } + + /// Returns whether this opcode is disabled in EOF bytecode. + #[inline] + pub const fn is_disabled_in_eof(&self) -> bool { + self.not_eof + } + + /// Returns whether this opcode terminates execution, e.g. `STOP`, `RETURN`, etc. + #[inline] + pub const fn is_terminating(&self) -> bool { + self.terminating + } + + /// Returns the size of the immediate value in bytes. + #[inline] + pub const fn immediate_size(&self) -> u8 { + self.immediate_size + } +} + +/// Sets the EOF flag to false. +#[inline] +pub const fn not_eof(mut op: OpCodeInfo) -> OpCodeInfo { + op.not_eof = true; + op +} + +/// Sets the immediate bytes number. +/// +/// RJUMPV is special case where the bytes len is depending on bytecode value, +/// for RJUMPV size will be set to one byte while minimum is two. +#[inline] +pub const fn immediate_size(mut op: OpCodeInfo, n: u8) -> OpCodeInfo { + op.immediate_size = n; + op +} + +/// Sets the terminating flag to true. +#[inline] +pub const fn terminating(mut op: OpCodeInfo) -> OpCodeInfo { + op.terminating = true; + op +} + +/// Sets the number of stack inputs and outputs. +#[inline] +pub const fn stack_io(mut op: OpCodeInfo, inputs: u8, outputs: u8) -> OpCodeInfo { + op.inputs = inputs; + op.outputs = outputs; + op } +/// Alias for the [`JUMPDEST`] opcode. pub const NOP: u8 = JUMPDEST; macro_rules! opcodes { - ($($val:literal => $name:ident => $f:expr => $($modifier:ident $(< $($modifier_num:literal),* >)?),*);* $(;)?) => { + ($($val:literal => $name:ident => $f:expr => $($modifier:ident $(( $($modifier_arg:expr),* ))?),*);* $(;)?) => { // Constants for each opcode. This also takes care of duplicate names. $( #[doc = concat!("The `", stringify!($val), "` (\"", stringify!($name),"\") opcode.")] @@ -331,9 +436,11 @@ macro_rules! opcodes { let val: u8 = $val; assert!(val == 0 || val > prev, "opcodes must be sorted in ascending order"); prev = val; - let opcode = OpCodeInfo::new(stringify!($name)); - $( let opcode = $modifier$(::< $( $modifier_num ),+ >)? (opcode);)* - map[$val] = Some(opcode); + let info = OpCodeInfo::new(stringify!($name)); + $( + let info = $modifier(info, $($($modifier_arg),*)?); + )* + map[$val] = Some(info); )* let _ = prev; map @@ -349,68 +456,45 @@ macro_rules! opcodes { }; } -pub const fn not_eof(mut opcode: OpCodeInfo) -> OpCodeInfo { - opcode.is_eof = false; - opcode -} - -/// Immediate bytes after opcode. -pub const fn imm_size(mut opcode: OpCodeInfo) -> OpCodeInfo { - opcode.immediate_size = N; - opcode -} - -pub const fn terminating(mut opcode: OpCodeInfo) -> OpCodeInfo { - opcode.is_terminating_opcode = true; - opcode -} - -pub const fn stack_io(mut opcode: OpCodeInfo) -> OpCodeInfo { - opcode.inputs = I; - opcode.outputs = O; - opcode -} - // When adding new opcodes: // 1. add the opcode to the list below; make sure it's sorted by opcode value -// 2. add its gas info in the `opcode_gas_info` function below -// 3. implement the opcode in the corresponding module; +// 2. implement the opcode in the corresponding module; // the function signature must be the exact same as the others opcodes! { - 0x00 => STOP => control::stop => stack_io<0,0>, terminating; - - 0x01 => ADD => arithmetic::add => stack_io<2, 1>; - 0x02 => MUL => arithmetic::mul => stack_io<2, 1>; - 0x03 => SUB => arithmetic::sub => stack_io<2, 1>; - 0x04 => DIV => arithmetic::div => stack_io<2, 1>; - 0x05 => SDIV => arithmetic::sdiv => stack_io<2, 1>; - 0x06 => MOD => arithmetic::rem => stack_io<2, 1>; - 0x07 => SMOD => arithmetic::smod => stack_io<2, 1>; - 0x08 => ADDMOD => arithmetic::addmod => stack_io<3, 1>; - 0x09 => MULMOD => arithmetic::mulmod => stack_io<3, 1>; - 0x0A => EXP => arithmetic::exp:: => stack_io<2, 1>; - 0x0B => SIGNEXTEND => arithmetic::signextend => stack_io<2, 1>; + 0x00 => STOP => control::stop => stack_io(0, 0), terminating; + + 0x01 => ADD => arithmetic::add => stack_io(2, 1); + 0x02 => MUL => arithmetic::mul => stack_io(2, 1); + 0x03 => SUB => arithmetic::sub => stack_io(2, 1); + 0x04 => DIV => arithmetic::div => stack_io(2, 1); + 0x05 => SDIV => arithmetic::sdiv => stack_io(2, 1); + 0x06 => MOD => arithmetic::rem => stack_io(2, 1); + 0x07 => SMOD => arithmetic::smod => stack_io(2, 1); + 0x08 => ADDMOD => arithmetic::addmod => stack_io(3, 1); + 0x09 => MULMOD => arithmetic::mulmod => stack_io(3, 1); + 0x0A => EXP => arithmetic::exp:: => stack_io(2, 1); + 0x0B => SIGNEXTEND => arithmetic::signextend => stack_io(2, 1); // 0x0C // 0x0D // 0x0E // 0x0F - 0x10 => LT => bitwise::lt => stack_io<2, 1>; - 0x11 => GT => bitwise::gt => stack_io<2, 1>; - 0x12 => SLT => bitwise::slt => stack_io<2, 1>; - 0x13 => SGT => bitwise::sgt => stack_io<2, 1>; - 0x14 => EQ => bitwise::eq => stack_io<2, 1>; - 0x15 => ISZERO => bitwise::iszero => stack_io<1, 1>; - 0x16 => AND => bitwise::bitand => stack_io<2, 1>; - 0x17 => OR => bitwise::bitor => stack_io<2, 1>; - 0x18 => XOR => bitwise::bitxor => stack_io<2, 1>; - 0x19 => NOT => bitwise::not => stack_io<1, 1>; - 0x1A => BYTE => bitwise::byte => stack_io<2, 1>; - 0x1B => SHL => bitwise::shl:: => stack_io<2, 1>; - 0x1C => SHR => bitwise::shr:: => stack_io<2, 1>; - 0x1D => SAR => bitwise::sar:: => stack_io<2, 1>; + 0x10 => LT => bitwise::lt => stack_io(2, 1); + 0x11 => GT => bitwise::gt => stack_io(2, 1); + 0x12 => SLT => bitwise::slt => stack_io(2, 1); + 0x13 => SGT => bitwise::sgt => stack_io(2, 1); + 0x14 => EQ => bitwise::eq => stack_io(2, 1); + 0x15 => ISZERO => bitwise::iszero => stack_io(1, 1); + 0x16 => AND => bitwise::bitand => stack_io(2, 1); + 0x17 => OR => bitwise::bitor => stack_io(2, 1); + 0x18 => XOR => bitwise::bitxor => stack_io(2, 1); + 0x19 => NOT => bitwise::not => stack_io(1, 1); + 0x1A => BYTE => bitwise::byte => stack_io(2, 1); + 0x1B => SHL => bitwise::shl:: => stack_io(2, 1); + 0x1C => SHR => bitwise::shr:: => stack_io(2, 1); + 0x1D => SAR => bitwise::sar:: => stack_io(2, 1); // 0x1E // 0x1F - 0x20 => KECCAK256 => system::keccak256 => stack_io<2, 1>; + 0x20 => KECCAK256 => system::keccak256 => stack_io(2, 1); // 0x21 // 0x22 // 0x23 @@ -426,128 +510,128 @@ opcodes! { // 0x2D // 0x2E // 0x2F - 0x30 => ADDRESS => system::address => stack_io<0, 1>; - 0x31 => BALANCE => host::balance:: => stack_io<1, 1>; - 0x32 => ORIGIN => host_env::origin => stack_io<0, 1>; - 0x33 => CALLER => system::caller => stack_io<0, 1>; - 0x34 => CALLVALUE => system::callvalue => stack_io<0, 1>; - 0x35 => CALLDATALOAD => system::calldataload => stack_io<1, 1>; - 0x36 => CALLDATASIZE => system::calldatasize => stack_io<0, 1>; - 0x37 => CALLDATACOPY => system::calldatacopy => stack_io<3, 0>; - 0x38 => CODESIZE => system::codesize => stack_io<0, 1>, not_eof; - 0x39 => CODECOPY => system::codecopy => stack_io<3, 0>, not_eof; - - 0x3A => GASPRICE => host_env::gasprice => stack_io<0, 1>; - 0x3B => EXTCODESIZE => host::extcodesize:: => stack_io<1, 1>, not_eof; - 0x3C => EXTCODECOPY => host::extcodecopy:: => stack_io<4, 0>, not_eof; - 0x3D => RETURNDATASIZE => system::returndatasize:: => stack_io<0, 1>; - 0x3E => RETURNDATACOPY => system::returndatacopy:: => stack_io<3, 0>; - 0x3F => EXTCODEHASH => host::extcodehash:: => stack_io<1, 1>, not_eof; - 0x40 => BLOCKHASH => host::blockhash => stack_io<1, 1>; - 0x41 => COINBASE => host_env::coinbase => stack_io<0, 1>; - 0x42 => TIMESTAMP => host_env::timestamp => stack_io<0, 1>; - 0x43 => NUMBER => host_env::block_number => stack_io<0, 1>; - 0x44 => DIFFICULTY => host_env::difficulty:: => stack_io<0, 1>; - 0x45 => GASLIMIT => host_env::gaslimit => stack_io<0, 1>; - 0x46 => CHAINID => host_env::chainid:: => stack_io<0, 1>; - 0x47 => SELFBALANCE => host::selfbalance:: => stack_io<0, 1>; - 0x48 => BASEFEE => host_env::basefee:: => stack_io<0, 1>; - 0x49 => BLOBHASH => host_env::blob_hash:: => stack_io<1, 1>; - 0x4A => BLOBBASEFEE => host_env::blob_basefee:: => stack_io<0, 1>; + 0x30 => ADDRESS => system::address => stack_io(0, 1); + 0x31 => BALANCE => host::balance:: => stack_io(1, 1); + 0x32 => ORIGIN => host_env::origin => stack_io(0, 1); + 0x33 => CALLER => system::caller => stack_io(0, 1); + 0x34 => CALLVALUE => system::callvalue => stack_io(0, 1); + 0x35 => CALLDATALOAD => system::calldataload => stack_io(1, 1); + 0x36 => CALLDATASIZE => system::calldatasize => stack_io(0, 1); + 0x37 => CALLDATACOPY => system::calldatacopy => stack_io(3, 0); + 0x38 => CODESIZE => system::codesize => stack_io(0, 1), not_eof; + 0x39 => CODECOPY => system::codecopy => stack_io(3, 0), not_eof; + + 0x3A => GASPRICE => host_env::gasprice => stack_io(0, 1); + 0x3B => EXTCODESIZE => host::extcodesize:: => stack_io(1, 1), not_eof; + 0x3C => EXTCODECOPY => host::extcodecopy:: => stack_io(4, 0), not_eof; + 0x3D => RETURNDATASIZE => system::returndatasize:: => stack_io(0, 1); + 0x3E => RETURNDATACOPY => system::returndatacopy:: => stack_io(3, 0); + 0x3F => EXTCODEHASH => host::extcodehash:: => stack_io(1, 1), not_eof; + 0x40 => BLOCKHASH => host::blockhash => stack_io(1, 1); + 0x41 => COINBASE => host_env::coinbase => stack_io(0, 1); + 0x42 => TIMESTAMP => host_env::timestamp => stack_io(0, 1); + 0x43 => NUMBER => host_env::block_number => stack_io(0, 1); + 0x44 => DIFFICULTY => host_env::difficulty:: => stack_io(0, 1); + 0x45 => GASLIMIT => host_env::gaslimit => stack_io(0, 1); + 0x46 => CHAINID => host_env::chainid:: => stack_io(0, 1); + 0x47 => SELFBALANCE => host::selfbalance:: => stack_io(0, 1); + 0x48 => BASEFEE => host_env::basefee:: => stack_io(0, 1); + 0x49 => BLOBHASH => host_env::blob_hash:: => stack_io(1, 1); + 0x4A => BLOBBASEFEE => host_env::blob_basefee:: => stack_io(0, 1); // 0x4B // 0x4C // 0x4D // 0x4E // 0x4F - 0x50 => POP => stack::pop => stack_io<1, 0>; - 0x51 => MLOAD => memory::mload => stack_io<1, 1>; - 0x52 => MSTORE => memory::mstore => stack_io<2, 0>; - 0x53 => MSTORE8 => memory::mstore8 => stack_io<2, 0>; - 0x54 => SLOAD => host::sload:: => stack_io<1, 1>; - 0x55 => SSTORE => host::sstore:: => stack_io<2, 0>; - 0x56 => JUMP => control::jump => stack_io<1, 0>, not_eof; - 0x57 => JUMPI => control::jumpi => stack_io<2, 0>, not_eof; - 0x58 => PC => control::pc => stack_io<0, 1>, not_eof; - 0x59 => MSIZE => memory::msize => stack_io<0, 1>; - 0x5A => GAS => system::gas => stack_io<0, 1>, not_eof; - 0x5B => JUMPDEST => control::jumpdest_or_nop => stack_io<0, 0>; - 0x5C => TLOAD => host::tload:: => stack_io<1, 1>; - 0x5D => TSTORE => host::tstore:: => stack_io<2, 0>; - 0x5E => MCOPY => memory::mcopy:: => stack_io<3, 0>; - - 0x5F => PUSH0 => stack::push0:: => stack_io<0, 1>; - 0x60 => PUSH1 => stack::push::<1, H> => stack_io<0, 1>, imm_size<1>; - 0x61 => PUSH2 => stack::push::<2, H> => stack_io<0, 1>, imm_size<2>; - 0x62 => PUSH3 => stack::push::<3, H> => stack_io<0, 1>, imm_size<3>; - 0x63 => PUSH4 => stack::push::<4, H> => stack_io<0, 1>, imm_size<4>; - 0x64 => PUSH5 => stack::push::<5, H> => stack_io<0, 1>, imm_size<5>; - 0x65 => PUSH6 => stack::push::<6, H> => stack_io<0, 1>, imm_size<6>; - 0x66 => PUSH7 => stack::push::<7, H> => stack_io<0, 1>, imm_size<7>; - 0x67 => PUSH8 => stack::push::<8, H> => stack_io<0, 1>, imm_size<8>; - 0x68 => PUSH9 => stack::push::<9, H> => stack_io<0, 1>, imm_size<9>; - 0x69 => PUSH10 => stack::push::<10, H> => stack_io<0, 1>, imm_size<10>; - 0x6A => PUSH11 => stack::push::<11, H> => stack_io<0, 1>, imm_size<11>; - 0x6B => PUSH12 => stack::push::<12, H> => stack_io<0, 1>, imm_size<12>; - 0x6C => PUSH13 => stack::push::<13, H> => stack_io<0, 1>, imm_size<13>; - 0x6D => PUSH14 => stack::push::<14, H> => stack_io<0, 1>, imm_size<14>; - 0x6E => PUSH15 => stack::push::<15, H> => stack_io<0, 1>, imm_size<15>; - 0x6F => PUSH16 => stack::push::<16, H> => stack_io<0, 1>, imm_size<16>; - 0x70 => PUSH17 => stack::push::<17, H> => stack_io<0, 1>, imm_size<17>; - 0x71 => PUSH18 => stack::push::<18, H> => stack_io<0, 1>, imm_size<18>; - 0x72 => PUSH19 => stack::push::<19, H> => stack_io<0, 1>, imm_size<19>; - 0x73 => PUSH20 => stack::push::<20, H> => stack_io<0, 1>, imm_size<20>; - 0x74 => PUSH21 => stack::push::<21, H> => stack_io<0, 1>, imm_size<21>; - 0x75 => PUSH22 => stack::push::<22, H> => stack_io<0, 1>, imm_size<22>; - 0x76 => PUSH23 => stack::push::<23, H> => stack_io<0, 1>, imm_size<23>; - 0x77 => PUSH24 => stack::push::<24, H> => stack_io<0, 1>, imm_size<24>; - 0x78 => PUSH25 => stack::push::<25, H> => stack_io<0, 1>, imm_size<25>; - 0x79 => PUSH26 => stack::push::<26, H> => stack_io<0, 1>, imm_size<26>; - 0x7A => PUSH27 => stack::push::<27, H> => stack_io<0, 1>, imm_size<27>; - 0x7B => PUSH28 => stack::push::<28, H> => stack_io<0, 1>, imm_size<28>; - 0x7C => PUSH29 => stack::push::<29, H> => stack_io<0, 1>, imm_size<29>; - 0x7D => PUSH30 => stack::push::<30, H> => stack_io<0, 1>, imm_size<30>; - 0x7E => PUSH31 => stack::push::<31, H> => stack_io<0, 1>, imm_size<31>; - 0x7F => PUSH32 => stack::push::<32, H> => stack_io<0, 1>, imm_size<32>; - - 0x80 => DUP1 => stack::dup::<1, H> => stack_io<1, 2>; - 0x81 => DUP2 => stack::dup::<2, H> => stack_io<2, 3>; - 0x82 => DUP3 => stack::dup::<3, H> => stack_io<3, 4>; - 0x83 => DUP4 => stack::dup::<4, H> => stack_io<4, 5>; - 0x84 => DUP5 => stack::dup::<5, H> => stack_io<5, 6>; - 0x85 => DUP6 => stack::dup::<6, H> => stack_io<6, 7>; - 0x86 => DUP7 => stack::dup::<7, H> => stack_io<7, 8>; - 0x87 => DUP8 => stack::dup::<8, H> => stack_io<8, 9>; - 0x88 => DUP9 => stack::dup::<9, H> => stack_io<9, 10>; - 0x89 => DUP10 => stack::dup::<10, H> => stack_io<10, 11>; - 0x8A => DUP11 => stack::dup::<11, H> => stack_io<11, 12>; - 0x8B => DUP12 => stack::dup::<12, H> => stack_io<12, 13>; - 0x8C => DUP13 => stack::dup::<13, H> => stack_io<13, 14>; - 0x8D => DUP14 => stack::dup::<14, H> => stack_io<14, 15>; - 0x8E => DUP15 => stack::dup::<15, H> => stack_io<15, 16>; - 0x8F => DUP16 => stack::dup::<16, H> => stack_io<16, 17>; - - 0x90 => SWAP1 => stack::swap::<1, H> => stack_io<2, 2>; - 0x91 => SWAP2 => stack::swap::<2, H> => stack_io<3, 3>; - 0x92 => SWAP3 => stack::swap::<3, H> => stack_io<4, 4>; - 0x93 => SWAP4 => stack::swap::<4, H> => stack_io<5, 5>; - 0x94 => SWAP5 => stack::swap::<5, H> => stack_io<6, 6>; - 0x95 => SWAP6 => stack::swap::<6, H> => stack_io<7, 7>; - 0x96 => SWAP7 => stack::swap::<7, H> => stack_io<8, 8>; - 0x97 => SWAP8 => stack::swap::<8, H> => stack_io<9, 9>; - 0x98 => SWAP9 => stack::swap::<9, H> => stack_io<10, 10>; - 0x99 => SWAP10 => stack::swap::<10, H> => stack_io<11, 11>; - 0x9A => SWAP11 => stack::swap::<11, H> => stack_io<12, 12>; - 0x9B => SWAP12 => stack::swap::<12, H> => stack_io<13, 13>; - 0x9C => SWAP13 => stack::swap::<13, H> => stack_io<14, 14>; - 0x9D => SWAP14 => stack::swap::<14, H> => stack_io<15, 15>; - 0x9E => SWAP15 => stack::swap::<15, H> => stack_io<16, 16>; - 0x9F => SWAP16 => stack::swap::<16, H> => stack_io<17, 17>; - - 0xA0 => LOG0 => host::log::<0, H> => stack_io<2, 0>; - 0xA1 => LOG1 => host::log::<1, H> => stack_io<3, 0>; - 0xA2 => LOG2 => host::log::<2, H> => stack_io<4, 0>; - 0xA3 => LOG3 => host::log::<3, H> => stack_io<5, 0>; - 0xA4 => LOG4 => host::log::<4, H> => stack_io<6, 0>; + 0x50 => POP => stack::pop => stack_io(1, 0); + 0x51 => MLOAD => memory::mload => stack_io(1, 1); + 0x52 => MSTORE => memory::mstore => stack_io(2, 0); + 0x53 => MSTORE8 => memory::mstore8 => stack_io(2, 0); + 0x54 => SLOAD => host::sload:: => stack_io(1, 1); + 0x55 => SSTORE => host::sstore:: => stack_io(2, 0); + 0x56 => JUMP => control::jump => stack_io(1, 0), not_eof; + 0x57 => JUMPI => control::jumpi => stack_io(2, 0), not_eof; + 0x58 => PC => control::pc => stack_io(0, 1), not_eof; + 0x59 => MSIZE => memory::msize => stack_io(0, 1); + 0x5A => GAS => system::gas => stack_io(0, 1), not_eof; + 0x5B => JUMPDEST => control::jumpdest_or_nop => stack_io(0, 0); + 0x5C => TLOAD => host::tload:: => stack_io(1, 1); + 0x5D => TSTORE => host::tstore:: => stack_io(2, 0); + 0x5E => MCOPY => memory::mcopy:: => stack_io(3, 0); + + 0x5F => PUSH0 => stack::push0:: => stack_io(0, 1); + 0x60 => PUSH1 => stack::push::<1, H> => stack_io(0, 1), immediate_size(1); + 0x61 => PUSH2 => stack::push::<2, H> => stack_io(0, 1), immediate_size(2); + 0x62 => PUSH3 => stack::push::<3, H> => stack_io(0, 1), immediate_size(3); + 0x63 => PUSH4 => stack::push::<4, H> => stack_io(0, 1), immediate_size(4); + 0x64 => PUSH5 => stack::push::<5, H> => stack_io(0, 1), immediate_size(5); + 0x65 => PUSH6 => stack::push::<6, H> => stack_io(0, 1), immediate_size(6); + 0x66 => PUSH7 => stack::push::<7, H> => stack_io(0, 1), immediate_size(7); + 0x67 => PUSH8 => stack::push::<8, H> => stack_io(0, 1), immediate_size(8); + 0x68 => PUSH9 => stack::push::<9, H> => stack_io(0, 1), immediate_size(9); + 0x69 => PUSH10 => stack::push::<10, H> => stack_io(0, 1), immediate_size(10); + 0x6A => PUSH11 => stack::push::<11, H> => stack_io(0, 1), immediate_size(11); + 0x6B => PUSH12 => stack::push::<12, H> => stack_io(0, 1), immediate_size(12); + 0x6C => PUSH13 => stack::push::<13, H> => stack_io(0, 1), immediate_size(13); + 0x6D => PUSH14 => stack::push::<14, H> => stack_io(0, 1), immediate_size(14); + 0x6E => PUSH15 => stack::push::<15, H> => stack_io(0, 1), immediate_size(15); + 0x6F => PUSH16 => stack::push::<16, H> => stack_io(0, 1), immediate_size(16); + 0x70 => PUSH17 => stack::push::<17, H> => stack_io(0, 1), immediate_size(17); + 0x71 => PUSH18 => stack::push::<18, H> => stack_io(0, 1), immediate_size(18); + 0x72 => PUSH19 => stack::push::<19, H> => stack_io(0, 1), immediate_size(19); + 0x73 => PUSH20 => stack::push::<20, H> => stack_io(0, 1), immediate_size(20); + 0x74 => PUSH21 => stack::push::<21, H> => stack_io(0, 1), immediate_size(21); + 0x75 => PUSH22 => stack::push::<22, H> => stack_io(0, 1), immediate_size(22); + 0x76 => PUSH23 => stack::push::<23, H> => stack_io(0, 1), immediate_size(23); + 0x77 => PUSH24 => stack::push::<24, H> => stack_io(0, 1), immediate_size(24); + 0x78 => PUSH25 => stack::push::<25, H> => stack_io(0, 1), immediate_size(25); + 0x79 => PUSH26 => stack::push::<26, H> => stack_io(0, 1), immediate_size(26); + 0x7A => PUSH27 => stack::push::<27, H> => stack_io(0, 1), immediate_size(27); + 0x7B => PUSH28 => stack::push::<28, H> => stack_io(0, 1), immediate_size(28); + 0x7C => PUSH29 => stack::push::<29, H> => stack_io(0, 1), immediate_size(29); + 0x7D => PUSH30 => stack::push::<30, H> => stack_io(0, 1), immediate_size(30); + 0x7E => PUSH31 => stack::push::<31, H> => stack_io(0, 1), immediate_size(31); + 0x7F => PUSH32 => stack::push::<32, H> => stack_io(0, 1), immediate_size(32); + + 0x80 => DUP1 => stack::dup::<1, H> => stack_io(1, 2); + 0x81 => DUP2 => stack::dup::<2, H> => stack_io(2, 3); + 0x82 => DUP3 => stack::dup::<3, H> => stack_io(3, 4); + 0x83 => DUP4 => stack::dup::<4, H> => stack_io(4, 5); + 0x84 => DUP5 => stack::dup::<5, H> => stack_io(5, 6); + 0x85 => DUP6 => stack::dup::<6, H> => stack_io(6, 7); + 0x86 => DUP7 => stack::dup::<7, H> => stack_io(7, 8); + 0x87 => DUP8 => stack::dup::<8, H> => stack_io(8, 9); + 0x88 => DUP9 => stack::dup::<9, H> => stack_io(9, 10); + 0x89 => DUP10 => stack::dup::<10, H> => stack_io(10, 11); + 0x8A => DUP11 => stack::dup::<11, H> => stack_io(11, 12); + 0x8B => DUP12 => stack::dup::<12, H> => stack_io(12, 13); + 0x8C => DUP13 => stack::dup::<13, H> => stack_io(13, 14); + 0x8D => DUP14 => stack::dup::<14, H> => stack_io(14, 15); + 0x8E => DUP15 => stack::dup::<15, H> => stack_io(15, 16); + 0x8F => DUP16 => stack::dup::<16, H> => stack_io(16, 17); + + 0x90 => SWAP1 => stack::swap::<1, H> => stack_io(2, 2); + 0x91 => SWAP2 => stack::swap::<2, H> => stack_io(3, 3); + 0x92 => SWAP3 => stack::swap::<3, H> => stack_io(4, 4); + 0x93 => SWAP4 => stack::swap::<4, H> => stack_io(5, 5); + 0x94 => SWAP5 => stack::swap::<5, H> => stack_io(6, 6); + 0x95 => SWAP6 => stack::swap::<6, H> => stack_io(7, 7); + 0x96 => SWAP7 => stack::swap::<7, H> => stack_io(8, 8); + 0x97 => SWAP8 => stack::swap::<8, H> => stack_io(9, 9); + 0x98 => SWAP9 => stack::swap::<9, H> => stack_io(10, 10); + 0x99 => SWAP10 => stack::swap::<10, H> => stack_io(11, 11); + 0x9A => SWAP11 => stack::swap::<11, H> => stack_io(12, 12); + 0x9B => SWAP12 => stack::swap::<12, H> => stack_io(13, 13); + 0x9C => SWAP13 => stack::swap::<13, H> => stack_io(14, 14); + 0x9D => SWAP14 => stack::swap::<14, H> => stack_io(15, 15); + 0x9E => SWAP15 => stack::swap::<15, H> => stack_io(16, 16); + 0x9F => SWAP16 => stack::swap::<16, H> => stack_io(17, 17); + + 0xA0 => LOG0 => host::log::<0, H> => stack_io(2, 0); + 0xA1 => LOG1 => host::log::<1, H> => stack_io(3, 0); + 0xA2 => LOG2 => host::log::<2, H> => stack_io(4, 0); + 0xA3 => LOG3 => host::log::<3, H> => stack_io(5, 0); + 0xA4 => LOG4 => host::log::<4, H> => stack_io(6, 0); // 0xA5 // 0xA6 // 0xA7 @@ -591,10 +675,10 @@ opcodes! { // 0xCD // 0xCE // 0xCF - 0xD0 => DATALOAD => data::data_load => stack_io<1, 1>; - 0xD1 => DATALOADN => data::data_loadn => stack_io<0, 1>, imm_size<2>; - 0xD2 => DATASIZE => data::data_size => stack_io<0, 1>; - 0xD3 => DATACOPY => data::data_copy => stack_io<3, 0>; + 0xD0 => DATALOAD => data::data_load => stack_io(1, 1); + 0xD1 => DATALOADN => data::data_loadn => stack_io(0, 1), immediate_size(2); + 0xD2 => DATASIZE => data::data_size => stack_io(0, 1); + 0xD3 => DATACOPY => data::data_copy => stack_io(3, 0); // 0xD4 // 0xD5 // 0xD6 @@ -607,38 +691,38 @@ opcodes! { // 0xDD // 0xDE // 0xDF - 0xE0 => RJUMP => control::rjump => stack_io<0, 0>, imm_size<2>, terminating; - 0xE1 => RJUMPI => control::rjumpi => stack_io<1, 0>, imm_size<2>; - 0xE2 => RJUMPV => control::rjumpv => stack_io<1, 0>, imm_size<1>; - 0xE3 => CALLF => control::callf => stack_io<0, 0>, imm_size<2>; - 0xE4 => RETF => control::retf => stack_io<0, 0>, terminating; - 0xE5 => JUMPF => control::jumpf => stack_io<0, 0>, imm_size<2>, terminating; - 0xE6 => DUPN => stack::dupn => stack_io<0, 1>, imm_size<1>; - 0xE7 => SWAPN => stack::swapn => stack_io<0, 0>, imm_size<1>; - 0xE8 => EXCHANGE => stack::exchange => stack_io<0, 0>, imm_size<1>; + 0xE0 => RJUMP => control::rjump => stack_io(0, 0), immediate_size(2), terminating; + 0xE1 => RJUMPI => control::rjumpi => stack_io(1, 0), immediate_size(2); + 0xE2 => RJUMPV => control::rjumpv => stack_io(1, 0), immediate_size(1); + 0xE3 => CALLF => control::callf => stack_io(0, 0), immediate_size(2); + 0xE4 => RETF => control::retf => stack_io(0, 0), terminating; + 0xE5 => JUMPF => control::jumpf => stack_io(0, 0), immediate_size(2), terminating; + 0xE6 => DUPN => stack::dupn => stack_io(0, 1), immediate_size(1); + 0xE7 => SWAPN => stack::swapn => stack_io(0, 0), immediate_size(1); + 0xE8 => EXCHANGE => stack::exchange => stack_io(0, 0), immediate_size(1); // 0xE9 // 0xEA // 0xEB - 0xEC => EOFCREATE => contract::eofcreate:: => stack_io<4, 1>, imm_size<1>; - 0xED => TXCREATE => contract::txcreate:: => stack_io<5, 1>; - 0xEE => RETURNCONTRACT => contract::return_contract:: => stack_io<2, 0>, imm_size<1>, terminating; + 0xEC => EOFCREATE => contract::eofcreate => stack_io(4, 1), immediate_size(1); + 0xED => TXCREATE => contract::txcreate => stack_io(5, 1); + 0xEE => RETURNCONTRACT => contract::return_contract => stack_io(2, 0), immediate_size(1), terminating; // 0xEF - 0xF0 => CREATE => contract::create:: => stack_io<3, 1>, not_eof; - 0xF1 => CALL => contract::call:: => stack_io<7, 1>, not_eof; - 0xF2 => CALLCODE => contract::call_code:: => stack_io<7, 1>, not_eof; - 0xF3 => RETURN => control::ret => stack_io<2, 0>, terminating; - 0xF4 => DELEGATECALL => contract::delegate_call:: => stack_io<6, 1>, not_eof; - 0xF5 => CREATE2 => contract::create:: => stack_io<4, 1>, not_eof; + 0xF0 => CREATE => contract::create:: => stack_io(3, 1), not_eof; + 0xF1 => CALL => contract::call:: => stack_io(7, 1), not_eof; + 0xF2 => CALLCODE => contract::call_code:: => stack_io(7, 1), not_eof; + 0xF3 => RETURN => control::ret => stack_io(2, 0), terminating; + 0xF4 => DELEGATECALL => contract::delegate_call:: => stack_io(6, 1), not_eof; + 0xF5 => CREATE2 => contract::create:: => stack_io(4, 1), not_eof; // 0xF6 - 0xF7 => RETURNDATALOAD => system::returndataload:: => stack_io<1, 1>; - 0xF8 => EXTCALL => contract::extcall:: => stack_io<4, 1>; - 0xF9 => EXFCALL => contract::extdcall:: => stack_io<3, 1>; - 0xFA => STATICCALL => contract::static_call:: => stack_io<6, 1>, not_eof; - 0xFB => EXTSCALL => contract::extscall:: => stack_io<3, 1>; + 0xF7 => RETURNDATALOAD => system::returndataload => stack_io(1, 1); + 0xF8 => EXTCALL => contract::extcall:: => stack_io(4, 1); + 0xF9 => EXFCALL => contract::extdcall:: => stack_io(3, 1); + 0xFA => STATICCALL => contract::static_call:: => stack_io(6, 1), not_eof; + 0xFB => EXTSCALL => contract::extscall => stack_io(3, 1); // 0xFC - 0xFD => REVERT => control::revert:: => stack_io<2, 0>, terminating; - 0xFE => INVALID => control::invalid => stack_io<0, 0>, terminating; - 0xFF => SELFDESTRUCT => host::selfdestruct:: => stack_io<1, 0>, not_eof, terminating; + 0xFD => REVERT => control::revert:: => stack_io(2, 0), terminating; + 0xFE => INVALID => control::invalid => stack_io(0, 0), terminating; + 0xFF => SELFDESTRUCT => host::selfdestruct:: => stack_io(1, 0), not_eof, terminating; } #[cfg(test)] @@ -655,34 +739,49 @@ mod tests { assert_eq!(opcode.get(), 0x00); } - const REJECTED_IN_EOF: &[u8] = &[ - 0x38, 0x39, 0x3b, 0x3c, 0x3f, 0x5a, 0xf1, 0xf2, 0xf4, 0xfa, 0xff, - ]; - #[test] fn test_eof_disable() { - for opcode in REJECTED_IN_EOF.iter() { + const REJECTED_IN_EOF: &[u8] = &[ + 0x38, 0x39, 0x3b, 0x3c, 0x3f, 0x5a, 0xf1, 0xf2, 0xf4, 0xfa, 0xff, + ]; + + for opcode in REJECTED_IN_EOF { let opcode = OpCode::new(*opcode).unwrap(); - assert!(!opcode.info().is_eof, "Opcode {:?} is not EOF", opcode); + assert!( + opcode.info().is_disabled_in_eof(), + "not disabled in EOF: {opcode:#?}", + ); } } #[test] - fn test_imm_size() { - let mut opcodes = [0u8; 256]; + fn test_immediate_size() { + let mut expected = [0u8; 256]; // PUSH opcodes - for push in PUSH1..PUSH32 { - opcodes[push as usize] = push - PUSH1 + 1; + for push in PUSH1..=PUSH32 { + expected[push as usize] = push - PUSH1 + 1; + } + expected[DATALOADN as usize] = 2; + expected[RJUMP as usize] = 2; + expected[RJUMPI as usize] = 2; + expected[RJUMPV as usize] = 1; + expected[CALLF as usize] = 2; + expected[JUMPF as usize] = 2; + expected[DUPN as usize] = 1; + expected[SWAPN as usize] = 1; + expected[EXCHANGE as usize] = 1; + expected[EOFCREATE as usize] = 1; + expected[RETURNCONTRACT as usize] = 1; + + for (i, opcode) in OPCODE_INFO_JUMPTABLE.iter().enumerate() { + if let Some(opcode) = opcode { + assert_eq!( + opcode.immediate_size(), + expected[i], + "immediate_size check failed for {opcode:#?}", + ); + } } - opcodes[DATALOADN as usize] = 2; - opcodes[RJUMP as usize] = 2; - opcodes[RJUMPI as usize] = 2; - opcodes[RJUMPV as usize] = 2; - opcodes[CALLF as usize] = 2; - opcodes[JUMPF as usize] = 2; - opcodes[DUPN as usize] = 1; - opcodes[SWAPN as usize] = 1; - opcodes[EXCHANGE as usize] = 1; } #[test] @@ -733,9 +832,7 @@ mod tests { for (i, opcode) in OPCODE_INFO_JUMPTABLE.into_iter().enumerate() { assert_eq!( - opcode - .map(|opcode| opcode.is_terminating_opcode) - .unwrap_or_default(), + opcode.map(|opcode| opcode.terminating).unwrap_or_default(), opcodes[i], "Opcode {:?} terminating chack failed.", opcode diff --git a/crates/interpreter/src/opcode/eof_printer.rs b/crates/interpreter/src/opcode/eof_printer.rs index d593d9a7..dc226882 100644 --- a/crates/interpreter/src/opcode/eof_printer.rs +++ b/crates/interpreter/src/opcode/eof_printer.rs @@ -16,19 +16,19 @@ pub fn print_eof_code(code: &[u8]) { continue; }; - if opcode.immediate_size != 0 { + if opcode.immediate_size() != 0 { // check if the opcode immediate are within the bounds of the code - if i + opcode.immediate_size as usize >= code.len() { + if i + opcode.immediate_size() as usize >= code.len() { println!("Malformed code: immediate out of bounds"); break; } } - print!("{}", opcode.name); - if opcode.immediate_size != 0 { + print!("{}", opcode.name()); + if opcode.immediate_size() != 0 { print!( " : 0x{:}", - hex::encode(&code[i + 1..i + 1 + opcode.immediate_size as usize]) + hex::encode(&code[i + 1..i + 1 + opcode.immediate_size() as usize]) ); } @@ -51,7 +51,7 @@ pub fn print_eof_code(code: &[u8]) { } } - i += 1 + opcode.immediate_size as usize + rjumpv_additional_immediates; + i += 1 + opcode.immediate_size() as usize + rjumpv_additional_immediates; } } diff --git a/crates/primitives/src/bytecode/eof/types_section.rs b/crates/primitives/src/bytecode/eof/types_section.rs index 84db61f0..7695dc97 100644 --- a/crates/primitives/src/bytecode/eof/types_section.rs +++ b/crates/primitives/src/bytecode/eof/types_section.rs @@ -20,9 +20,9 @@ pub struct TypesSection { } impl TypesSection { - /// Return the difference between inputs and outputs. + /// Calculates the difference between the number of input and output stack elements. #[inline] - pub fn io_diff(&self) -> i32 { + pub const fn io_diff(&self) -> i32 { self.outputs as i32 - self.inputs as i32 } diff --git a/crates/revm/src/inspector/eip3155.rs b/crates/revm/src/inspector/eip3155.rs index cbc4b817..b5331157 100644 --- a/crates/revm/src/inspector/eip3155.rs +++ b/crates/revm/src/inspector/eip3155.rs @@ -222,7 +222,7 @@ impl Inspector for TracerEip3155 { refund: hex_number(self.refunded as u64), mem_size: self.mem_size.to_string(), - op_name: OpCode::new(self.opcode).map(|i| i.info().name), + op_name: OpCode::new(self.opcode).map(|i| i.as_str()), error: if !interp.instruction_result.is_ok() { Some(format!("{:?}", interp.instruction_result)) } else { From 9165a4a5eaa2260acc16812e54658964a798447e Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 29 Apr 2024 12:54:55 +0200 Subject: [PATCH 035/105] chore: don't clone bytes in `Bytecode::bytes` (#1344) --- crates/interpreter/src/interpreter.rs | 2 +- crates/primitives/src/bytecode.rs | 10 +++++----- crates/primitives/src/bytecode/legacy.rs | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index 1d415772..18921a68 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -87,7 +87,7 @@ impl Interpreter { panic!("Contract is not execution ready {:?}", contract.bytecode); } let is_eof = contract.bytecode.is_eof(); - let bytecode = contract.bytecode.bytecode_bytes(); + let bytecode = contract.bytecode.bytecode().clone(); Self { instruction_pointer: bytecode.as_ptr(), bytecode, diff --git a/crates/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index 6236c3ea..2e446726 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -91,17 +91,17 @@ impl Bytecode { } /// Returns a reference to the bytecode. + /// /// In case of EOF this will be the first code section. #[inline] - pub fn bytecode_bytes(&self) -> Bytes { + pub fn bytecode(&self) -> &Bytes { match self { - Self::LegacyRaw(bytes) => bytes.clone(), - Self::LegacyAnalyzed(analyzed) => analyzed.bytes(), + Self::LegacyRaw(bytes) => bytes, + Self::LegacyAnalyzed(analyzed) => analyzed.bytecode(), Self::Eof(eof) => eof .body .code(0) - .expect("Valid EOF has at least one code section") - .clone(), + .expect("Valid EOF has at least one code section"), } } diff --git a/crates/primitives/src/bytecode/legacy.rs b/crates/primitives/src/bytecode/legacy.rs index 3e6f2d2b..2a44fefd 100644 --- a/crates/primitives/src/bytecode/legacy.rs +++ b/crates/primitives/src/bytecode/legacy.rs @@ -39,11 +39,11 @@ impl LegacyAnalyzedBytecode { } } - /// Returns bytes of bytecode. + /// Returns a reference to the bytecode. /// - /// Bytes are padded with 32 zero bytes. - pub fn bytes(&self) -> Bytes { - self.bytecode.clone() + /// The bytecode is padded with 32 zero bytes. + pub fn bytecode(&self) -> &Bytes { + &self.bytecode } /// Original bytes length. From 9ec2248ecc24b6726619b1d130c5392dabf8102a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:16:37 +0200 Subject: [PATCH 036/105] chore(deps): bump aurora-engine-modexp from 1.0.0 to 1.1.0 (#1339) Bumps [aurora-engine-modexp](https://github.com/aurora-is-near/aurora-engine) from 1.0.0 to 1.1.0. - [Release notes](https://github.com/aurora-is-near/aurora-engine/releases) - [Changelog](https://github.com/aurora-is-near/aurora-engine/blob/develop/CHANGES.md) - [Commits](https://github.com/aurora-is-near/aurora-engine/compare/1.0.0...1.1.0) --- updated-dependencies: - dependency-name: aurora-engine-modexp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- crates/precompile/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7dcdf72..a51b8d54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -552,9 +552,9 @@ dependencies = [ [[package]] name = "aurora-engine-modexp" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfacad86e9e138fca0670949eb8ed4ffdf73a55bded8887efe0863cd1a3a6f70" +checksum = "0aef7712851e524f35fbbb74fa6599c5cd8692056a1c36f9ca0d2001b670e7e5" dependencies = [ "hex", "num", diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index 3d1c8e71..a9893a82 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -19,7 +19,7 @@ once_cell = { version = "1.19", default-features = false, features = ["alloc"] } ripemd = { version = "0.1", default-features = false } sha2 = { version = "0.10", default-features = false } # modexp precompile -aurora-engine-modexp = { version = "1.0", default-features = false } +aurora-engine-modexp = { version = "1.1", default-features = false } # Optional KZG point evaluation precompile c-kzg = { version = "1.0.0", default-features = false, optional = true } From 215a4c4de5da84a606385224d850ae31477b62b0 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:35:45 +0200 Subject: [PATCH 037/105] fix: return the correct error in resize_memory (#1359) --- crates/interpreter/src/instructions/macros.rs | 2 +- crates/revm/src/builder.rs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index 214a6c79..a2b7f37c 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -106,7 +106,7 @@ macro_rules! resize_memory { .gas .record_memory($crate::gas::memory_gas(words_num)) { - $interp.instruction_result = $crate::InstructionResult::MemoryLimitOOG; + $interp.instruction_result = $crate::InstructionResult::MemoryOOG; return $ret; } $interp.shared_memory.resize(rounded_size); diff --git a/crates/revm/src/builder.rs b/crates/revm/src/builder.rs index 1b8d8279..5508fa9c 100644 --- a/crates/revm/src/builder.rs +++ b/crates/revm/src/builder.rs @@ -448,7 +448,7 @@ mod test { }, Context, ContextPrecompile, ContextStatefulPrecompile, Evm, InMemoryDB, InnerEvmContext, }; - use revm_interpreter::{Host, Interpreter}; + use revm_interpreter::{gas, Host, Interpreter}; use std::{cell::RefCell, rc::Rc, sync::Arc}; /// Custom evm context @@ -511,9 +511,10 @@ mod test { const CUSTOM_INSTRUCTION_COST: u64 = 133; const INITIAL_TX_GAS: u64 = 21000; const EXPECTED_RESULT_GAS: u64 = INITIAL_TX_GAS + CUSTOM_INSTRUCTION_COST; + fn custom_instruction(interp: &mut Interpreter, _host: &mut impl Host) { // just spend some gas - interp.gas.record_cost(CUSTOM_INSTRUCTION_COST); + gas!(interp, CUSTOM_INSTRUCTION_COST); } let code = Bytecode::new_raw([0xEF, 0x00].into()); From f59ce8c5a65870564fea08f87c24e6a809e36b60 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:36:10 +0200 Subject: [PATCH 038/105] feat(interpreter): add helpers for spending all gas (#1360) --- crates/interpreter/src/gas.rs | 19 +++++++++++++++++++ crates/revm/src/handler/mainnet/execution.rs | 3 +-- crates/revm/src/inspector/gas.rs | 10 ++-------- crates/revm/src/optimism/handler_register.rs | 3 +-- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/crates/interpreter/src/gas.rs b/crates/interpreter/src/gas.rs index 387f4737..5d1b5d75 100644 --- a/crates/interpreter/src/gas.rs +++ b/crates/interpreter/src/gas.rs @@ -35,6 +35,18 @@ impl Gas { } } + /// Creates a new `Gas` struct with the given gas limit, but without any gas remaining. + #[inline] + pub const fn new_spent(limit: u64) -> Self { + Self { + limit, + remaining: 0, + remaining_nomem: 0, + memory: 0, + refunded: 0, + } + } + /// Returns the gas limit. #[inline] pub const fn limit(&self) -> u64 { @@ -79,6 +91,13 @@ impl Gas { self.remaining += returned; } + /// Spends all remaining gas. + #[inline] + pub fn spend_all(&mut self) { + self.remaining = 0; + self.remaining_nomem = 0; + } + /// Records a refund value. /// /// `refund` can be negative but `self.refunded` should always be positive diff --git a/crates/revm/src/handler/mainnet/execution.rs b/crates/revm/src/handler/mainnet/execution.rs index c4985b54..852dab37 100644 --- a/crates/revm/src/handler/mainnet/execution.rs +++ b/crates/revm/src/handler/mainnet/execution.rs @@ -24,8 +24,7 @@ pub fn frame_return_with_refund_flag( let refunded = gas.refunded(); // Spend the gas limit. Gas is reimbursed when the tx returns successfully. - *gas = Gas::new(env.tx.gas_limit); - gas.record_cost(env.tx.gas_limit); + *gas = Gas::new_spent(env.tx.gas_limit); match instruction_result { return_ok!() => { diff --git a/crates/revm/src/inspector/gas.rs b/crates/revm/src/inspector/gas.rs index dc98bcaa..7542c3d3 100644 --- a/crates/revm/src/inspector/gas.rs +++ b/crates/revm/src/inspector/gas.rs @@ -60,10 +60,7 @@ impl Inspector for GasInspector { mut outcome: CallOutcome, ) -> CallOutcome { if outcome.result.result.is_error() { - outcome - .result - .gas - .record_cost(outcome.result.gas.remaining()); + outcome.result.gas.spend_all(); self.gas_remaining = 0; } outcome @@ -76,10 +73,7 @@ impl Inspector for GasInspector { mut outcome: CreateOutcome, ) -> CreateOutcome { if outcome.result.result.is_error() { - outcome - .result - .gas - .record_cost(outcome.result.gas.remaining()); + outcome.result.gas.spend_all(); self.gas_remaining = 0; } outcome diff --git a/crates/revm/src/optimism/handler_register.rs b/crates/revm/src/optimism/handler_register.rs index 600d6709..0d3bcf40 100644 --- a/crates/revm/src/optimism/handler_register.rs +++ b/crates/revm/src/optimism/handler_register.rs @@ -82,8 +82,7 @@ pub fn last_frame_return( let remaining = gas.remaining(); let refunded = gas.refunded(); // Spend the gas limit. Gas is reimbursed when the tx returns successfully. - *gas = Gas::new(tx_gas_limit); - gas.record_cost(tx_gas_limit); + *gas = Gas::new_spent(tx_gas_limit); match instruction_result { return_ok!() => { From ac3fa4f75e05c74a3619d805b27766c02a8c1a84 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:39:30 +0200 Subject: [PATCH 039/105] perf: remove bounds check in DUP, SWAP/EXCHANGE (#1346) * perf: remove bounds check in DUP * perf: use `mem::swap` in stack swap/exchange * docs: is_static doc driveby * chore: use swap_nonoverlapping * chore: restore Cargo.toml --- crates/interpreter/src/interpreter/stack.rs | 48 +++++++++++++------ .../src/interpreter_action/call_inputs.rs | 2 +- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/crates/interpreter/src/interpreter/stack.rs b/crates/interpreter/src/interpreter/stack.rs index 44dbb48a..28b0baf3 100644 --- a/crates/interpreter/src/interpreter/stack.rs +++ b/crates/interpreter/src/interpreter/stack.rs @@ -2,7 +2,7 @@ use crate::{ primitives::{B256, U256}, InstructionResult, }; -use core::fmt; +use core::{fmt, ptr}; use std::vec::Vec; /// EVM interpreter stack limit. @@ -222,8 +222,14 @@ impl Stack { } /// Duplicates the `N`th value from the top of the stack. + /// + /// # Panics + /// + /// Panics if `n` is 0. #[inline] + #[cfg_attr(debug_assertions, track_caller)] pub fn dup(&mut self, n: usize) -> Result<(), InstructionResult> { + assume!(n > 0, "attempted to dup 0"); let len = self.data.len(); if len < n { Err(InstructionResult::StackUnderflow) @@ -232,36 +238,50 @@ impl Stack { } else { // SAFETY: check for out of bounds is done above and it makes this safe to do. unsafe { + let ptr = self.data.as_mut_ptr().add(len); + ptr::copy_nonoverlapping(ptr.sub(n), ptr, 1); self.data.set_len(len + 1); } - self.data[len] = self.data[len - n]; Ok(()) } } /// Swaps the topmost value with the `N`th value from the top. - #[inline] + /// + /// # Panics + /// + /// Panics if `n` is 0. + #[inline(always)] + #[cfg_attr(debug_assertions, track_caller)] pub fn swap(&mut self, n: usize) -> Result<(), InstructionResult> { - let len = self.data.len(); - if n >= len { - return Err(InstructionResult::StackUnderflow); - } - let last_index = len - 1; - self.data.swap(last_index, last_index - n); - Ok(()) + self.exchange(0, n) } - /// Exchange two values on the stack. where `N` is first index and second index - /// is calculated as N+M + /// Exchange two values on the stack. + /// + /// `n` is the first index, and the second index is calculated as `n + m`. + /// + /// # Panics + /// + /// Panics if `m` is zero. #[inline] + #[cfg_attr(debug_assertions, track_caller)] pub fn exchange(&mut self, n: usize, m: usize) -> Result<(), InstructionResult> { + assume!(m > 0, "overlapping exchange"); let len = self.data.len(); let n_m_index = n + m; if n_m_index >= len { return Err(InstructionResult::StackUnderflow); } - let last_index = len - 1; - self.data.swap(last_index - n, last_index - n_m_index); + // SAFETY: `n` and `n_m` are checked to be within bounds, and they don't overlap. + unsafe { + // NOTE: `ptr::swap_nonoverlapping` is more efficient than `slice::swap` or `ptr::swap` + // because it operates under the assumption that the pointers do not overlap, + // eliminating an intemediate copy, + // which is a condition we know to be true in this context. + let top = self.data.as_mut_ptr().add(len - 1); + core::ptr::swap_nonoverlapping(top.sub(n), top.sub(n_m_index), 1); + } Ok(()) } diff --git a/crates/interpreter/src/interpreter_action/call_inputs.rs b/crates/interpreter/src/interpreter_action/call_inputs.rs index 196f7b1a..0e51bd5e 100644 --- a/crates/interpreter/src/interpreter_action/call_inputs.rs +++ b/crates/interpreter/src/interpreter_action/call_inputs.rs @@ -36,7 +36,7 @@ pub struct CallInputs { /// /// Previously `context.scheme`. pub scheme: CallScheme, - /// Whether the call is initiated inside a static call. + /// Whether the call is a static call, or is initiated inside a static call. pub is_static: bool, /// Whether the call is initiated from EOF bytecode. pub is_eof: bool, From 1f44e4c6da7ce57e8deffef35432d87441b93ee9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:39:54 +0200 Subject: [PATCH 040/105] chore(deps): bump hashbrown from 0.14.3 to 0.14.5 (#1365) Bumps [hashbrown](https://github.com/rust-lang/hashbrown) from 0.14.3 to 0.14.5. - [Changelog](https://github.com/rust-lang/hashbrown/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/hashbrown/compare/v0.14.3...v0.14.5) --- updated-dependencies: - dependency-name: hashbrown dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a51b8d54..aeac26d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1622,9 +1622,9 @@ checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", "allocator-api2", From 3f5bb7651a26c3562e6202fdbb5405b81407ccb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Urbanek?= Date: Mon, 29 Apr 2024 14:54:35 +0200 Subject: [PATCH 041/105] feat: Add uniswap V2 WETH-USDC swap example (#1353) * Add uniswap V2 WETH-USDC swap example * Use alloy primitives * Use revm primitives * Use alloydb * Use only necessary pair slots * typo * Simplify error handling * Improve numbers decoding * Dont use panic for errors * Remove unused feature * Use alloydb instead of manually fetching data --- Cargo.lock | 29 +++- crates/revm/Cargo.toml | 7 + examples/uniswap_v2_usdc_swap.rs | 278 +++++++++++++++++++++++++++++++ 3 files changed, 312 insertions(+), 2 deletions(-) create mode 100644 examples/uniswap_v2_usdc_swap.rs diff --git a/Cargo.lock b/Cargo.lock index aeac26d0..b86ba8d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1604,6 +1604,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "h2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 1.1.0", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "2.4.0" @@ -1778,7 +1797,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", + "h2 0.3.25", "http 0.2.12", "http-body 0.4.6", "httparse", @@ -1801,6 +1820,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", + "h2 0.4.4", "http 1.1.0", "http-body 1.0.0", "httparse", @@ -2780,7 +2800,7 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", + "h2 0.3.25", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", @@ -2818,8 +2838,10 @@ checksum = "2d66674f2b6fb864665eea7a3c1ac4e3dfacd2fda83cf6f935a612e01b0e3338" dependencies = [ "base64 0.21.7", "bytes", + "encoding_rs", "futures-core", "futures-util", + "h2 0.4.4", "http 1.1.0", "http-body 1.0.0", "http-body-util", @@ -2839,6 +2861,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper", + "system-configuration", "tokio", "tokio-native-tls", "tower-service", @@ -2855,6 +2878,7 @@ version = "8.0.0" dependencies = [ "alloy-provider", "alloy-rpc-types", + "alloy-sol-types", "alloy-transport", "alloy-transport-http", "anyhow", @@ -2866,6 +2890,7 @@ dependencies = [ "ethers-core", "ethers-providers", "indicatif", + "reqwest 0.12.2", "revm-interpreter", "revm-precompile", "serde", diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 8510a9ed..2a517a4a 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -46,10 +46,12 @@ alloy-rpc-types = {git = "https://github.com/alloy-rs/alloy.git", optional = tru alloy-transport = {git = "https://github.com/alloy-rs/alloy.git", optional = true, default-features = false } [dev-dependencies] +alloy-sol-types = { version = "0.7.0", default-features = false, features = ["std"] } ethers-contract = { version = "2.0.14", default-features = false } anyhow = "1.0.82" criterion = "0.5" indicatif = "0.17" +reqwest = { version = "0.12" } alloy-provider = { git = "https://github.com/alloy-rs/alloy.git", default-features = false, features = ["reqwest"] } # needed for enabling TLS to use HTTPS connections when testing alloy DB @@ -136,6 +138,11 @@ name = "db_by_ref" path = "../../examples/db_by_ref.rs" required-features = ["std", "serde-json"] +[[example]] +name = "uniswap_v2_usdc_swap" +path = "../../examples/uniswap_v2_usdc_swap.rs" +required-features = ["alloydb"] + [[bench]] name = "bench" path = "benches/bench.rs" diff --git a/examples/uniswap_v2_usdc_swap.rs b/examples/uniswap_v2_usdc_swap.rs new file mode 100644 index 00000000..9171da10 --- /dev/null +++ b/examples/uniswap_v2_usdc_swap.rs @@ -0,0 +1,278 @@ +use alloy_provider::{network::Ethereum, ProviderBuilder, RootProvider}; +use alloy_sol_types::{sol, SolCall, SolValue}; +use alloy_transport_http::Http; +use anyhow::{anyhow, Result}; +use reqwest::Client; +use revm::{ + db::{AlloyDB, CacheDB}, + primitives::{ + address, keccak256, AccountInfo, Address, Bytes, ExecutionResult, Output, TransactTo, U256, + }, + Evm, +}; +use std::ops::Div; +use std::sync::Arc; + +type AlloyCacheDB = CacheDB, Ethereum, Arc>>>>; + +#[tokio::main] +async fn main() -> Result<()> { + let client = ProviderBuilder::new() + .on_reqwest_http( + "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27" + .parse() + .unwrap(), + ) + .unwrap(); + let client = Arc::new(client); + let mut cache_db = CacheDB::new(AlloyDB::new(client, None)); + + // Random empty account + let account = address!("18B06aaF27d44B756FCF16Ca20C1f183EB49111f"); + + let weth = address!("c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"); + let usdc = address!("a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"); + let usdc_weth_pair = address!("B4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc"); + + let weth_balance_slot = U256::from(3); + + // give our test account some fake WETH and ETH + let one_ether = U256::from(1_000_000_000_000_000_000u128); + let hashed_acc_balance_slot = keccak256((account, weth_balance_slot).abi_encode()); + cache_db + .insert_account_storage(weth, hashed_acc_balance_slot.into(), one_ether) + .unwrap(); + + let acc_info = AccountInfo { + nonce: 0_u64, + balance: one_ether, + code_hash: keccak256(Bytes::new()), + code: None, + }; + cache_db.insert_account_info(account, acc_info); + + let acc_weth_balance_before = balance_of(weth, account, &mut cache_db)?; + println!("WETH balance before swap: {}", acc_weth_balance_before); + let acc_usdc_balance_before = balance_of(usdc, account, &mut cache_db)?; + println!("USDC balance before swap: {}", acc_usdc_balance_before); + + let (reserve0, reserve1) = get_reserves(usdc_weth_pair, &mut cache_db)?; + + let amount_in = one_ether.div(U256::from(10)); + + // calculate USDC amount out + let amount_out = get_amount_out(amount_in, reserve1, reserve0, &mut cache_db).await?; + + // transfer WETH to USDC-WETH pair + transfer(account, usdc_weth_pair, amount_in, weth, &mut cache_db)?; + + // execute low-level swap without using UniswapV2 router + swap( + account, + usdc_weth_pair, + account, + amount_out, + true, + &mut cache_db, + )?; + + let acc_weth_balance_after = balance_of(weth, account, &mut cache_db)?; + println!("WETH balance after swap: {}", acc_weth_balance_after); + let acc_usdc_balance_after = balance_of(usdc, account, &mut cache_db)?; + println!("USDC balance after swap: {}", acc_usdc_balance_after); + + Ok(()) +} + +fn balance_of(token: Address, address: Address, cache_db: &mut AlloyCacheDB) -> Result { + sol! { + function balanceOf(address account) public returns (uint256); + } + + let encoded = balanceOfCall { account: address }.abi_encode(); + + let mut evm = Evm::builder() + .with_db(cache_db) + .modify_tx_env(|tx| { + // 0x1 because calling USDC proxy from zero address fails + tx.caller = address!("0000000000000000000000000000000000000001"); + tx.transact_to = TransactTo::Call(token); + tx.data = encoded.into(); + tx.value = U256::from(0); + }) + .build(); + + let ref_tx = evm.transact().unwrap(); + let result = ref_tx.result; + + let value = match result { + ExecutionResult::Success { + output: Output::Call(value), + .. + } => value, + result => return Err(anyhow!("'balanceOf' execution failed: {result:?}")), + }; + + let balance = ::abi_decode(&value, false)?; + + Ok(balance) +} + +async fn get_amount_out( + amount_in: U256, + reserve_in: U256, + reserve_out: U256, + cache_db: &mut AlloyCacheDB, +) -> Result { + let uniswap_v2_router = address!("7a250d5630b4cf539739df2c5dacb4c659f2488d"); + sol! { + function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); + } + + let encoded = getAmountOutCall { + amountIn: amount_in, + reserveIn: reserve_in, + reserveOut: reserve_out, + } + .abi_encode(); + + let mut evm = Evm::builder() + .with_db(cache_db) + .modify_tx_env(|tx| { + tx.caller = address!("0000000000000000000000000000000000000000"); + tx.transact_to = TransactTo::Call(uniswap_v2_router); + tx.data = encoded.into(); + tx.value = U256::from(0); + }) + .build(); + + let ref_tx = evm.transact().unwrap(); + let result = ref_tx.result; + + let value = match result { + ExecutionResult::Success { + output: Output::Call(value), + .. + } => value, + result => return Err(anyhow!("'getAmountOut' execution failed: {result:?}")), + }; + + let amount_out = ::abi_decode(&value, false)?; + + Ok(amount_out) +} + +fn get_reserves(pair_address: Address, cache_db: &mut AlloyCacheDB) -> Result<(U256, U256)> { + sol! { + function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); + } + + let encoded = getReservesCall {}.abi_encode(); + + let mut evm = Evm::builder() + .with_db(cache_db) + .modify_tx_env(|tx| { + tx.caller = address!("0000000000000000000000000000000000000000"); + tx.transact_to = TransactTo::Call(pair_address); + tx.data = encoded.into(); + tx.value = U256::from(0); + }) + .build(); + + let ref_tx = evm.transact().unwrap(); + let result = ref_tx.result; + + let value = match result { + ExecutionResult::Success { + output: Output::Call(value), + .. + } => value, + result => return Err(anyhow!("'getReserves' execution failed: {result:?}")), + }; + + let (reserve0, reserve1, _) = <(U256, U256, u32)>::abi_decode(&value, false)?; + + Ok((reserve0, reserve1)) +} + +fn swap( + from: Address, + pool_address: Address, + target: Address, + amount_out: U256, + is_token0: bool, + cache_db: &mut AlloyCacheDB, +) -> Result<()> { + sol! { + function swap(uint amount0Out, uint amount1Out, address target, bytes callback) external; + } + + let amount0_out = if is_token0 { amount_out } else { U256::from(0) }; + let amount1_out = if is_token0 { U256::from(0) } else { amount_out }; + + let encoded = swapCall { + amount0Out: amount0_out, + amount1Out: amount1_out, + target, + callback: Bytes::new(), + } + .abi_encode(); + + let mut evm = Evm::builder() + .with_db(cache_db) + .modify_tx_env(|tx| { + tx.caller = from; + tx.transact_to = TransactTo::Call(pool_address); + tx.data = encoded.into(); + tx.value = U256::from(0); + }) + .build(); + + let ref_tx = evm.transact_commit().unwrap(); + + match ref_tx { + ExecutionResult::Success { .. } => {} + result => return Err(anyhow!("'swap' execution failed: {result:?}")), + }; + + Ok(()) +} + +fn transfer( + from: Address, + to: Address, + amount: U256, + token: Address, + cache_db: &mut AlloyCacheDB, +) -> Result<()> { + sol! { + function transfer(address to, uint amount) external returns (bool); + } + + let encoded = transferCall { to, amount }.abi_encode(); + + let mut evm = Evm::builder() + .with_db(cache_db) + .modify_tx_env(|tx| { + tx.caller = from; + tx.transact_to = TransactTo::Call(token); + tx.data = encoded.into(); + tx.value = U256::from(0); + }) + .build(); + + let ref_tx = evm.transact_commit().unwrap(); + let success: bool = match ref_tx { + ExecutionResult::Success { + output: Output::Call(value), + .. + } => ::abi_decode(&value, false)?, + result => return Err(anyhow!("'transfer' execution failed: {result:?}")), + }; + + if !success { + return Err(anyhow!("'transfer' failed")); + } + + Ok(()) +} From a2279f25236b8b670a285529fbd73f6372fd4ceb Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 29 Apr 2024 15:49:53 +0200 Subject: [PATCH 042/105] perf(interpreter): rewrite gas accounting for memory expansion (#1361) * feat(interpreter): add helpers for spending all gas * perf(interpreter): rewrite gas accounting for memory expansion * chore: do not inline * chore: restore Cargo.toml --- bins/revm-test/src/bin/snailtracer.rs | 2 +- crates/interpreter/src/gas.rs | 40 ++------- crates/interpreter/src/gas/calc.rs | 15 ++-- crates/interpreter/src/instructions/macros.rs | 22 ++--- crates/interpreter/src/interpreter.rs | 27 +++++- .../src/interpreter/shared_memory.rs | 83 ++++++++----------- crates/interpreter/src/lib.rs | 2 +- 7 files changed, 89 insertions(+), 102 deletions(-) diff --git a/bins/revm-test/src/bin/snailtracer.rs b/bins/revm-test/src/bin/snailtracer.rs index 7d1e217b..a931dc3a 100644 --- a/bins/revm-test/src/bin/snailtracer.rs +++ b/bins/revm-test/src/bin/snailtracer.rs @@ -19,7 +19,7 @@ pub fn simple_example() { }) .build(); - let _ = evm.transact(); + let _ = evm.transact().unwrap(); } fn main() { diff --git a/crates/interpreter/src/gas.rs b/crates/interpreter/src/gas.rs index 5d1b5d75..192dcc7b 100644 --- a/crates/interpreter/src/gas.rs +++ b/crates/interpreter/src/gas.rs @@ -14,10 +14,6 @@ pub struct Gas { limit: u64, /// The remaining gas. remaining: u64, - /// The remaining gas, without memory expansion. - remaining_nomem: u64, - /// The **last** memory expansion cost. - memory: u64, /// Refunded gas. This is used only at the end of execution. refunded: i64, } @@ -29,8 +25,6 @@ impl Gas { Self { limit, remaining: limit, - remaining_nomem: limit, - memory: 0, refunded: 0, } } @@ -41,8 +35,6 @@ impl Gas { Self { limit, remaining: 0, - remaining_nomem: 0, - memory: 0, refunded: 0, } } @@ -55,8 +47,11 @@ impl Gas { /// Returns the **last** memory expansion cost. #[inline] + #[deprecated = "memory expansion cost is not tracked anymore; \ + calculate it using `SharedMemory::current_expansion_cost` instead"] + #[doc(hidden)] pub const fn memory(&self) -> u64 { - self.memory + 0 } /// Returns the total amount of gas that was refunded. @@ -87,7 +82,6 @@ impl Gas { /// Erases a gas cost from the totals. #[inline] pub fn erase_cost(&mut self, returned: u64) { - self.remaining_nomem += returned; self.remaining += returned; } @@ -95,7 +89,6 @@ impl Gas { #[inline] pub fn spend_all(&mut self) { self.remaining = 0; - self.remaining_nomem = 0; } /// Records a refund value. @@ -128,30 +121,13 @@ impl Gas { /// /// Returns `false` if the gas limit is exceeded. #[inline] + #[must_use] pub fn record_cost(&mut self, cost: u64) -> bool { let (remaining, overflow) = self.remaining.overflowing_sub(cost); - if overflow { - return false; - } - - self.remaining_nomem -= cost; - self.remaining = remaining; - true - } - - /// Records memory expansion gas. - /// - /// Used in [`resize_memory!`](crate::resize_memory). - #[inline] - pub fn record_memory(&mut self, gas_memory: u64) -> bool { - if gas_memory > self.memory { - let (remaining, overflow) = self.remaining_nomem.overflowing_sub(gas_memory); - if overflow { - return false; - } - self.memory = gas_memory; + let success = !overflow; + if success { self.remaining = remaining; } - true + success } } diff --git a/crates/interpreter/src/gas/calc.rs b/crates/interpreter/src/gas/calc.rs index 18d0fd70..7337a991 100644 --- a/crates/interpreter/src/gas/calc.rs +++ b/crates/interpreter/src/gas/calc.rs @@ -342,13 +342,18 @@ pub const fn warm_cold_cost(is_cold: bool) -> u64 { } } -/// Memory expansion cost calculation. +/// Memory expansion cost calculation for a given memory length. #[inline] -pub const fn memory_gas(a: usize) -> u64 { - let a = a as u64; +pub const fn memory_gas_for_len(len: usize) -> u64 { + memory_gas(crate::interpreter::num_words(len as u64)) +} + +/// Memory expansion cost calculation for a given number of words. +#[inline] +pub const fn memory_gas(num_words: u64) -> u64 { MEMORY - .saturating_mul(a) - .saturating_add(a.saturating_mul(a) / 512) + .saturating_mul(num_words) + .saturating_add(num_words.saturating_mul(num_words) / 512) } /// Initial gas that is deducted for transaction to be included. diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index a2b7f37c..7a964fde 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -89,27 +89,23 @@ macro_rules! resize_memory { $crate::resize_memory!($interp, $offset, $len, ()) }; ($interp:expr, $offset:expr, $len:expr, $ret:expr) => { - let size = $offset.saturating_add($len); - if size > $interp.shared_memory.len() { - // We are fine with saturating to usize if size is close to MAX value. - let rounded_size = $crate::interpreter::next_multiple_of_32(size); - + let new_size = $offset.saturating_add($len); + if new_size > $interp.shared_memory.len() { #[cfg(feature = "memory_limit")] - if $interp.shared_memory.limit_reached(size) { + if $interp.shared_memory.limit_reached(new_size) { $interp.instruction_result = $crate::InstructionResult::MemoryLimitOOG; return $ret; } - // Gas is calculated in evm words (256 bits). - let words_num = rounded_size / 32; - if !$interp - .gas - .record_memory($crate::gas::memory_gas(words_num)) - { + // Note: we can't use `Interpreter` directly here because of potential double-borrows. + if !$crate::interpreter::resize_memory( + &mut $interp.shared_memory, + &mut $interp.gas, + new_size, + ) { $interp.instruction_result = $crate::InstructionResult::MemoryOOG; return $ret; } - $interp.shared_memory.resize(rounded_size); } }; } diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index 18921a68..3546e48d 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -6,12 +6,12 @@ mod shared_memory; mod stack; pub use contract::Contract; -pub use shared_memory::{next_multiple_of_32, SharedMemory, EMPTY_SHARED_MEMORY}; +pub use shared_memory::{num_words, SharedMemory, EMPTY_SHARED_MEMORY}; pub use stack::{Stack, STACK_LIMIT}; use crate::EOFCreateOutcome; use crate::{ - primitives::Bytes, push, push_b256, return_ok, return_revert, CallOutcome, CreateOutcome, + gas, primitives::Bytes, push, push_b256, return_ok, return_revert, CallOutcome, CreateOutcome, FunctionStack, Gas, Host, InstructionResult, InterpreterAction, }; use core::cmp::min; @@ -379,6 +379,13 @@ impl Interpreter { }, } } + + /// Resize the memory to the new size. Returns whether the gas was enough to resize the memory. + #[inline] + #[must_use] + pub fn resize_memory(&mut self, new_size: usize) -> bool { + resize_memory(&mut self.shared_memory, &mut self.gas, new_size) + } } impl InterpreterResult { @@ -401,6 +408,22 @@ impl InterpreterResult { } } +/// Resize the memory to the new size. Returns whether the gas was enough to resize the memory. +#[inline(never)] +#[cold] +#[must_use] +pub fn resize_memory(memory: &mut SharedMemory, gas: &mut Gas, new_size: usize) -> bool { + let new_words = num_words(new_size as u64); + let new_cost = gas::memory_gas(new_words); + let current_cost = memory.current_expansion_cost(); + let cost = new_cost - current_cost; + let success = gas.record_cost(cost); + if success { + memory.resize((new_words as usize) * 32); + } + success +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/interpreter/src/interpreter/shared_memory.rs b/crates/interpreter/src/interpreter/shared_memory.rs index 3ee25bf6..e76015a5 100644 --- a/crates/interpreter/src/interpreter/shared_memory.rs +++ b/crates/interpreter/src/interpreter/shared_memory.rs @@ -1,10 +1,5 @@ +use core::{cmp::min, fmt, ops::Range}; use revm_primitives::{B256, U256}; - -use core::{ - cmp::min, - fmt, - ops::{BitAnd, Not, Range}, -}; use std::vec::Vec; /// A sequential memory shared between calls, which uses @@ -128,6 +123,12 @@ impl SharedMemory { self.len() == 0 } + /// Returns the gas cost for the current memory expansion. + #[inline] + pub fn current_expansion_cost(&self) -> u64 { + crate::gas::memory_gas_for_len(self.len()) + } + /// Resizes the memory in-place so that `len` is equal to `new_len`. #[inline] pub fn resize(&mut self, new_size: usize) { @@ -145,21 +146,18 @@ impl SharedMemory { self.slice_range(offset..offset + size) } + /// Returns a byte slice of the memory region at the given offset. + /// + /// # Panics + /// + /// Panics on out of bounds. #[inline] #[cfg_attr(debug_assertions, track_caller)] - pub fn slice_range(&self, range: Range) -> &[u8] { - let last_checkpoint = self.last_checkpoint; - - self.buffer - .get(last_checkpoint + range.start..last_checkpoint + range.end) - .unwrap_or_else(|| { - debug_unreachable!( - "slice OOB: {}..{}; len: {}", - range.start, - range.end, - self.len() - ) - }) + pub fn slice_range(&self, range @ Range { start, end }: Range) -> &[u8] { + match self.context_memory().get(range) { + Some(slice) => slice, + None => debug_unreachable!("slice OOB: {start}..{end}; len: {}", self.len()), + } } /// Returns a byte slice of the memory region at the given offset. @@ -170,13 +168,11 @@ impl SharedMemory { #[inline] #[cfg_attr(debug_assertions, track_caller)] pub fn slice_mut(&mut self, offset: usize, size: usize) -> &mut [u8] { - let len = self.len(); let end = offset + size; - let last_checkpoint = self.last_checkpoint; - - self.buffer - .get_mut(last_checkpoint + offset..last_checkpoint + offset + size) - .unwrap_or_else(|| debug_unreachable!("slice OOB: {offset}..{end}; len: {}", len)) + match self.context_memory_mut().get_mut(offset..end) { + Some(slice) => slice, + None => debug_unreachable!("slice OOB: {offset}..{end}"), + } } /// Returns the byte at the given offset. @@ -312,12 +308,11 @@ impl SharedMemory { } } -/// Rounds up `x` to the closest multiple of 32. If `x % 32 == 0` then `x` is returned. Note, if `x` -/// is greater than `usize::MAX - 31` this will return `usize::MAX` which isn't a multiple of 32. +/// Returns number of words what would fit to provided number of bytes, +/// i.e. it rounds up the number bytes to number of words. #[inline] -pub fn next_multiple_of_32(x: usize) -> usize { - let r = x.bitand(31).not().wrapping_add(1).bitand(31); - x.saturating_add(r) +pub const fn num_words(len: u64) -> u64 { + len.saturating_add(31) / 32 } #[cfg(test)] @@ -325,24 +320,16 @@ mod tests { use super::*; #[test] - fn test_next_multiple_of_32() { - // next_multiple_of_32 returns x when it is a multiple of 32 - for i in 0..32 { - let x = i * 32; - assert_eq!(x, next_multiple_of_32(x)); - } - - // next_multiple_of_32 rounds up to the nearest multiple of 32 when `x % 32 != 0` - for x in 0..1024 { - if x % 32 == 0 { - continue; - } - let next_multiple = x + 32 - (x % 32); - assert_eq!(next_multiple, next_multiple_of_32(x)); - } - - // We expect large values to saturate and not overflow. - assert_eq!(usize::MAX, next_multiple_of_32(usize::MAX)); + fn test_num_words() { + assert_eq!(num_words(0), 0); + assert_eq!(num_words(1), 1); + assert_eq!(num_words(31), 1); + assert_eq!(num_words(32), 1); + assert_eq!(num_words(33), 2); + assert_eq!(num_words(63), 2); + assert_eq!(num_words(64), 2); + assert_eq!(num_words(65), 3); + assert_eq!(num_words(u64::MAX), u64::MAX / 32); } #[test] diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index 50507409..27df443b 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -34,7 +34,7 @@ pub use gas::Gas; pub use host::{DummyHost, Host, LoadAccountResult, SStoreResult, SelfDestructResult}; pub use instruction_result::*; pub use interpreter::{ - analysis, next_multiple_of_32, Contract, Interpreter, InterpreterResult, SharedMemory, Stack, + analysis, num_words, Contract, Interpreter, InterpreterResult, SharedMemory, Stack, EMPTY_SHARED_MEMORY, STACK_LIMIT, }; pub use interpreter_action::{ From 67c13f3daaba8620829d949b93fb0583d8f8fcd7 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Wed, 1 May 2024 08:47:22 +0200 Subject: [PATCH 043/105] feat: parse opcodes from strings (#1358) --- Cargo.lock | 50 +++++++++++++++++++++++ crates/interpreter/Cargo.toml | 10 ++++- crates/interpreter/src/opcode.rs | 69 +++++++++++++++++++++++++++++++- 3 files changed, 125 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b86ba8d2..8a57162c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2462,6 +2462,48 @@ dependencies = [ "rustc_version 0.4.0", ] +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project" version = "1.1.5" @@ -2903,6 +2945,8 @@ name = "revm-interpreter" version = "4.0.0" dependencies = [ "bincode", + "paste", + "phf", "revm-primitives", "serde", "serde_json", @@ -3438,6 +3482,12 @@ dependencies = [ "time", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" version = "0.4.9" diff --git a/crates/interpreter/Cargo.toml b/crates/interpreter/Cargo.toml index e9fe68cb..1b59e7d3 100644 --- a/crates/interpreter/Cargo.toml +++ b/crates/interpreter/Cargo.toml @@ -16,6 +16,11 @@ rustdoc-args = ["--cfg", "docsrs"] [dependencies] revm-primitives = { path = "../primitives", version = "3.1.1", default-features = false } +paste = { version = "1.0", optional = true } +phf = { version = "0.11", default-features = false, optional = true, features = [ + "macros", +] } + # optional serde = { version = "1.0", default-features = false, features = [ "derive", @@ -24,7 +29,7 @@ serde = { version = "1.0", default-features = false, features = [ [dev-dependencies] walkdir = "2.5" -serde_json = { version = "1.0"} +serde_json = "1.0" bincode = "1.3" [[test]] @@ -33,13 +38,14 @@ path = "tests/eof.rs" required-features = ["serde"] [features] -default = ["std"] +default = ["std", "parse"] std = ["serde?/std", "revm-primitives/std"] hashbrown = ["revm-primitives/hashbrown"] serde = ["dep:serde", "revm-primitives/serde"] arbitrary = ["std", "revm-primitives/arbitrary"] asm-keccak = ["revm-primitives/asm-keccak"] portable = ["revm-primitives/portable"] +parse = ["dep:paste", "dep:phf"] optimism = ["revm-primitives/optimism"] # Optimism default handler enabled Optimism handler register by default in EvmBuilder. diff --git a/crates/interpreter/src/opcode.rs b/crates/interpreter/src/opcode.rs index eb4ff273..725f8694 100644 --- a/crates/interpreter/src/opcode.rs +++ b/crates/interpreter/src/opcode.rs @@ -125,6 +125,21 @@ where core::array::from_fn(|i| outer(table[i])) } +/// An error indicating that an opcode is invalid. +#[derive(Debug, PartialEq, Eq)] +#[cfg(feature = "parse")] +pub struct OpCodeError(()); + +#[cfg(feature = "parse")] +impl fmt::Display for OpCodeError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("invalid opcode") + } +} + +#[cfg(all(feature = "std", feature = "parse"))] +impl std::error::Error for OpCodeError {} + /// An EVM opcode. /// /// This is always a valid opcode, as declared in the [`opcode`][self] module or the @@ -144,6 +159,16 @@ impl fmt::Display for OpCode { } } +#[cfg(feature = "parse")] +impl core::str::FromStr for OpCode { + type Err = OpCodeError; + + #[inline] + fn from_str(s: &str) -> Result { + Self::parse(s).ok_or(OpCodeError(())) + } +} + impl OpCode { /// Instantiate a new opcode from a u8. #[inline] @@ -154,6 +179,13 @@ impl OpCode { } } + /// Parses an opcode from a string. This is the inverse of [`as_str`](Self::as_str). + #[inline] + #[cfg(feature = "parse")] + pub fn parse(s: &str) -> Option { + NAME_TO_OPCODE.get(s).copied() + } + /// Returns true if the opcode is a jump destination. #[inline] pub const fn is_jumpdest(&self) -> bool { @@ -213,7 +245,7 @@ impl OpCode { Self(opcode) } - /// Returns the opcode as a string. + /// Returns the opcode as a string. This is the inverse of [`parse`](Self::parse). #[doc(alias = "name")] #[inline] pub const fn as_str(self) -> &'static str { @@ -416,6 +448,25 @@ pub const fn stack_io(mut op: OpCodeInfo, inputs: u8, outputs: u8) -> OpCodeInfo /// Alias for the [`JUMPDEST`] opcode. pub const NOP: u8 = JUMPDEST; +/// Callback for creating a [`phf`] map with `stringify_with_cb`. +#[cfg(feature = "parse")] +macro_rules! phf_map_cb { + ($(#[doc = $s:literal] $id:ident)*) => { + phf::phf_map! { + $($s => OpCode::$id),* + } + }; +} + +/// Stringifies identifiers with `paste` so that they are available as literals. +/// This doesn't work with `stringify!` because it cannot be expanded inside of another macro. +#[cfg(feature = "parse")] +macro_rules! stringify_with_cb { + ($callback:ident; $($id:ident)*) => { paste::paste! { + $callback! { $(#[doc = "" $id ""] $id)* } + }}; +} + macro_rules! opcodes { ($($val:literal => $name:ident => $f:expr => $($modifier:ident $(( $($modifier_arg:expr),* ))?),*);* $(;)?) => { // Constants for each opcode. This also takes care of duplicate names. @@ -428,7 +479,7 @@ macro_rules! opcodes { pub const $name: Self = Self($val); )*} - /// Maps each opcode to its name. + /// Maps each opcode to its info. pub const OPCODE_INFO_JUMPTABLE: [Option; 256] = { let mut map = [None; 256]; let mut prev: u8 = 0; @@ -446,6 +497,10 @@ macro_rules! opcodes { map }; + /// Maps each name to its opcode. + #[cfg(feature = "parse")] + static NAME_TO_OPCODE: phf::Map<&'static str, OpCode> = stringify_with_cb! { phf_map_cb; $($name)* }; + /// Returns the instruction function for the given opcode and spec. pub const fn instruction(opcode: u8) -> Instruction { match opcode { @@ -839,4 +894,14 @@ mod tests { ); } } + + #[test] + #[cfg(feature = "parse")] + fn test_parsing() { + for i in 0..=u8::MAX { + if let Some(op) = OpCode::new(i) { + assert_eq!(OpCode::parse(op.as_str()), Some(op)); + } + } + } } From aceb0939b1712faa0e8f45c1f5621c11b81df94e Mon Sep 17 00:00:00 2001 From: rakita Date: Wed, 1 May 2024 12:03:36 +0400 Subject: [PATCH 044/105] feat(Handler): Add ClearHandle (#1368) * fix(revme): Print one json outcome in statetest * feat(Handler): Add ClearHandle * nits * clippy --- crates/revm/src/evm.rs | 72 ++++++++++++------- .../handler/handle_types/post_execution.rs | 17 ++++- crates/revm/src/handler/mainnet.rs | 2 +- .../src/handler/mainnet/post_execution.rs | 8 +++ crates/revm/src/journaled_state.rs | 6 ++ documentation/src/crates/revm/handler.md | 5 +- 6 files changed, 80 insertions(+), 30 deletions(-) diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index 7c888d3d..25ff0d01 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -88,14 +88,14 @@ impl Evm<'_, EXT, DB> { /// has enough balance to pay for the gas. #[inline] pub fn preverify_transaction(&mut self) -> Result<(), EVMError> { - self.handler.validation().env(&self.context.evm.env)?; - self.handler - .validation() - .initial_tx_gas(&self.context.evm.env)?; - self.handler - .validation() - .tx_against_state(&mut self.context)?; - Ok(()) + let output = self.preverify_transaction_inner().map(|_| ()); + self.clear(); + output + } + + /// Calls clear handle of post execution to clear the state for next execution. + fn clear(&mut self) { + self.handler.post_execution().clear(&mut self.context); } /// Transact pre-verified transaction @@ -103,12 +103,48 @@ impl Evm<'_, EXT, DB> { /// This function will not validate the transaction. #[inline] pub fn transact_preverified(&mut self) -> EVMResult { + let initial_gas_spend = self + .handler + .validation() + .initial_tx_gas(&self.context.evm.env) + .map_err(|e| { + self.clear(); + e + })?; + let output = self.transact_preverified_inner(initial_gas_spend); + let output = self.handler.post_execution().end(&mut self.context, output); + self.clear(); + output + } + + /// Pre verify transaction inner. + #[inline] + fn preverify_transaction_inner(&mut self) -> Result> { + self.handler.validation().env(&self.context.evm.env)?; let initial_gas_spend = self .handler .validation() .initial_tx_gas(&self.context.evm.env)?; + self.handler + .validation() + .tx_against_state(&mut self.context)?; + Ok(initial_gas_spend) + } + + /// Transact transaction + /// + /// This function will validate the transaction. + #[inline] + pub fn transact(&mut self) -> EVMResult { + let initial_gas_spend = self.preverify_transaction_inner().map_err(|e| { + self.clear(); + e + })?; + let output = self.transact_preverified_inner(initial_gas_spend); - self.handler.post_execution().end(&mut self.context, output) + let output = self.handler.post_execution().end(&mut self.context, output); + self.clear(); + output } /// Returns the reference of handler configuration @@ -165,24 +201,6 @@ impl Evm<'_, EXT, DB> { &mut self.context.evm.env.block } - /// Transact transaction - /// - /// This function will validate the transaction. - #[inline] - pub fn transact(&mut self) -> EVMResult { - self.handler.validation().env(&self.context.evm.env)?; - let initial_gas_spend = self - .handler - .validation() - .initial_tx_gas(&self.context.evm.env)?; - self.handler - .validation() - .tx_against_state(&mut self.context)?; - - let output = self.transact_preverified_inner(initial_gas_spend); - self.handler.post_execution().end(&mut self.context, output) - } - /// Modify spec id, this will create new EVM that matches this spec id. pub fn modify_spec_id(&mut self, spec_id: SpecId) { self.handler.modify_spec_id(spec_id); diff --git a/crates/revm/src/handler/handle_types/post_execution.rs b/crates/revm/src/handler/handle_types/post_execution.rs index 393b321a..1b9e9fdc 100644 --- a/crates/revm/src/handler/handle_types/post_execution.rs +++ b/crates/revm/src/handler/handle_types/post_execution.rs @@ -35,6 +35,10 @@ pub type EndHandle<'a, EXT, DB> = Arc< + 'a, >; +/// Clear handle, doesn't have output, its purpose is to clear the +/// context. It will be always called even on failed validation. +pub type ClearHandle<'a, EXT, DB> = Arc) + 'a>; + /// Handles related to post execution after the stack loop is finished. pub struct PostExecutionHandler<'a, EXT, DB: Database> { /// Reimburse the caller with ethereum it didn't spent. @@ -43,8 +47,13 @@ pub struct PostExecutionHandler<'a, EXT, DB: Database> { pub reward_beneficiary: RewardBeneficiaryHandle<'a, EXT, DB>, /// Main return handle, returns the output of the transact. pub output: OutputHandle<'a, EXT, DB>, - /// End handle. + /// End handle. Called when execution ends. + /// End in comparison to output will be called every time after execution. + /// Output in case of error will not be called. pub end: EndHandle<'a, EXT, DB>, + /// Clear handle will be called always. In comparison to end that + /// is called only on execution end, clear handle is called even if validation fails. + pub clear: ClearHandle<'a, EXT, DB>, } impl<'a, EXT: 'a, DB: Database + 'a> PostExecutionHandler<'a, EXT, DB> { @@ -55,6 +64,7 @@ impl<'a, EXT: 'a, DB: Database + 'a> PostExecutionHandler<'a, EXT, DB> { reward_beneficiary: Arc::new(mainnet::reward_beneficiary::), output: Arc::new(mainnet::output::), end: Arc::new(mainnet::end::), + clear: Arc::new(mainnet::clear::), } } } @@ -94,4 +104,9 @@ impl<'a, EXT, DB: Database> PostExecutionHandler<'a, EXT, DB> { ) -> Result> { (self.end)(context, end_output) } + + /// Clean handler. + pub fn clear(&self, context: &mut Context) { + (self.clear)(context) + } } diff --git a/crates/revm/src/handler/mainnet.rs b/crates/revm/src/handler/mainnet.rs index f02a8167..3bf7da30 100644 --- a/crates/revm/src/handler/mainnet.rs +++ b/crates/revm/src/handler/mainnet.rs @@ -10,6 +10,6 @@ pub use execution::{ frame_return_with_refund_flag, insert_call_outcome, insert_create_outcome, insert_eofcreate_outcome, last_frame_return, }; -pub use post_execution::{end, output, reimburse_caller, reward_beneficiary}; +pub use post_execution::{clear, end, output, reimburse_caller, reward_beneficiary}; pub use pre_execution::{deduct_caller, deduct_caller_inner, load_accounts, load_precompiles}; pub use validation::{validate_env, validate_initial_tx_gas, validate_tx_against_state}; diff --git a/crates/revm/src/handler/mainnet/post_execution.rs b/crates/revm/src/handler/mainnet/post_execution.rs index 6230b882..bf732361 100644 --- a/crates/revm/src/handler/mainnet/post_execution.rs +++ b/crates/revm/src/handler/mainnet/post_execution.rs @@ -15,6 +15,14 @@ pub fn end( evm_output } +/// Clear handle clears error and journal state. +#[inline] +pub fn clear(context: &mut Context) { + // clear error and journaled state. + let _ = context.evm.take_error(); + context.evm.inner.journaled_state.clear(); +} + /// Reward beneficiary with gas fee. #[inline] pub fn reward_beneficiary( diff --git a/crates/revm/src/journaled_state.rs b/crates/revm/src/journaled_state.rs index 18899509..96a1c186 100644 --- a/crates/revm/src/journaled_state.rs +++ b/crates/revm/src/journaled_state.rs @@ -91,6 +91,12 @@ impl JournaledState { } } + /// Clears the JournaledState. Preserving only the spec. + pub fn clear(&mut self) { + let spec = self.spec; + *self = Self::new(spec, HashSet::new()); + } + /// Does cleanup and returns modified state. /// /// This resets the [JournaledState] to its initial state in [Self::new] diff --git a/documentation/src/crates/revm/handler.md b/documentation/src/crates/revm/handler.md index c6239d62..9222d8ba 100644 --- a/documentation/src/crates/revm/handler.md +++ b/documentation/src/crates/revm/handler.md @@ -105,4 +105,7 @@ Is a list of functions that are called after the execution. They are called in t Returns the state changes and the result of the execution. * `end`: - Always called as the last function of the handler. + Always called after transaction. End handler will not be called if validation fails. + +* `clear`: + Clears journal state and error and it is always called for the cleanup. \ No newline at end of file From 3e089f35ed2a98278ddbae8f5dd816ccc373fa31 Mon Sep 17 00:00:00 2001 From: Oliver Nordbjerg Date: Thu, 2 May 2024 09:13:38 +0200 Subject: [PATCH 045/105] feat: implement EIP-2935 (#1354) * feat: add eip-2935 constants * feat: impl EIP-2935 `BLOCKHASH` * fix: early return in prague * chore: fmt * refactor: `sload!` macro * chore: rm unused import * chore: rename consts * fix: typo from merge --- crates/interpreter/src/instructions/host.rs | 52 +++++++++++++------ crates/interpreter/src/instructions/macros.rs | 24 +++++++++ crates/interpreter/src/opcode.rs | 2 +- crates/primitives/src/constants.rs | 40 +++++++++++--- 4 files changed, 95 insertions(+), 23 deletions(-) diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index bad571de..43cba873 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -5,7 +5,7 @@ use crate::{ Host, InstructionResult, SStoreResult, }; use core::cmp::min; -use revm_primitives::BLOCK_HASH_HISTORY; +use revm_primitives::{BLOCKHASH_SERVE_WINDOW, BLOCKHASH_STORAGE_ADDRESS, BLOCK_HASH_HISTORY}; use std::vec::Vec; pub fn balance(interpreter: &mut Interpreter, host: &mut H) { @@ -103,32 +103,52 @@ pub fn extcodecopy(interpreter: &mut Interpreter, .set_data(memory_offset, code_offset, len, &code.original_bytes()); } -pub fn blockhash(interpreter: &mut Interpreter, host: &mut H) { +pub fn blockhash(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BLOCKHASH); pop_top!(interpreter, number); - if let Some(diff) = host.env().block.number.checked_sub(*number) { - let diff = as_usize_saturated!(diff); - // blockhash should push zero if number is same as current block number. - if diff <= BLOCK_HASH_HISTORY && diff != 0 { - let Some(hash) = host.block_hash(*number) else { - interpreter.instruction_result = InstructionResult::FatalExternalError; + let block_number = host.env().block.number; + + match block_number.checked_sub(*number) { + Some(diff) if !diff.is_zero() => { + let diff = as_usize_saturated!(diff); + + // blockhash should push zero if number is same as current block number. + if SPEC::enabled(PRAGUE) && diff <= BLOCKHASH_SERVE_WINDOW { + let value = sload!( + interpreter, + host, + BLOCKHASH_STORAGE_ADDRESS, + number.wrapping_rem(U256::from(BLOCKHASH_SERVE_WINDOW)) + ); + *number = value; return; - }; - *number = U256::from_be_bytes(hash.0); - return; + } else if diff <= BLOCK_HASH_HISTORY { + let Some(hash) = host.block_hash(*number) else { + interpreter.instruction_result = InstructionResult::FatalExternalError; + return; + }; + *number = U256::from_be_bytes(hash.0); + return; + } + } + _ => { + // If blockhash is requested for the current block, the hash should be 0, so we fall + // through. } } + *number = U256::ZERO; } pub fn sload(interpreter: &mut Interpreter, host: &mut H) { pop_top!(interpreter, index); - let Some((value, is_cold)) = host.sload(interpreter.contract.target_address, *index) else { - interpreter.instruction_result = InstructionResult::FatalExternalError; - return; - }; - gas!(interpreter, gas::sload_cost(SPEC::SPEC_ID, is_cold)); + let value = sload!( + interpreter, + host, + interpreter.contract.target_address, + *index + ); *index = value; } diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index 7a964fde..310ccdc3 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -45,6 +45,30 @@ macro_rules! check { }; } +/// Performs an `SLOAD` on the target account and storage index. +/// +/// If the slot could not be loaded, or if the gas cost could not be charged, the expanded code +/// sets the instruction result and returns accordingly. +/// +/// # Note +/// +/// This macro charges gas. +/// +/// # Returns +/// +/// Expands to the value of the storage slot. +#[macro_export] +macro_rules! sload { + ($interp:expr, $host:expr, $address:expr, $index:expr) => {{ + let Some((value, is_cold)) = $host.sload($address, $index) else { + $interp.instruction_result = $crate::InstructionResult::FatalExternalError; + return; + }; + $crate::gas!($interp, $crate::gas::sload_cost(SPEC::SPEC_ID, is_cold)); + value + }}; +} + /// Records a `gas` cost and fails the instruction if it would exceed the available gas. #[macro_export] macro_rules! gas { diff --git a/crates/interpreter/src/opcode.rs b/crates/interpreter/src/opcode.rs index 725f8694..5114c2ae 100644 --- a/crates/interpreter/src/opcode.rs +++ b/crates/interpreter/src/opcode.rs @@ -582,7 +582,7 @@ opcodes! { 0x3D => RETURNDATASIZE => system::returndatasize:: => stack_io(0, 1); 0x3E => RETURNDATACOPY => system::returndatacopy:: => stack_io(3, 0); 0x3F => EXTCODEHASH => host::extcodehash:: => stack_io(1, 1), not_eof; - 0x40 => BLOCKHASH => host::blockhash => stack_io(1, 1); + 0x40 => BLOCKHASH => host::blockhash:: => stack_io(1, 1); 0x41 => COINBASE => host_env::coinbase => stack_io(0, 1); 0x42 => TIMESTAMP => host_env::timestamp => stack_io(0, 1); 0x43 => NUMBER => host_env::block_number => stack_io(0, 1); diff --git a/crates/primitives/src/constants.rs b/crates/primitives/src/constants.rs index 07745dd3..c8223300 100644 --- a/crates/primitives/src/constants.rs +++ b/crates/primitives/src/constants.rs @@ -1,34 +1,62 @@ -use crate::Address; +use alloy_primitives::{address, Address}; /// EIP-170: Contract code size limit -/// By default limit is 0x6000 (~25kb) +/// +/// By default the limit is `0x6000` (~25kb) pub const MAX_CODE_SIZE: usize = 0x6000; -/// Number of block hashes that EVM can access in the past +/// Number of block hashes that EVM can access in the past (pre-Prague). pub const BLOCK_HASH_HISTORY: usize = 256; +/// EIP-2935: Serve historical block hashes from state +/// +/// Number of block hashes the EVM can access in the past (Prague). +/// +/// # Note +/// +/// This is named `HISTORY_SERVE_WINDOW` in the EIP. +pub const BLOCKHASH_SERVE_WINDOW: usize = 8192; + +/// EIP-2935: Serve historical block hashes from state +/// +/// The address where historical blockhashes are available. +/// +/// # Note +/// +/// This is named `HISTORY_STORAGE_ADDRESS` in the EIP. +pub const BLOCKHASH_STORAGE_ADDRESS: Address = address!("25a219378dad9b3503c8268c9ca836a52427a4fb"); + /// EIP-3860: Limit and meter initcode /// -/// Limit of maximum initcode size is 2 * MAX_CODE_SIZE +/// Limit of maximum initcode size is `2 * MAX_CODE_SIZE`. pub const MAX_INITCODE_SIZE: usize = 2 * MAX_CODE_SIZE; -/// Precompile 3 is special in few places +/// The address of precompile 3, which is handled specially in a few places. pub const PRECOMPILE3: Address = Address::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]); -// EIP-4844 constants + +// === EIP-4844 constants === + /// Gas consumption of a single data blob (== blob byte size). pub const GAS_PER_BLOB: u64 = 1 << 17; + /// Target number of the blob per block. pub const TARGET_BLOB_NUMBER_PER_BLOCK: u64 = 3; + /// Max number of blobs per block pub const MAX_BLOB_NUMBER_PER_BLOCK: u64 = 2 * TARGET_BLOB_NUMBER_PER_BLOCK; + /// Maximum consumable blob gas for data blobs per block. pub const MAX_BLOB_GAS_PER_BLOCK: u64 = MAX_BLOB_NUMBER_PER_BLOCK * GAS_PER_BLOB; + /// Target consumable blob gas for data blobs per block (for 1559-like pricing). pub const TARGET_BLOB_GAS_PER_BLOCK: u64 = TARGET_BLOB_NUMBER_PER_BLOCK * GAS_PER_BLOB; + /// Minimum gas price for data blobs. pub const MIN_BLOB_GASPRICE: u64 = 1; + /// Controls the maximum rate of change for blob gas price. pub const BLOB_GASPRICE_UPDATE_FRACTION: u64 = 3338477; + /// First version of the blob. pub const VERSIONED_HASH_VERSION_KZG: u8 = 0x01; From 12062b04dfad9b3a5536158d14b11424b245099f Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 2 May 2024 14:10:20 +0200 Subject: [PATCH 046/105] chore: re-use num_words in gas::cost_per_word (#1371) --- crates/interpreter/src/gas/calc.rs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/crates/interpreter/src/gas/calc.rs b/crates/interpreter/src/gas/calc.rs index 7337a991..828e6112 100644 --- a/crates/interpreter/src/gas/calc.rs +++ b/crates/interpreter/src/gas/calc.rs @@ -1,12 +1,7 @@ -use revm_primitives::Bytes; - use super::constants::*; use crate::{ - primitives::{ - Address, SpecId, - SpecId::{BERLIN, SPURIOUS_DRAGON, TANGERINE}, - U256, - }, + num_words, + primitives::{Address, Bytes, SpecId, U256}, SelfDestructResult, }; use std::vec::Vec; @@ -155,7 +150,7 @@ pub const fn keccak256_cost(len: u64) -> Option { /// Calculate the cost of buffer per word. #[inline] pub const fn cost_per_word(len: u64, multiple: u64) -> Option { - multiple.checked_mul(len.div_ceil(32)) + multiple.checked_mul(num_words(len)) } /// EIP-3860: Limit and meter initcode @@ -302,9 +297,9 @@ pub const fn call_cost( new_account_accounting: bool, ) -> u64 { // Account access. - let mut gas = if spec_id.is_enabled_in(BERLIN) { + let mut gas = if spec_id.is_enabled_in(SpecId::BERLIN) { warm_cold_cost(is_cold) - } else if spec_id.is_enabled_in(TANGERINE) { + } else if spec_id.is_enabled_in(SpecId::TANGERINE) { // EIP-150: Gas cost changes for IO-heavy operations 700 } else { @@ -319,7 +314,7 @@ pub const fn call_cost( // new account cost if new_account_accounting { // EIP-161: State trie clearing (invariant-preserving alternative) - if spec_id.is_enabled_in(SPURIOUS_DRAGON) { + if spec_id.is_enabled_in(SpecId::SPURIOUS_DRAGON) { // account only if there is value transferred. if transfers_value { gas += NEWACCOUNT; From 99e177d6bedf3823a717d3017b3cfeb98ed2aeac Mon Sep 17 00:00:00 2001 From: rakita Date: Thu, 2 May 2024 16:27:01 +0400 Subject: [PATCH 047/105] chore(ci): bump action/deploy (#1372) --- .github/workflows/book.yml | 2 +- crates/revm/src/handler/handle_types/post_execution.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml index 10894c4d..fb41e3ee 100644 --- a/.github/workflows/book.yml +++ b/.github/workflows/book.yml @@ -129,4 +129,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v2 \ No newline at end of file + uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/crates/revm/src/handler/handle_types/post_execution.rs b/crates/revm/src/handler/handle_types/post_execution.rs index 1b9e9fdc..f2149e89 100644 --- a/crates/revm/src/handler/handle_types/post_execution.rs +++ b/crates/revm/src/handler/handle_types/post_execution.rs @@ -47,8 +47,8 @@ pub struct PostExecutionHandler<'a, EXT, DB: Database> { pub reward_beneficiary: RewardBeneficiaryHandle<'a, EXT, DB>, /// Main return handle, returns the output of the transact. pub output: OutputHandle<'a, EXT, DB>, - /// End handle. Called when execution ends. - /// End in comparison to output will be called every time after execution. + /// Called when execution ends. + /// End handle in comparison to output handle will be called every time after execution. /// Output in case of error will not be called. pub end: EndHandle<'a, EXT, DB>, /// Clear handle will be called always. In comparison to end that From 569760d831f64c807367c114c7df1152cec9e61c Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Fri, 3 May 2024 13:42:36 +0200 Subject: [PATCH 048/105] perf(interpreter): branch less in as_usize_or_fail (#1374) * perf(interpreter): branch less in as_usize_or_fail * chore: clippy --- bins/revme/src/cmd/statetest/runner.rs | 2 +- crates/interpreter/src/instructions/i256.rs | 2 +- crates/interpreter/src/instructions/macros.rs | 38 ++++++++++--------- .../revm/src/db/states/transition_account.rs | 2 +- crates/revm/src/inspector/eip3155.rs | 2 +- 5 files changed, 24 insertions(+), 22 deletions(-) diff --git a/bins/revme/src/cmd/statetest/runner.rs b/bins/revme/src/cmd/statetest/runner.rs index c9f8aede..dcf8fcc3 100644 --- a/bins/revme/src/cmd/statetest/runner.rs +++ b/bins/revme/src/cmd/statetest/runner.rs @@ -361,7 +361,7 @@ pub fn execute_test_suite( .build(); let mut evm = Evm::builder() .with_db(&mut state) - .modify_env(|e| *e = env.clone()) + .modify_env(|e| e.clone_from(&env)) .with_spec_id(spec_id) .build(); diff --git a/crates/interpreter/src/instructions/i256.rs b/crates/interpreter/src/instructions/i256.rs index d806eacf..d7f72446 100644 --- a/crates/interpreter/src/instructions/i256.rs +++ b/crates/interpreter/src/instructions/i256.rs @@ -33,7 +33,7 @@ pub fn i256_sign(val: &U256) -> Sign { Sign::Minus } else { // SAFETY: false == 0 == Zero, true == 1 == Plus - unsafe { core::mem::transmute(*val != U256::ZERO) } + unsafe { core::mem::transmute::(*val != U256::ZERO) } } } diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index 310ccdc3..abac40bc 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -300,14 +300,17 @@ macro_rules! push { /// Converts a `U256` value to a `u64`, saturating to `MAX` if the value is too large. #[macro_export] macro_rules! as_u64_saturated { - ($v:expr) => {{ - let x: &[u64; 4] = $v.as_limbs(); - if x[1] == 0 && x[2] == 0 && x[3] == 0 { - x[0] - } else { - u64::MAX + ($v:expr) => { + match $v.as_limbs() { + x => { + if (x[1] == 0) & (x[2] == 0) & (x[3] == 0) { + x[0] + } else { + u64::MAX + } + } } - }}; + }; } /// Converts a `U256` value to a `usize`, saturating to `MAX` if the value is too large. @@ -352,16 +355,15 @@ macro_rules! as_usize_or_fail_ret { ) }; - ($interp:expr, $v:expr, $reason:expr, $ret:expr) => {{ - let x = $v.as_limbs(); - if x[1] != 0 || x[2] != 0 || x[3] != 0 { - $interp.instruction_result = $reason; - return $ret; + ($interp:expr, $v:expr, $reason:expr, $ret:expr) => { + match $v.as_limbs() { + x => { + if (x[0] > usize::MAX as u64) | (x[1] != 0) | (x[2] != 0) | (x[3] != 0) { + $interp.instruction_result = $reason; + return $ret; + } + x[0] as usize + } } - let Ok(val) = usize::try_from(x[0]) else { - $interp.instruction_result = $reason; - return $ret; - }; - val - }}; + }; } diff --git a/crates/revm/src/db/states/transition_account.rs b/crates/revm/src/db/states/transition_account.rs index 1dc6bc33..599bc290 100644 --- a/crates/revm/src/db/states/transition_account.rs +++ b/crates/revm/src/db/states/transition_account.rs @@ -85,7 +85,7 @@ impl TransitionAccount { /// Update new values of transition. Don't override old values. /// Both account info and old storages need to be left intact. pub fn update(&mut self, other: Self) { - self.info = other.info.clone(); + self.info.clone_from(&other.info); self.status = other.status; // if transition is from some to destroyed drop the storage. diff --git a/crates/revm/src/inspector/eip3155.rs b/crates/revm/src/inspector/eip3155.rs index b5331157..aec20ffd 100644 --- a/crates/revm/src/inspector/eip3155.rs +++ b/crates/revm/src/inspector/eip3155.rs @@ -191,7 +191,7 @@ impl Inspector for TracerEip3155 { fn step(&mut self, interp: &mut Interpreter, context: &mut EvmContext) { self.gas_inspector.step(interp, context); - self.stack = interp.stack.data().clone(); + self.stack.clone_from(interp.stack.data()); self.memory = if self.include_memory { Some(hex::encode_prefixed(interp.shared_memory.context_memory())) } else { From f0cfe774a1e55a1d9d95410f4c2a2092c92d72bd Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Sat, 4 May 2024 22:50:26 +0200 Subject: [PATCH 049/105] chore: remove unused file (#1379) --- .../src/instructions/contract/call_helpers.rs | 4 +- .../src/instructions/host/call_helpers.rs | 73 ------------------- 2 files changed, 1 insertion(+), 76 deletions(-) delete mode 100644 crates/interpreter/src/instructions/host/call_helpers.rs diff --git a/crates/interpreter/src/instructions/contract/call_helpers.rs b/crates/interpreter/src/instructions/contract/call_helpers.rs index ae8b9ed6..8746f2ec 100644 --- a/crates/interpreter/src/instructions/contract/call_helpers.rs +++ b/crates/interpreter/src/instructions/contract/call_helpers.rs @@ -1,9 +1,7 @@ -use revm_primitives::U256; - use crate::{ gas, interpreter::Interpreter, - primitives::{Bytes, Spec, SpecId::*}, + primitives::{Bytes, Spec, SpecId::*, U256}, Host, }; use core::{cmp::min, ops::Range}; diff --git a/crates/interpreter/src/instructions/host/call_helpers.rs b/crates/interpreter/src/instructions/host/call_helpers.rs deleted file mode 100644 index 803d0e62..00000000 --- a/crates/interpreter/src/instructions/host/call_helpers.rs +++ /dev/null @@ -1,73 +0,0 @@ -use crate::{ - gas::{self}, - interpreter::Interpreter, - primitives::{Address, Bytes, Spec, SpecId::*}, - Host, InstructionResult, -}; -use core::{cmp::min, ops::Range}; - -#[inline] -pub fn get_memory_input_and_out_ranges( - interpreter: &mut Interpreter, -) -> Option<(Bytes, Range)> { - pop_ret!(interpreter, in_offset, in_len, out_offset, out_len, None); - - let in_len = as_usize_or_fail_ret!(interpreter, in_len, None); - let input = if in_len != 0 { - let in_offset = as_usize_or_fail_ret!(interpreter, in_offset, None); - resize_memory!(interpreter, in_offset, in_len, None); - Bytes::copy_from_slice(interpreter.shared_memory.slice(in_offset, in_len)) - } else { - Bytes::new() - }; - - let out_len = as_usize_or_fail_ret!(interpreter, out_len, None); - let out_offset = if out_len != 0 { - let out_offset = as_usize_or_fail_ret!(interpreter, out_offset, None); - resize_memory!(interpreter, out_offset, out_len, None); - out_offset - } else { - usize::MAX //unrealistic value so we are sure it is not used - }; - - Some((input, out_offset..out_offset + out_len)) -} - -#[inline] -pub fn calc_call_gas( - interpreter: &mut Interpreter, - host: &mut H, - to: Address, - has_transfer: bool, - local_gas_limit: u64, - is_call_or_callcode: bool, - is_call_or_staticcall: bool, -) -> Option { - let Some((is_cold, exist)) = host.load_account(to) else { - interpreter.instruction_result = InstructionResult::FatalExternalError; - return None; - }; - let is_new = !exist; - - let call_cost = gas::call_cost( - SPEC::SPEC_ID, - has_transfer, - is_new, - is_cold, - is_call_or_callcode, - is_call_or_staticcall, - ); - - gas!(interpreter, call_cost, None); - - // EIP-150: Gas cost changes for IO-heavy operations - let gas_limit = if SPEC::enabled(TANGERINE) { - let gas = interpreter.gas().remaining(); - // take l64 part of gas_limit - min(gas - gas / 64, local_gas_limit) - } else { - local_gas_limit - }; - - Some(gas_limit) -} From f778a5d00a62a9d1fc1dde139c3eab5a99c65bb2 Mon Sep 17 00:00:00 2001 From: halo3mic <46010359+halo3mic@users.noreply.github.com> Date: Sat, 4 May 2024 22:51:15 +0200 Subject: [PATCH 050/105] bump alloy & specify dep rev (#1380) * bump alloy & specify dep rev * satisfy fmt check --- Cargo.lock | 55 +++++++++++++++++--------------- crates/primitives/Cargo.toml | 2 +- crates/revm/Cargo.toml | 10 +++--- crates/revm/src/db/alloydb.rs | 31 +++++++----------- examples/uniswap_v2_usdc_swap.rs | 15 ++++----- 5 files changed, 54 insertions(+), 59 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a57162c..fcfa74fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,20 +47,20 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "alloy-consensus" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +source = "git+https://github.com/alloy-rs/alloy.git?rev=44b8a6d#44b8a6da656602fd9fd2c52f28ecffa4acaed96c" dependencies = [ "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-serde", + "c-kzg", "serde", - "sha2", ] [[package]] name = "alloy-eips" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +source = "git+https://github.com/alloy-rs/alloy.git?rev=44b8a6d#44b8a6da656602fd9fd2c52f28ecffa4acaed96c" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -68,33 +68,36 @@ dependencies = [ "c-kzg", "once_cell", "serde", + "sha2", ] [[package]] name = "alloy-genesis" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +source = "git+https://github.com/alloy-rs/alloy.git?rev=44b8a6d#44b8a6da656602fd9fd2c52f28ecffa4acaed96c" dependencies = [ "alloy-primitives", "alloy-serde", "serde", + "serde_json", ] [[package]] name = "alloy-json-rpc" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +source = "git+https://github.com/alloy-rs/alloy.git?rev=44b8a6d#44b8a6da656602fd9fd2c52f28ecffa4acaed96c" dependencies = [ "alloy-primitives", "serde", "serde_json", "thiserror", + "tracing", ] [[package]] name = "alloy-network" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +source = "git+https://github.com/alloy-rs/alloy.git?rev=44b8a6d#44b8a6da656602fd9fd2c52f28ecffa4acaed96c" dependencies = [ "alloy-consensus", "alloy-eips", @@ -102,17 +105,17 @@ dependencies = [ "alloy-primitives", "alloy-rpc-types", "alloy-signer", + "alloy-sol-types", "async-trait", "futures-utils-wasm", - "serde", "thiserror", ] [[package]] name = "alloy-primitives" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99bbad0a6b588ef4aec1b5ddbbfdacd9ef04e00b979617765b03174318ee1f3a" +checksum = "525448f6afc1b70dd0f9d0a8145631bf2f5e434678ab23ab18409ca264cae6b3" dependencies = [ "alloy-rlp", "arbitrary", @@ -138,8 +141,9 @@ dependencies = [ [[package]] name = "alloy-provider" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +source = "git+https://github.com/alloy-rs/alloy.git?rev=44b8a6d#44b8a6da656602fd9fd2c52f28ecffa4acaed96c" dependencies = [ + "alloy-eips", "alloy-json-rpc", "alloy-network", "alloy-primitives", @@ -153,6 +157,7 @@ dependencies = [ "auto_impl", "dashmap", "futures", + "futures-utils-wasm", "lru", "reqwest 0.12.2", "serde_json", @@ -186,7 +191,7 @@ dependencies = [ [[package]] name = "alloy-rpc-client" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +source = "git+https://github.com/alloy-rs/alloy.git?rev=44b8a6d#44b8a6da656602fd9fd2c52f28ecffa4acaed96c" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -206,7 +211,7 @@ dependencies = [ [[package]] name = "alloy-rpc-types" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +source = "git+https://github.com/alloy-rs/alloy.git?rev=44b8a6d#44b8a6da656602fd9fd2c52f28ecffa4acaed96c" dependencies = [ "alloy-consensus", "alloy-eips", @@ -224,7 +229,7 @@ dependencies = [ [[package]] name = "alloy-rpc-types-trace" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +source = "git+https://github.com/alloy-rs/alloy.git?rev=44b8a6d#44b8a6da656602fd9fd2c52f28ecffa4acaed96c" dependencies = [ "alloy-primitives", "alloy-rpc-types", @@ -236,7 +241,7 @@ dependencies = [ [[package]] name = "alloy-serde" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +source = "git+https://github.com/alloy-rs/alloy.git?rev=44b8a6d#44b8a6da656602fd9fd2c52f28ecffa4acaed96c" dependencies = [ "alloy-primitives", "serde", @@ -246,7 +251,7 @@ dependencies = [ [[package]] name = "alloy-signer" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +source = "git+https://github.com/alloy-rs/alloy.git?rev=44b8a6d#44b8a6da656602fd9fd2c52f28ecffa4acaed96c" dependencies = [ "alloy-primitives", "async-trait", @@ -258,9 +263,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "452d929748ac948a10481fff4123affead32c553cf362841c5103dd508bdfc16" +checksum = "89c80a2cb97e7aa48611cbb63950336f9824a174cdf670527cc6465078a26ea1" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -276,9 +281,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-input" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df64e094f6d2099339f9e82b5b38440b159757b6920878f28316243f8166c8d1" +checksum = "c58894b58ac50979eeac6249661991ac40b9d541830d9a725f7714cc9ef08c23" dependencies = [ "const-hex", "dunce", @@ -291,9 +296,9 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43bc2d6dfc2a19fd56644494479510f98b1ee929e04cf0d4aa45e98baa3e545b" +checksum = "399287f68d1081ed8b1f4903c49687658b95b142207d7cb4ae2f4813915343ef" dependencies = [ "alloy-primitives", "alloy-sol-macro", @@ -304,7 +309,7 @@ dependencies = [ [[package]] name = "alloy-transport" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +source = "git+https://github.com/alloy-rs/alloy.git?rev=44b8a6d#44b8a6da656602fd9fd2c52f28ecffa4acaed96c" dependencies = [ "alloy-json-rpc", "base64 0.22.0", @@ -322,7 +327,7 @@ dependencies = [ [[package]] name = "alloy-transport-http" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#bfd0fda492e560c3463d521958793c81bbeadfc1" +source = "git+https://github.com/alloy-rs/alloy.git?rev=44b8a6d#44b8a6da656602fd9fd2c52f28ecffa4acaed96c" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -3636,9 +3641,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4497156948bd342b52038035a6fa514a89626e37af9d2c52a5e8d8ebcc7ee479" +checksum = "5aa0cefd02f532035d83cfec82647c6eb53140b0485220760e669f4bad489e36" dependencies = [ "paste", "proc-macro2", diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index b9fbb9fc..32ab4efb 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -17,7 +17,7 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -alloy-primitives = { version = "0.7", default-features = false, features = [ +alloy-primitives = { version = "0.7.2", default-features = false, features = [ "rlp", ] } hashbrown = "0.14" diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 2a517a4a..a10599ac 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -41,9 +41,9 @@ ethers-providers = { version = "2.0", optional = true } ethers-core = { version = "2.0", optional = true } # alloydb -alloy-provider = { git = "https://github.com/alloy-rs/alloy.git", optional = true, default-features = false } -alloy-rpc-types = {git = "https://github.com/alloy-rs/alloy.git", optional = true, default-features = false } -alloy-transport = {git = "https://github.com/alloy-rs/alloy.git", optional = true, default-features = false } +alloy-provider = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6d", optional = true, default-features = false } +alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6d", optional = true, default-features = false } +alloy-transport = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6d", optional = true, default-features = false } [dev-dependencies] alloy-sol-types = { version = "0.7.0", default-features = false, features = ["std"] } @@ -53,9 +53,9 @@ criterion = "0.5" indicatif = "0.17" reqwest = { version = "0.12" } -alloy-provider = { git = "https://github.com/alloy-rs/alloy.git", default-features = false, features = ["reqwest"] } +alloy-provider = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6d", default-features = false, features = ["reqwest"] } # needed for enabling TLS to use HTTPS connections when testing alloy DB -alloy-transport-http = { git = "https://github.com/alloy-rs/alloy.git" } +alloy-transport-http = { git = "https://github.com/alloy-rs/alloy.git" , rev = "44b8a6d" } [features] default = ["std", "c-kzg", "secp256k1", "portable"] diff --git a/crates/revm/src/db/alloydb.rs b/crates/revm/src/db/alloydb.rs index a9541991..932fc32d 100644 --- a/crates/revm/src/db/alloydb.rs +++ b/crates/revm/src/db/alloydb.rs @@ -15,13 +15,13 @@ pub struct AlloyDB> { /// The provider to fetch the data from. provider: P, /// The block number on which the queries will be based on. - block_number: Option, + block_number: BlockId, _marker: std::marker::PhantomData (T, N)>, } impl> AlloyDB { /// Create a new AlloyDB instance, with a [Provider] and a block (Use None for latest). - pub fn new(provider: P, block_number: Option) -> Self { + pub fn new(provider: P, block_number: BlockId) -> Self { Self { provider, block_number, @@ -63,7 +63,7 @@ impl> AlloyDB { } /// Set the block number on which the queries will be based on. - pub fn set_block_number(&mut self, block_number: Option) { + pub fn set_block_number(&mut self, block_number: BlockId) { self.block_number = block_number; } } @@ -77,9 +77,7 @@ impl> DatabaseRef for AlloyD .provider .get_transaction_count(address, self.block_number); let balance = self.provider.get_balance(address, self.block_number); - let code = self - .provider - .get_code_at(address, self.block_number.unwrap_or_default()); + let code = self.provider.get_code_at(address, self.block_number); tokio::join!(nonce, balance, code) }; @@ -90,12 +88,7 @@ impl> DatabaseRef for AlloyD let code_hash = code.hash_slow(); let nonce = nonce?; - Ok(Some(AccountInfo::new( - balance, - nonce.to::(), - code_hash, - code, - ))) + Ok(Some(AccountInfo::new(balance, nonce, code_hash, code))) } fn block_hash_ref(&self, number: U256) -> Result { @@ -160,14 +153,12 @@ mod tests { #[test] fn can_get_basic() { - let client = ProviderBuilder::new() - .on_reqwest_http( - "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27" - .parse() - .unwrap(), - ) - .unwrap(); - let alloydb = AlloyDB::new(client, Some(BlockId::from(16148323))); + let client = ProviderBuilder::new().on_http( + "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27" + .parse() + .unwrap(), + ); + let alloydb = AlloyDB::new(client, BlockId::from(16148323)); // ETH/USDT pair on Uniswap V2 let address: Address = "0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852" diff --git a/examples/uniswap_v2_usdc_swap.rs b/examples/uniswap_v2_usdc_swap.rs index 9171da10..a57a9826 100644 --- a/examples/uniswap_v2_usdc_swap.rs +++ b/examples/uniswap_v2_usdc_swap.rs @@ -1,4 +1,5 @@ use alloy_provider::{network::Ethereum, ProviderBuilder, RootProvider}; +use alloy_rpc_types::BlockId; use alloy_sol_types::{sol, SolCall, SolValue}; use alloy_transport_http::Http; use anyhow::{anyhow, Result}; @@ -17,15 +18,13 @@ type AlloyCacheDB = CacheDB, Ethereum, Arc Result<()> { - let client = ProviderBuilder::new() - .on_reqwest_http( - "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27" - .parse() - .unwrap(), - ) - .unwrap(); + let client = ProviderBuilder::new().on_http( + "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27" + .parse() + .unwrap(), + ); let client = Arc::new(client); - let mut cache_db = CacheDB::new(AlloyDB::new(client, None)); + let mut cache_db = CacheDB::new(AlloyDB::new(client, BlockId::default())); // Random empty account let account = address!("18B06aaF27d44B756FCF16Ca20C1f183EB49111f"); From 8f5be0e0c207ab9ca4d30512364f928db28d2e30 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Sat, 4 May 2024 22:51:39 +0200 Subject: [PATCH 051/105] chore(revme): increment statetest bar *after* running the test (#1377) --- bins/revme/src/cmd/statetest/runner.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bins/revme/src/cmd/statetest/runner.rs b/bins/revme/src/cmd/statetest/runner.rs index dcf8fcc3..16cf2379 100644 --- a/bins/revme/src/cmd/statetest/runner.rs +++ b/bins/revme/src/cmd/statetest/runner.rs @@ -509,8 +509,12 @@ pub fn run( (prev_idx, test_path) }; + let result = execute_test_suite(&test_path, &elapsed, trace, print_outcome); + + // Increment after the test is done. console_bar.inc(1); - if let Err(err) = execute_test_suite(&test_path, &elapsed, trace, print_outcome) { + + if let Err(err) = result { n_errors.fetch_add(1, Ordering::SeqCst); if !keep_going { return Err(err); From 7f19b988350fdc61f2ce3c17cfff2f2b2779c7ed Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Sat, 4 May 2024 14:02:36 -0700 Subject: [PATCH 052/105] chore: add blob_count and max_blobs to `TooManyBlobs` err enum (#1375) * add: essential info to `TooManyBlobs` err enum * fix clippy * nit: with names * fix --- crates/primitives/src/env.rs | 8 ++++++-- crates/primitives/src/result.rs | 9 +++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/crates/primitives/src/env.rs b/crates/primitives/src/env.rs index 9d0bc100..99b55571 100644 --- a/crates/primitives/src/env.rs +++ b/crates/primitives/src/env.rs @@ -172,8 +172,12 @@ impl Env { // ensure the total blob gas spent is at most equal to the limit // assert blob_gas_used <= MAX_BLOB_GAS_PER_BLOCK - if self.tx.blob_hashes.len() > MAX_BLOB_NUMBER_PER_BLOCK as usize { - return Err(InvalidTransaction::TooManyBlobs); + let num_blobs = self.tx.blob_hashes.len(); + if num_blobs > MAX_BLOB_NUMBER_PER_BLOCK as usize { + return Err(InvalidTransaction::TooManyBlobs { + have: num_blobs, + max: MAX_BLOB_NUMBER_PER_BLOCK as usize, + }); } } } else { diff --git a/crates/primitives/src/result.rs b/crates/primitives/src/result.rs index 516ce251..659c4fe3 100644 --- a/crates/primitives/src/result.rs +++ b/crates/primitives/src/result.rs @@ -242,7 +242,10 @@ pub enum InvalidTransaction { /// `to` must be present BlobCreateTransaction, /// Transaction has more then [`crate::MAX_BLOB_NUMBER_PER_BLOCK`] blobs - TooManyBlobs, + TooManyBlobs { + max: usize, + have: usize, + }, /// Blob transaction contains a versioned hash with an incorrect version BlobVersionNotSupported, /// EOF TxCreate transaction is not supported before Prague hardfork. @@ -339,7 +342,9 @@ impl fmt::Display for InvalidTransaction { } Self::EmptyBlobs => write!(f, "empty blobs"), Self::BlobCreateTransaction => write!(f, "blob create transaction"), - Self::TooManyBlobs => write!(f, "too many blobs"), + Self::TooManyBlobs { max, have } => { + write!(f, "too many blobs, have {have}, max {max}") + } Self::BlobVersionNotSupported => write!(f, "blob version not supported"), Self::EofInitcodesNotSupported => write!(f, "EOF initcodes not supported"), Self::EofCrateShouldHaveToAddress => write!(f, "EOF crate should have `to` address"), From 432852c936cf10f5dddbe48cf6643214dba56c6d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 13:12:55 +0200 Subject: [PATCH 053/105] chore(deps): bump thiserror from 1.0.58 to 1.0.59 (#1383) Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.58 to 1.0.59. - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.58...1.0.59) --- updated-dependencies: - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fcfa74fc..737365a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3707,18 +3707,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" dependencies = [ "proc-macro2", "quote", From 37e76b7e2b392f16730104953188a7e5990f8f89 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 13:13:04 +0200 Subject: [PATCH 054/105] chore(deps): bump serde from 1.0.197 to 1.0.200 (#1385) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.197 to 1.0.200. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.197...v1.0.200) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 737365a5..f0b5bdce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3381,18 +3381,18 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" dependencies = [ "proc-macro2", "quote", From 24f2db3ae00e2cbaa9b7f12bedce7af54b412b97 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 13:55:26 +0200 Subject: [PATCH 055/105] chore(deps): bump reqwest from 0.12.2 to 0.12.4 (#1384) Bumps [reqwest](https://github.com/seanmonstar/reqwest) from 0.12.2 to 0.12.4. - [Release notes](https://github.com/seanmonstar/reqwest/releases) - [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md) - [Commits](https://github.com/seanmonstar/reqwest/compare/v0.12.2...v0.12.4) --- updated-dependencies: - dependency-name: reqwest dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f0b5bdce..b1079536 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -159,7 +159,7 @@ dependencies = [ "futures", "futures-utils-wasm", "lru", - "reqwest 0.12.2", + "reqwest 0.12.4", "serde_json", "tokio", "tracing", @@ -198,7 +198,7 @@ dependencies = [ "alloy-transport-http", "futures", "pin-project", - "reqwest 0.12.2", + "reqwest 0.12.4", "serde", "serde_json", "tokio", @@ -331,7 +331,7 @@ source = "git+https://github.com/alloy-rs/alloy.git?rev=44b8a6d#44b8a6da656602fd dependencies = [ "alloy-json-rpc", "alloy-transport", - "reqwest 0.12.2", + "reqwest 0.12.4", "serde_json", "tower", "url", @@ -2860,7 +2860,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", @@ -2874,16 +2874,16 @@ dependencies = [ "wasm-bindgen-futures", "web-sys", "webpki-roots", - "winreg", + "winreg 0.50.0", ] [[package]] name = "reqwest" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d66674f2b6fb864665eea7a3c1ac4e3dfacd2fda83cf6f935a612e01b0e3338" +checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" dependencies = [ - "base64 0.21.7", + "base64 0.22.0", "bytes", "encoding_rs", "futures-core", @@ -2903,7 +2903,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile", + "rustls-pemfile 2.1.2", "serde", "serde_json", "serde_urlencoded", @@ -2916,7 +2916,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg", + "winreg 0.52.0", ] [[package]] @@ -2937,7 +2937,7 @@ dependencies = [ "ethers-core", "ethers-providers", "indicatif", - "reqwest 0.12.2", + "reqwest 0.12.4", "revm-interpreter", "revm-precompile", "serde", @@ -3195,6 +3195,22 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.0", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beb461507cee2c2ff151784c52762cf4d9ff6a61f3e80968600ed24fa837fa54" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -4454,6 +4470,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "ws_stream_wasm" version = "0.7.4" From f24bf3b7270f6219967306d55746dd5fbb4e82cc Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Tue, 7 May 2024 17:41:11 +0200 Subject: [PATCH 056/105] feat: add a hook to execute individual frames (#1369) * feat: add a hook to optionally execute individual frames * Move Host to Context and modify execute frame handle * return error form execute frame handle, nits --- crates/revm/src/builder.rs | 24 +- crates/revm/src/context.rs | 83 ++++- crates/revm/src/context/inner_evm_context.rs | 1 + crates/revm/src/evm.rs | 329 ++++++------------ crates/revm/src/handler.rs | 39 ++- .../src/handler/handle_types/execution.rs | 32 +- crates/revm/src/handler/mainnet.rs | 2 +- crates/revm/src/handler/mainnet/execution.rs | 26 +- crates/revm/src/handler/register.rs | 4 +- crates/revm/src/inspector/handler_register.rs | 80 ++--- 10 files changed, 312 insertions(+), 308 deletions(-) diff --git a/crates/revm/src/builder.rs b/crates/revm/src/builder.rs index 5508fa9c..4b2a81ec 100644 --- a/crates/revm/src/builder.rs +++ b/crates/revm/src/builder.rs @@ -15,7 +15,7 @@ use std::boxed::Box; pub struct EvmBuilder<'a, BuilderStage, EXT, DB: Database> { context: Context, /// Handler that will be used by EVM. It contains handle registers - handler: Handler<'a, Evm<'a, EXT, DB>, EXT, DB>, + handler: Handler<'a, Context, EXT, DB>, /// Phantom data to mark the stage of the builder. phantom: PhantomData, } @@ -269,7 +269,7 @@ impl<'a, BuilderStage, EXT, DB: Database> EvmBuilder<'a, BuilderStage, EXT, DB> /// Creates the default handler. /// /// This is useful for adding optimism handle register. - fn handler(handler_cfg: HandlerCfg) -> Handler<'a, Evm<'a, EXT, DB>, EXT, DB> { + fn handler(handler_cfg: HandlerCfg) -> Handler<'a, Context, EXT, DB> { Handler::new(handler_cfg) } @@ -291,7 +291,7 @@ impl<'a, BuilderStage, EXT, DB: Database> EvmBuilder<'a, BuilderStage, EXT, DB> /// ``` pub fn with_handler( self, - handler: Handler<'a, Evm<'a, EXT, DB>, EXT, DB>, + handler: Handler<'a, Context, EXT, DB>, ) -> EvmBuilder<'a, BuilderStage, EXT, DB> { EvmBuilder { context: self.context, @@ -481,22 +481,18 @@ mod test { // we need to use a box to capture the custom context in the instruction let custom_instruction = Box::new( - move |_interp: &mut Interpreter, _host: &mut Evm<'_, (), InMemoryDB>| { + move |_interp: &mut Interpreter, _host: &mut Context<(), InMemoryDB>| { // modify the value let mut inner = custom_context.inner.borrow_mut(); *inner += 1; }, ); - // need to make esure the instruction table is a boxed instruction table so that we + // need to ensure the instruction table is a boxed instruction table so that we // can insert the custom instruction as a boxed instruction - let mut table = handler.take_instruction_table(); - table = table.map(|mut table| { - // now we can finally insert - table.insert_boxed(0xEF, custom_instruction); - table - }); - handler.instruction_table = table; + handler + .instruction_table + .insert_boxed(0xEF, custom_instruction); })) .build(); @@ -528,9 +524,7 @@ mod test { }) .modify_tx_env(|tx| tx.transact_to = TransactTo::Call(to_addr)) .append_handler_register(|handler| { - if let Some(ref mut table) = handler.instruction_table { - table.insert(0xEF, custom_instruction) - } + handler.instruction_table.insert(0xEF, custom_instruction) }) .build(); diff --git a/crates/revm/src/context.rs b/crates/revm/src/context.rs index aba8f27d..343dfcf9 100644 --- a/crates/revm/src/context.rs +++ b/crates/revm/src/context.rs @@ -11,7 +11,8 @@ pub use inner_evm_context::InnerEvmContext; use crate::{ db::{Database, EmptyDB}, - primitives::HandlerCfg, + interpreter::{Host, LoadAccountResult, SStoreResult, SelfDestructResult}, + primitives::{Address, Bytecode, Env, HandlerCfg, Log, B256, U256}, }; use std::boxed::Box; @@ -94,3 +95,83 @@ where } } } + +impl Host for Context { + fn env(&self) -> &Env { + &self.evm.env + } + + fn env_mut(&mut self) -> &mut Env { + &mut self.evm.env + } + + fn block_hash(&mut self, number: U256) -> Option { + self.evm + .block_hash(number) + .map_err(|e| self.evm.error = Err(e)) + .ok() + } + + fn load_account(&mut self, address: Address) -> Option { + self.evm + .load_account_exist(address) + .map_err(|e| self.evm.error = Err(e)) + .ok() + } + + fn balance(&mut self, address: Address) -> Option<(U256, bool)> { + self.evm + .balance(address) + .map_err(|e| self.evm.error = Err(e)) + .ok() + } + + fn code(&mut self, address: Address) -> Option<(Bytecode, bool)> { + self.evm + .code(address) + .map_err(|e| self.evm.error = Err(e)) + .ok() + } + + fn code_hash(&mut self, address: Address) -> Option<(B256, bool)> { + self.evm + .code_hash(address) + .map_err(|e| self.evm.error = Err(e)) + .ok() + } + + fn sload(&mut self, address: Address, index: U256) -> Option<(U256, bool)> { + self.evm + .sload(address, index) + .map_err(|e| self.evm.error = Err(e)) + .ok() + } + + fn sstore(&mut self, address: Address, index: U256, value: U256) -> Option { + self.evm + .sstore(address, index, value) + .map_err(|e| self.evm.error = Err(e)) + .ok() + } + + fn tload(&mut self, address: Address, index: U256) -> U256 { + self.evm.tload(address, index) + } + + fn tstore(&mut self, address: Address, index: U256, value: U256) { + self.evm.tstore(address, index, value) + } + + fn log(&mut self, log: Log) { + self.evm.journaled_state.log(log); + } + + fn selfdestruct(&mut self, address: Address, target: Address) -> Option { + self.evm + .inner + .journaled_state + .selfdestruct(address, target, &mut self.evm.inner.db) + .map_err(|e| self.evm.error = Err(e)) + .ok() + } +} diff --git a/crates/revm/src/context/inner_evm_context.rs b/crates/revm/src/context/inner_evm_context.rs index 63e11467..109b16a7 100644 --- a/crates/revm/src/context/inner_evm_context.rs +++ b/crates/revm/src/context/inner_evm_context.rs @@ -114,6 +114,7 @@ impl InnerEvmContext { } /// Returns the error by replacing it with `Ok(())`, if any. + #[inline] pub fn take_error(&mut self) -> Result<(), EVMError> { core::mem::replace(&mut self.error, Ok(())) } diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index 25ff0d01..2fcf9324 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -2,14 +2,10 @@ use crate::{ builder::{EvmBuilder, HandlerStage, SetGenericStage}, db::{Database, DatabaseCommit, EmptyDB}, handler::Handler, - interpreter::{ - opcode::InstructionTables, Host, Interpreter, InterpreterAction, LoadAccountResult, - SStoreResult, SelfDestructResult, SharedMemory, - }, + interpreter::{Host, InterpreterAction, SharedMemory}, primitives::{ - specification::SpecId, Address, BlockEnv, Bytecode, CfgEnv, EVMError, EVMResult, Env, - EnvWithHandlerCfg, ExecutionResult, HandlerCfg, Log, ResultAndState, TransactTo, TxEnv, - B256, U256, + specification::SpecId, BlockEnv, CfgEnv, EVMError, EVMResult, EnvWithHandlerCfg, + ExecutionResult, HandlerCfg, ResultAndState, TransactTo, TxEnv, }, Context, ContextWithHandlerCfg, Frame, FrameOrResult, FrameResult, }; @@ -27,7 +23,7 @@ pub struct Evm<'a, EXT, DB: Database> { pub context: Context, /// Handler is a component of the of EVM that contains all the logic. Handler contains specification id /// and it different depending on the specified fork. - pub handler: Handler<'a, Self, EXT, DB>, + pub handler: Handler<'a, Context, EXT, DB>, } impl fmt::Debug for Evm<'_, EXT, DB> @@ -63,7 +59,7 @@ impl<'a, EXT, DB: Database> Evm<'a, EXT, DB> { /// Create new EVM. pub fn new( mut context: Context, - handler: Handler<'a, Self, EXT, DB>, + handler: Handler<'a, Context, EXT, DB>, ) -> Evm<'a, EXT, DB> { context.evm.journaled_state.set_spec_id(handler.cfg.spec_id); Evm { context, handler } @@ -74,6 +70,102 @@ impl<'a, EXT, DB: Database> Evm<'a, EXT, DB> { pub fn modify(self) -> EvmBuilder<'a, HandlerStage, EXT, DB> { EvmBuilder::new(self) } + + /// Runs main call loop. + #[inline] + pub fn run_the_loop(&mut self, first_frame: Frame) -> Result> { + let mut call_stack: Vec = Vec::with_capacity(1025); + call_stack.push(first_frame); + + #[cfg(feature = "memory_limit")] + let mut shared_memory = + SharedMemory::new_with_memory_limit(self.context.evm.env.cfg.memory_limit); + #[cfg(not(feature = "memory_limit"))] + let mut shared_memory = SharedMemory::new(); + + shared_memory.new_context(); + + // Peek the last stack frame. + let mut stack_frame = call_stack.last_mut().unwrap(); + + loop { + // Execute the frame. + let next_action = + self.handler + .execute_frame(stack_frame, &mut shared_memory, &mut self.context)?; + + // Take error and break the loop, if any. + // This error can be set in the Interpreter when it interacts with the context. + self.context.evm.take_error()?; + + let exec = &mut self.handler.execution; + let frame_or_result = match next_action { + InterpreterAction::Call { inputs } => exec.call(&mut self.context, inputs)?, + InterpreterAction::Create { inputs } => exec.create(&mut self.context, inputs)?, + InterpreterAction::EOFCreate { inputs } => { + exec.eofcreate(&mut self.context, inputs)? + } + InterpreterAction::Return { result } => { + // free memory context. + shared_memory.free_context(); + + // pop last frame from the stack and consume it to create FrameResult. + let returned_frame = call_stack + .pop() + .expect("We just returned from Interpreter frame"); + + let ctx = &mut self.context; + FrameOrResult::Result(match returned_frame { + Frame::Call(frame) => { + // return_call + FrameResult::Call(exec.call_return(ctx, frame, result)?) + } + Frame::Create(frame) => { + // return_create + FrameResult::Create(exec.create_return(ctx, frame, result)?) + } + Frame::EOFCreate(frame) => { + // return_eofcreate + FrameResult::EOFCreate(exec.eofcreate_return(ctx, frame, result)?) + } + }) + } + InterpreterAction::None => unreachable!("InterpreterAction::None is not expected"), + }; + + // handle result + match frame_or_result { + FrameOrResult::Frame(frame) => { + shared_memory.new_context(); + call_stack.push(frame); + stack_frame = call_stack.last_mut().unwrap(); + } + FrameOrResult::Result(result) => { + let Some(top_frame) = call_stack.last_mut() else { + // Break the loop if there are no more frames. + return Ok(result); + }; + stack_frame = top_frame; + let ctx = &mut self.context; + // Insert result to the top frame. + match result { + FrameResult::Call(outcome) => { + // return_call + exec.insert_call_outcome(ctx, stack_frame, &mut shared_memory, outcome)? + } + FrameResult::Create(outcome) => { + // return_create + exec.insert_create_outcome(ctx, stack_frame, outcome)? + } + FrameResult::EOFCreate(outcome) => { + // return_eofcreate + exec.insert_eofcreate_outcome(ctx, stack_frame, outcome)? + } + } + } + } + } + } } impl Evm<'_, EXT, DB> { @@ -156,7 +248,7 @@ impl Evm<'_, EXT, DB> { /// Returns the reference of Env configuration #[inline] pub fn cfg(&self) -> &CfgEnv { - &self.env().cfg + &self.context.env().cfg } /// Returns the mutable reference of Env configuration @@ -230,133 +322,6 @@ impl Evm<'_, EXT, DB> { ContextWithHandlerCfg::new(self.context, self.handler.cfg) } - /// Starts the main loop and returns outcome of the execution. - pub fn start_the_loop( - &mut self, - first_frame: Frame, - ) -> Result> { - // take instruction table - let table = self - .handler - .take_instruction_table() - .expect("Instruction table should be present"); - - // run main loop - let frame_result = match &table { - InstructionTables::Plain(table) => self.run_the_loop(table, first_frame), - InstructionTables::Boxed(table) => self.run_the_loop(table, first_frame), - }; - - // return back instruction table - self.handler.set_instruction_table(table); - - frame_result - } - - /// Runs main call loop. - #[inline] - pub fn run_the_loop( - &mut self, - instruction_table: &[FN; 256], - first_frame: Frame, - ) -> Result> - where - FN: Fn(&mut Interpreter, &mut Self), - { - let mut call_stack: Vec = Vec::with_capacity(1025); - call_stack.push(first_frame); - - #[cfg(feature = "memory_limit")] - let mut shared_memory = - SharedMemory::new_with_memory_limit(self.context.evm.env.cfg.memory_limit); - #[cfg(not(feature = "memory_limit"))] - let mut shared_memory = SharedMemory::new(); - - shared_memory.new_context(); - - // peek last stack frame. - let mut stack_frame = call_stack.last_mut().unwrap(); - - loop { - // run interpreter - let interpreter = &mut stack_frame.frame_data_mut().interpreter; - let next_action = interpreter.run(shared_memory, instruction_table, self); - - // take error and break the loop if there is any. - // This error is set From Interpreter when it's interacting with Host. - self.context.evm.take_error()?; - // take shared memory back. - shared_memory = interpreter.take_memory(); - - let exec = &mut self.handler.execution; - let frame_or_result = match next_action { - InterpreterAction::Call { inputs } => exec.call(&mut self.context, inputs)?, - InterpreterAction::Create { inputs } => exec.create(&mut self.context, inputs)?, - InterpreterAction::EOFCreate { inputs } => { - exec.eofcreate(&mut self.context, inputs)? - } - InterpreterAction::Return { result } => { - // free memory context. - shared_memory.free_context(); - - // pop last frame from the stack and consume it to create FrameResult. - let returned_frame = call_stack - .pop() - .expect("We just returned from Interpreter frame"); - - let ctx = &mut self.context; - FrameOrResult::Result(match returned_frame { - Frame::Call(frame) => { - // return_call - FrameResult::Call(exec.call_return(ctx, frame, result)?) - } - Frame::Create(frame) => { - // return_create - FrameResult::Create(exec.create_return(ctx, frame, result)?) - } - Frame::EOFCreate(frame) => { - // return_eofcreate - FrameResult::EOFCreate(exec.eofcreate_return(ctx, frame, result)?) - } - }) - } - InterpreterAction::None => unreachable!("InterpreterAction::None is not expected"), - }; - - // handle result - match frame_or_result { - FrameOrResult::Frame(frame) => { - shared_memory.new_context(); - call_stack.push(frame); - stack_frame = call_stack.last_mut().unwrap(); - } - FrameOrResult::Result(result) => { - let Some(top_frame) = call_stack.last_mut() else { - // Break the look if there are no more frames. - return Ok(result); - }; - stack_frame = top_frame; - let ctx = &mut self.context; - // Insert result to the top frame. - match result { - FrameResult::Call(outcome) => { - // return_call - exec.insert_call_outcome(ctx, stack_frame, &mut shared_memory, outcome)? - } - FrameResult::Create(outcome) => { - // return_create - exec.insert_create_outcome(ctx, stack_frame, outcome)? - } - FrameResult::EOFCreate(outcome) => { - // return_eofcreate - exec.insert_eofcreate_outcome(ctx, stack_frame, outcome)? - } - } - } - } - } - } - /// Transact pre-verified transaction. fn transact_preverified_inner(&mut self, initial_gas_spend: u64) -> EVMResult { let ctx = &mut self.context; @@ -389,7 +354,7 @@ impl Evm<'_, EXT, DB> { // Starts the main running loop. let mut result = match first_frame_or_result { - FrameOrResult::Frame(first_frame) => self.start_the_loop(first_frame)?, + FrameOrResult::Frame(first_frame) => self.run_the_loop(first_frame)?, FrameOrResult::Result(result) => result, }; @@ -409,91 +374,3 @@ impl Evm<'_, EXT, DB> { post_exec.output(ctx, result) } } - -impl Host for Evm<'_, EXT, DB> { - fn env(&self) -> &Env { - &self.context.evm.env - } - - fn env_mut(&mut self) -> &mut Env { - &mut self.context.evm.env - } - - fn block_hash(&mut self, number: U256) -> Option { - self.context - .evm - .block_hash(number) - .map_err(|e| self.context.evm.error = Err(e)) - .ok() - } - - fn load_account(&mut self, address: Address) -> Option { - self.context - .evm - .load_account_exist(address) - .map_err(|e| self.context.evm.error = Err(e)) - .ok() - } - - fn balance(&mut self, address: Address) -> Option<(U256, bool)> { - self.context - .evm - .balance(address) - .map_err(|e| self.context.evm.error = Err(e)) - .ok() - } - - fn code(&mut self, address: Address) -> Option<(Bytecode, bool)> { - self.context - .evm - .code(address) - .map_err(|e| self.context.evm.error = Err(e)) - .ok() - } - - fn code_hash(&mut self, address: Address) -> Option<(B256, bool)> { - self.context - .evm - .code_hash(address) - .map_err(|e| self.context.evm.error = Err(e)) - .ok() - } - - fn sload(&mut self, address: Address, index: U256) -> Option<(U256, bool)> { - self.context - .evm - .sload(address, index) - .map_err(|e| self.context.evm.error = Err(e)) - .ok() - } - - fn sstore(&mut self, address: Address, index: U256, value: U256) -> Option { - self.context - .evm - .sstore(address, index, value) - .map_err(|e| self.context.evm.error = Err(e)) - .ok() - } - - fn tload(&mut self, address: Address, index: U256) -> U256 { - self.context.evm.tload(address, index) - } - - fn tstore(&mut self, address: Address, index: U256, value: U256) { - self.context.evm.tstore(address, index, value) - } - - fn log(&mut self, log: Log) { - self.context.evm.journaled_state.log(log); - } - - fn selfdestruct(&mut self, address: Address, target: Address) -> Option { - self.context - .evm - .inner - .journaled_state - .selfdestruct(address, target, &mut self.context.evm.inner.db) - .map_err(|e| self.context.evm.error = Err(e)) - .ok() - } -} diff --git a/crates/revm/src/handler.rs b/crates/revm/src/handler.rs index a6dfde55..fab20b12 100644 --- a/crates/revm/src/handler.rs +++ b/crates/revm/src/handler.rs @@ -8,10 +8,11 @@ pub use handle_types::*; // Includes. use crate::{ - interpreter::{opcode::InstructionTables, Host}, - primitives::{db::Database, spec_to_generic, HandlerCfg, Spec, SpecId}, - Evm, + interpreter::{opcode::InstructionTables, Host, InterpreterAction, SharedMemory}, + primitives::{db::Database, spec_to_generic, EVMError, HandlerCfg, Spec, SpecId}, + Context, Frame, }; +use core::mem; use register::{EvmHandler, HandleRegisters}; use std::vec::Vec; @@ -24,7 +25,7 @@ pub struct Handler<'a, H: Host + 'a, EXT, DB: Database> { /// Handler configuration. pub cfg: HandlerCfg, /// Instruction table type. - pub instruction_table: Option>, + pub instruction_table: InstructionTables<'a, H>, /// Registers that will be called on initialization. pub registers: Vec>, /// Validity handles. @@ -60,7 +61,7 @@ impl<'a, EXT, DB: Database> EvmHandler<'a, EXT, DB> { pub fn mainnet() -> Self { Self { cfg: HandlerCfg::new(SPEC::SPEC_ID), - instruction_table: Some(InstructionTables::new_plain::()), + instruction_table: InstructionTables::new_plain::(), registers: Vec::new(), validation: ValidationHandler::new::(), pre_execution: PreExecutionHandler::new::(), @@ -102,14 +103,34 @@ impl<'a, EXT, DB: Database> EvmHandler<'a, EXT, DB> { self.cfg } + /// Returns specification ID. + pub fn spec_id(&self) -> SpecId { + self.cfg.spec_id + } + + /// Executes call frame. + pub fn execute_frame( + &self, + frame: &mut Frame, + shared_memory: &mut SharedMemory, + context: &mut Context, + ) -> Result> { + self.execution + .execute_frame(frame, shared_memory, &self.instruction_table, context) + } + /// Take instruction table. - pub fn take_instruction_table(&mut self) -> Option>> { - self.instruction_table.take() + pub fn take_instruction_table(&mut self) -> InstructionTables<'a, Context> { + let spec_id = self.spec_id(); + mem::replace( + &mut self.instruction_table, + spec_to_generic!(spec_id, InstructionTables::new_plain::()), + ) } /// Set instruction table. - pub fn set_instruction_table(&mut self, table: InstructionTables<'a, Evm<'a, EXT, DB>>) { - self.instruction_table = Some(table); + pub fn set_instruction_table(&mut self, table: InstructionTables<'a, Context>) { + self.instruction_table = table; } /// Returns reference to pre execution handler. diff --git a/crates/revm/src/handler/handle_types/execution.rs b/crates/revm/src/handler/handle_types/execution.rs index d13dd205..b69354a5 100644 --- a/crates/revm/src/handler/handle_types/execution.rs +++ b/crates/revm/src/handler/handle_types/execution.rs @@ -5,11 +5,11 @@ use crate::{ primitives::{db::Database, EVMError, Spec}, CallFrame, Context, CreateFrame, Frame, FrameOrResult, FrameResult, }; -use std::{boxed::Box, sync::Arc}; - use revm_interpreter::{ - CallOutcome, CreateOutcome, EOFCreateInput, EOFCreateOutcome, InterpreterResult, + opcode::InstructionTables, CallOutcome, CreateOutcome, EOFCreateInput, EOFCreateOutcome, + InterpreterAction, InterpreterResult, }; +use std::{boxed::Box, sync::Arc}; /// Handles first frame return handle. pub type LastFrameReturnHandle<'a, EXT, DB> = Arc< @@ -17,6 +17,17 @@ pub type LastFrameReturnHandle<'a, EXT, DB> = Arc< + 'a, >; +/// Executes a single frame. Errors can be returned in the EVM context. +pub type ExecuteFrameHandle<'a, EXT, DB> = Arc< + dyn Fn( + &mut Frame, + &mut SharedMemory, + &InstructionTables<'_, Context>, + &mut Context, + ) -> Result::Error>> + + 'a, +>; + /// Handle sub call. pub type FrameCallHandle<'a, EXT, DB> = Arc< dyn Fn( @@ -110,6 +121,8 @@ pub struct ExecutionHandler<'a, EXT, DB: Database> { /// Handles last frame return, modified gas for refund and /// sets tx gas limit. pub last_frame_return: LastFrameReturnHandle<'a, EXT, DB>, + /// Executes a single frame. + pub execute_frame: ExecuteFrameHandle<'a, EXT, DB>, /// Frame call pub call: FrameCallHandle<'a, EXT, DB>, /// Call return @@ -135,6 +148,7 @@ impl<'a, EXT: 'a, DB: Database + 'a> ExecutionHandler<'a, EXT, DB> { pub fn new() -> Self { Self { last_frame_return: Arc::new(mainnet::last_frame_return::), + execute_frame: Arc::new(mainnet::execute_frame::), call: Arc::new(mainnet::call::), call_return: Arc::new(mainnet::call_return::), insert_call_outcome: Arc::new(mainnet::insert_call_outcome), @@ -149,6 +163,18 @@ impl<'a, EXT: 'a, DB: Database + 'a> ExecutionHandler<'a, EXT, DB> { } impl<'a, EXT, DB: Database> ExecutionHandler<'a, EXT, DB> { + /// Executes single frame. + #[inline] + pub fn execute_frame( + &self, + frame: &mut Frame, + shared_memory: &mut SharedMemory, + instruction_tables: &InstructionTables<'_, Context>, + context: &mut Context, + ) -> Result> { + (self.execute_frame)(frame, shared_memory, instruction_tables, context) + } + /// Handle call return, depending on instruction result gas will be reimbursed or not. #[inline] pub fn last_frame_return( diff --git a/crates/revm/src/handler/mainnet.rs b/crates/revm/src/handler/mainnet.rs index 3bf7da30..b02e96bf 100644 --- a/crates/revm/src/handler/mainnet.rs +++ b/crates/revm/src/handler/mainnet.rs @@ -6,7 +6,7 @@ mod pre_execution; mod validation; pub use execution::{ - call, call_return, create, create_return, eofcreate, eofcreate_return, + call, call_return, create, create_return, eofcreate, eofcreate_return, execute_frame, frame_return_with_refund_flag, insert_call_outcome, insert_create_outcome, insert_eofcreate_outcome, last_frame_return, }; diff --git a/crates/revm/src/handler/mainnet/execution.rs b/crates/revm/src/handler/mainnet/execution.rs index 852dab37..9e1ff3ef 100644 --- a/crates/revm/src/handler/mainnet/execution.rs +++ b/crates/revm/src/handler/mainnet/execution.rs @@ -8,9 +8,33 @@ use crate::{ primitives::{EVMError, Env, Spec, SpecId}, CallFrame, Context, CreateFrame, Frame, FrameOrResult, FrameResult, }; -use revm_interpreter::{CallOutcome, EOFCreateInput, EOFCreateOutcome, InterpreterResult}; +use core::mem; +use revm_interpreter::{ + opcode::InstructionTables, CallOutcome, EOFCreateInput, EOFCreateOutcome, InterpreterAction, + InterpreterResult, EMPTY_SHARED_MEMORY, +}; use std::boxed::Box; +/// Execute frame +#[inline] +pub fn execute_frame( + frame: &mut Frame, + shared_memory: &mut SharedMemory, + instruction_tables: &InstructionTables<'_, Context>, + context: &mut Context, +) -> Result> { + let interpreter = frame.interpreter_mut(); + let memory = mem::replace(shared_memory, EMPTY_SHARED_MEMORY); + let next_action = match instruction_tables { + InstructionTables::Plain(table) => interpreter.run(memory, table, context), + InstructionTables::Boxed(table) => interpreter.run(memory, table, context), + }; + // Take the shared memory back. + *shared_memory = interpreter.take_memory(); + + Ok(next_action) +} + /// Helper function called inside [`last_frame_return`] #[inline] pub fn frame_return_with_refund_flag( diff --git a/crates/revm/src/handler/register.rs b/crates/revm/src/handler/register.rs index 73c28439..4b9fa313 100644 --- a/crates/revm/src/handler/register.rs +++ b/crates/revm/src/handler/register.rs @@ -1,8 +1,8 @@ -use crate::{db::Database, handler::Handler, Evm}; +use crate::{db::Database, handler::Handler, Context}; use std::boxed::Box; /// EVM Handler -pub type EvmHandler<'a, EXT, DB> = Handler<'a, Evm<'a, EXT, DB>, EXT, DB>; +pub type EvmHandler<'a, EXT, DB> = Handler<'a, Context, EXT, DB>; // Handle register pub type HandleRegister = for<'a> fn(&mut EvmHandler<'a, EXT, DB>); diff --git a/crates/revm/src/inspector/handler_register.rs b/crates/revm/src/inspector/handler_register.rs index 65a60dae..01bc11c5 100644 --- a/crates/revm/src/inspector/handler_register.rs +++ b/crates/revm/src/inspector/handler_register.rs @@ -1,9 +1,12 @@ use crate::{ db::Database, handler::register::EvmHandler, - interpreter::{opcode, opcode::BoxedInstruction, InstructionResult, Interpreter}, + interpreter::{ + opcode::{self, BoxedInstruction}, + InstructionResult, Interpreter, + }, primitives::EVMError, - Evm, FrameOrResult, FrameResult, Inspector, JournalEntry, + Context, FrameOrResult, FrameResult, Inspector, JournalEntry, }; use core::cell::RefCell; use revm_interpreter::opcode::InstructionTables; @@ -34,13 +37,11 @@ impl> GetInspector for INSP { /// A few instructions handlers are wrapped twice once for `step` and `step_end` /// and in case of Logs and Selfdestruct wrapper is wrapped again for the /// `log` and `selfdestruct` calls. -pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector>( - handler: &mut EvmHandler<'a, EXT, DB>, +pub fn inspector_handle_register>( + handler: &mut EvmHandler<'_, EXT, DB>, ) { // Every instruction inside flat table that is going to be wrapped by inspector calls. - let table = handler - .take_instruction_table() - .expect("Handler must have instruction table"); + let table = handler.take_instruction_table(); let mut table = match table { InstructionTables::Plain(table) => table .into_iter() @@ -57,28 +58,18 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector>( if let Some(i) = table.get_mut(index as usize) { let old = core::mem::replace(i, Box::new(|_, _| ())); *i = Box::new( - move |interpreter: &mut Interpreter, host: &mut Evm<'a, EXT, DB>| { - let old_log_len = host.context.evm.journaled_state.logs.len(); + move |interpreter: &mut Interpreter, host: &mut Context| { + let old_log_len = host.evm.journaled_state.logs.len(); old(interpreter, host); // check if log was added. It is possible that revert happened // cause of gas or stack underflow. - if host.context.evm.journaled_state.logs.len() == old_log_len + 1 { + if host.evm.journaled_state.logs.len() == old_log_len + 1 { // clone log. // TODO decide if we should remove this and leave the comment // that log can be found as journaled_state. - let last_log = host - .context - .evm - .journaled_state - .logs - .last() - .unwrap() - .clone(); + let last_log = host.evm.journaled_state.logs.last().unwrap().clone(); // call Inspector - host.context - .external - .get_inspector() - .log(&mut host.context.evm, &last_log); + host.external.get_inspector().log(&mut host.evm, &last_log); } }, ) @@ -95,7 +86,7 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector>( if let Some(i) = table.get_mut(opcode::SELFDESTRUCT as usize) { let old = core::mem::replace(i, Box::new(|_, _| ())); *i = Box::new( - move |interpreter: &mut Interpreter, host: &mut Evm<'a, EXT, DB>| { + move |interpreter: &mut Interpreter, host: &mut Context| { // execute selfdestruct old(interpreter, host); // check if selfdestruct was successful and if journal entry is made. @@ -104,20 +95,11 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector>( target, had_balance, .. - }) = host - .context - .evm - .journaled_state - .journal - .last() - .unwrap() - .last() + }) = host.evm.journaled_state.journal.last().unwrap().last() { - host.context.external.get_inspector().selfdestruct( - *address, - *target, - *had_balance, - ); + host.external + .get_inspector() + .selfdestruct(*address, *target, *had_balance); } }, ) @@ -236,20 +218,19 @@ pub fn inspector_instruction< 'a, INSP: GetInspector, DB: Database, - Instruction: Fn(&mut Interpreter, &mut Evm<'a, INSP, DB>) + 'a, + Instruction: Fn(&mut Interpreter, &mut Context) + 'a, >( instruction: Instruction, -) -> BoxedInstruction<'a, Evm<'a, INSP, DB>> { +) -> BoxedInstruction<'a, Context> { Box::new( - move |interpreter: &mut Interpreter, host: &mut Evm<'a, INSP, DB>| { + move |interpreter: &mut Interpreter, host: &mut Context| { // SAFETY: as the PC was already incremented we need to subtract 1 to preserve the // old Inspector behavior. interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.sub(1) }; - host.context - .external + host.external .get_inspector() - .step(interpreter, &mut host.context.evm); + .step(interpreter, &mut host.evm); if interpreter.instruction_result != InstructionResult::Continue { return; } @@ -260,10 +241,9 @@ pub fn inspector_instruction< // execute instruction. instruction(interpreter, host); - host.context - .external + host.external .get_inspector() - .step_end(interpreter, &mut host.context.evm); + .step_end(interpreter, &mut host.evm); }, ) } @@ -276,16 +256,16 @@ mod tests { inspectors::NoOpInspector, interpreter::{opcode::*, CallInputs, CallOutcome, CreateInputs, CreateOutcome}, primitives::BerlinSpec, - EvmContext, + Evm, EvmContext, }; // Test that this pattern builds. #[test] fn test_make_boxed_instruction_table() { - type MyEvm<'a> = Evm<'a, NoOpInspector, EmptyDB>; - let table: InstructionTable> = make_instruction_table::, BerlinSpec>(); - let _boxed_table: BoxedInstructionTable<'_, MyEvm<'_>> = - make_boxed_instruction_table::<'_, MyEvm<'_>, BerlinSpec, _>( + type MyContext = Context; + let table: InstructionTable = make_instruction_table::(); + let _boxed_table: BoxedInstructionTable<'_, MyContext> = + make_boxed_instruction_table::<'_, MyContext, BerlinSpec, _>( table, inspector_instruction, ); From c1109bd9c478094b786efe4f36e848bb1d468757 Mon Sep 17 00:00:00 2001 From: rakita Date: Wed, 8 May 2024 01:09:15 +0200 Subject: [PATCH 057/105] chore: refactor lints (#1386) * chore: refactor lints * rustdoc lints * fix doc link --- crates/interpreter/Cargo.toml | 8 ++++++++ crates/interpreter/src/lib.rs | 4 +--- crates/precompile/Cargo.toml | 8 ++++++++ crates/precompile/src/lib.rs | 2 -- crates/primitives/Cargo.toml | 11 ++++++++--- crates/primitives/src/lib.rs | 4 +--- crates/revm/Cargo.toml | 18 +++++++++++++++--- crates/revm/src/journaled_state.rs | 2 +- crates/revm/src/lib.rs | 5 +---- 9 files changed, 43 insertions(+), 19 deletions(-) diff --git a/crates/interpreter/Cargo.toml b/crates/interpreter/Cargo.toml index 1b59e7d3..db705bd9 100644 --- a/crates/interpreter/Cargo.toml +++ b/crates/interpreter/Cargo.toml @@ -13,6 +13,14 @@ readme = "../../README.md" all-features = true rustdoc-args = ["--cfg", "docsrs"] +[lints.rust] +unreachable_pub = "warn" +unused_must_use = "deny" +rust_2018_idioms = "deny" + +[lints.rustdoc] +all = "warn" + [dependencies] revm-primitives = { path = "../primitives", version = "3.1.1", default-features = false } diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs index 27df443b..01db0327 100644 --- a/crates/interpreter/src/lib.rs +++ b/crates/interpreter/src/lib.rs @@ -1,9 +1,7 @@ //! # revm-interpreter //! //! REVM Interpreter. -#![warn(rustdoc::all)] -#![warn(unreachable_pub, unused_crate_dependencies)] -#![deny(unused_must_use, rust_2018_idioms)] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(not(feature = "std"), no_std)] #[cfg(not(feature = "std"))] diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index a9893a82..8c7c7e6f 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -12,6 +12,14 @@ version = "6.0.0" all-features = true rustdoc-args = ["--cfg", "docsrs"] +[lints.rust] +unreachable_pub = "warn" +unused_must_use = "deny" +rust_2018_idioms = "deny" + +[lints.rustdoc] +all = "warn" + [dependencies] revm-primitives = { path = "../primitives", version = "3.1.1", default-features = false } bn = { package = "substrate-bn", version = "0.6", default-features = false } diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index aa3ffadf..4dc6cae5 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -1,9 +1,7 @@ //! # revm-precompile //! //! Implementations of EVM precompiled contracts. -#![warn(rustdoc::all)] #![cfg_attr(not(test), warn(unused_crate_dependencies))] -#![deny(unused_must_use, rust_2018_idioms)] #![cfg_attr(not(feature = "std"), no_std)] #[macro_use] diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 32ab4efb..07b049a0 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -9,13 +9,18 @@ repository = "https://github.com/bluealloy/revm" version = "3.1.1" readme = "../../README.md" -# Don't need to run build script outside of this repo -exclude = ["build.rs", "src/kzg/*.txt"] - [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] +[lints.rust] +unreachable_pub = "warn" +unused_must_use = "deny" +rust_2018_idioms = "deny" + +[lints.rustdoc] +all = "warn" + [dependencies] alloy-primitives = { version = "0.7.2", default-features = false, features = [ "rlp", diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 2ce1a8e5..c57f900b 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -1,9 +1,7 @@ //! # revm-primitives //! //! EVM primitive types. -#![warn(rustdoc::all)] -#![warn(unreachable_pub, unused_crate_dependencies)] -#![deny(unused_must_use, rust_2018_idioms)] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(not(feature = "std"), no_std)] #[cfg(not(feature = "std"))] diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index a10599ac..7ddb7175 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -13,6 +13,14 @@ readme = "../../README.md" all-features = true rustdoc-args = ["--cfg", "docsrs"] +[lints.rust] +unreachable_pub = "warn" +unused_must_use = "deny" +rust_2018_idioms = "deny" + +[lints.rustdoc] +all = "warn" + [dependencies] # revm revm-interpreter = { path = "../interpreter", version = "4.0.0", default-features = false } @@ -46,16 +54,20 @@ alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6 alloy-transport = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6d", optional = true, default-features = false } [dev-dependencies] -alloy-sol-types = { version = "0.7.0", default-features = false, features = ["std"] } +alloy-sol-types = { version = "0.7.0", default-features = false, features = [ + "std", +] } ethers-contract = { version = "2.0.14", default-features = false } anyhow = "1.0.82" criterion = "0.5" indicatif = "0.17" reqwest = { version = "0.12" } -alloy-provider = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6d", default-features = false, features = ["reqwest"] } +alloy-provider = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6d", default-features = false, features = [ + "reqwest", +] } # needed for enabling TLS to use HTTPS connections when testing alloy DB -alloy-transport-http = { git = "https://github.com/alloy-rs/alloy.git" , rev = "44b8a6d" } +alloy-transport-http = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6d" } [features] default = ["std", "c-kzg", "secp256k1", "portable"] diff --git a/crates/revm/src/journaled_state.rs b/crates/revm/src/journaled_state.rs index 96a1c186..a233a78c 100644 --- a/crates/revm/src/journaled_state.rs +++ b/crates/revm/src/journaled_state.rs @@ -15,7 +15,7 @@ use std::vec::Vec; pub struct JournaledState { /// Current state. pub state: State, - /// [EIP-1153[(https://eips.ethereum.org/EIPS/eip-1153) transient storage that is discarded after every transactions + /// [EIP-1153](https://eips.ethereum.org/EIPS/eip-1153) transient storage that is discarded after every transactions pub transient_storage: TransientStorage, /// logs pub logs: Vec, diff --git a/crates/revm/src/lib.rs b/crates/revm/src/lib.rs index cf9b275a..6b69b5bd 100644 --- a/crates/revm/src/lib.rs +++ b/crates/revm/src/lib.rs @@ -1,8 +1,5 @@ -#![doc = "Revm is a Rust EVM implementation."] -#![warn(rustdoc::all, unreachable_pub)] -#![allow(rustdoc::bare_urls)] +//! Revm is a Rust EVM implementation. #![cfg_attr(not(test), warn(unused_crate_dependencies))] -#![deny(unused_must_use, rust_2018_idioms)] #![cfg_attr(not(feature = "std"), no_std)] #[macro_use] From 5404a6a931b971121b8bc970466bf3e5aa518537 Mon Sep 17 00:00:00 2001 From: Qiwei Yang Date: Wed, 8 May 2024 19:08:32 +0800 Subject: [PATCH 058/105] feat: add trace option in `revme evm` (#1376) * feat: add trace option * fix: use evm.modify * fix * refactor * Update bins/revme/src/cmd/evmrunner.rs * Update bins/revme/src/cmd/evmrunner.rs --- bins/revme/src/cmd/evmrunner.rs | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/bins/revme/src/cmd/evmrunner.rs b/bins/revme/src/cmd/evmrunner.rs index 1414a970..8c93d318 100644 --- a/bins/revme/src/cmd/evmrunner.rs +++ b/bins/revme/src/cmd/evmrunner.rs @@ -1,5 +1,7 @@ use revm::{ db::BenchmarkDB, + inspector_handle_register, + inspectors::TracerEip3155, primitives::{Address, Bytecode, TransactTo}, Evm, }; @@ -51,6 +53,9 @@ pub struct Cmd { /// Print the state. #[structopt(long)] state: bool, + /// Print the trace. + #[structopt(long)] + trace: bool, } impl Cmd { @@ -93,13 +98,30 @@ impl Cmd { microbench::bench(&bench_options, "Run bytecode", || { let _ = evm.transact().unwrap(); }); + + return Ok(()); + } + + let out = if self.trace { + let mut evm = evm + .modify() + .reset_handler_with_external_context(TracerEip3155::new( + Box::new(std::io::stdout()), + )) + .append_handler_register(inspector_handle_register) + .build(); + + evm.transact().map_err(|_| Errors::EVMError)? } else { let out = evm.transact().map_err(|_| Errors::EVMError)?; println!("Result: {:#?}", out.result); - if self.state { - println!("State: {:#?}", out.state); - } + out + }; + + if self.state { + println!("State: {:#?}", out.state); } + Ok(()) } } From ab54cd5cc652f49f8d7088f6551de1f351c830af Mon Sep 17 00:00:00 2001 From: Alexey Shekhirin Date: Wed, 8 May 2024 15:28:27 +0100 Subject: [PATCH 059/105] feat(precompile): add Prague hardfork specification (#1387) --- crates/precompile/src/lib.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index 4dc6cae5..7903d38b 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -63,6 +63,7 @@ impl Precompiles { PrecompileSpecId::ISTANBUL => Self::istanbul(), PrecompileSpecId::BERLIN => Self::berlin(), PrecompileSpecId::CANCUN => Self::cancun(), + PrecompileSpecId::PRAGUE => Self::prague(), PrecompileSpecId::LATEST => Self::latest(), } } @@ -154,9 +155,21 @@ impl Precompiles { }) } + /// Returns precompiles for Prague spec. + pub fn prague() -> &'static Self { + static INSTANCE: OnceBox = OnceBox::new(); + INSTANCE.get_or_init(|| { + let precompiles = Self::cancun().clone(); + // EIP-2537: Precompile for BLS12-381 curve operations + // TODO(alexey): add BLS12-381 precompiles + // precompiles.extend(bls12_381::precompiles()); + Box::new(precompiles) + }) + } + /// Returns the precompiles for the latest spec. pub fn latest() -> &'static Self { - Self::cancun() + Self::prague() } /// Returns an iterator over the precompiles addresses. @@ -229,6 +242,7 @@ pub enum PrecompileSpecId { ISTANBUL, BERLIN, CANCUN, + PRAGUE, LATEST, } @@ -243,7 +257,8 @@ impl PrecompileSpecId { BYZANTIUM | CONSTANTINOPLE | PETERSBURG => Self::BYZANTIUM, ISTANBUL | MUIR_GLACIER => Self::ISTANBUL, BERLIN | LONDON | ARROW_GLACIER | GRAY_GLACIER | MERGE | SHANGHAI => Self::BERLIN, - CANCUN | PRAGUE => Self::CANCUN, + CANCUN => Self::CANCUN, + PRAGUE => Self::PRAGUE, LATEST => Self::LATEST, #[cfg(feature = "optimism")] BEDROCK | REGOLITH | CANYON => Self::BERLIN, From 15ef150f381c8ff074011ae0698350a0fbc214bf Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Wed, 8 May 2024 18:06:09 -0400 Subject: [PATCH 060/105] chore: bump c-kzg to 1.0.2 (#1390) --- Cargo.lock | 4 ++-- crates/precompile/Cargo.toml | 2 +- crates/primitives/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b1079536..9c1edc6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -730,9 +730,9 @@ dependencies = [ [[package]] name = "c-kzg" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3130f3d8717cc02e668a896af24984d5d5d4e8bf12e278e982e0f1bd88a0f9af" +checksum = "cdf100c4cea8f207e883ff91ca886d621d8a166cb04971dfaa9bb8fd99ed95df" dependencies = [ "blst", "cc", diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index 8c7c7e6f..14c009d7 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -30,7 +30,7 @@ sha2 = { version = "0.10", default-features = false } aurora-engine-modexp = { version = "1.1", default-features = false } # Optional KZG point evaluation precompile -c-kzg = { version = "1.0.0", default-features = false, optional = true } +c-kzg = { version = "1.0.2", default-features = false, optional = true } # ecRecover precompile k256 = { version = "0.13.3", default-features = false, features = ["ecdsa"] } diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 07b049a0..b23697b1 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -31,7 +31,7 @@ bitvec = { version = "1", default-features = false, features = ["alloc"] } bitflags = { version = "2.5.0", default-features = false } # For setting the CfgEnv KZGSettings. Enabled by c-kzg flag. -c-kzg = { version = "1.0.0", default-features = false, optional = true } +c-kzg = { version = "1.0.2", default-features = false, optional = true } once_cell = { version = "1.19", default-features = false, optional = true } # utility From 1914696de833600f28d895be6c2621714402419c Mon Sep 17 00:00:00 2001 From: Alexey Shekhirin Date: Fri, 10 May 2024 05:44:11 +0100 Subject: [PATCH 061/105] feat(precompile): Prague - EIP-2537 - BLS12-381 curve operations (#1389) * feat(precompile): add Prague hardfork specification * feat(precompile): add Prague hardfork specification * feat(precompile): BLS12-381 * feature-gate blst * run EIP-2537 tests in CI * fix doc comment * fixes after review (arrays to vecs, question mark operators, default inits) * introduce separate variables for mutable blst calls * return value instead of mutating the input argument where possible * replace *mut with *const where mut is not needed --- .github/workflows/ethereum-tests.yml | 2 + Cargo.lock | 1 + bins/revme/Cargo.toml | 1 + crates/precompile/Cargo.toml | 8 +- crates/precompile/src/bls12_381/g1.rs | 48 ++++++++++ crates/precompile/src/bls12_381/g1_add.rs | 61 ++++++++++++ crates/precompile/src/bls12_381/g1_msm.rs | 77 +++++++++++++++ crates/precompile/src/bls12_381/g1_mul.rs | 61 ++++++++++++ crates/precompile/src/bls12_381/g2.rs | 64 +++++++++++++ crates/precompile/src/bls12_381/g2_add.rs | 62 ++++++++++++ crates/precompile/src/bls12_381/g2_msm.rs | 77 +++++++++++++++ crates/precompile/src/bls12_381/g2_mul.rs | 61 ++++++++++++ .../precompile/src/bls12_381/map_fp2_to_g2.rs | 70 ++++++++++++++ .../precompile/src/bls12_381/map_fp_to_g1.rs | 60 ++++++++++++ crates/precompile/src/bls12_381/mod.rs | 31 ++++++ crates/precompile/src/bls12_381/msm.rs | 28 ++++++ crates/precompile/src/bls12_381/pairing.rs | 95 +++++++++++++++++++ crates/precompile/src/bls12_381/utils.rs | 65 +++++++++++++ crates/precompile/src/lib.rs | 16 +++- crates/revm/Cargo.toml | 3 +- 20 files changed, 885 insertions(+), 6 deletions(-) create mode 100644 crates/precompile/src/bls12_381/g1.rs create mode 100644 crates/precompile/src/bls12_381/g1_add.rs create mode 100644 crates/precompile/src/bls12_381/g1_msm.rs create mode 100644 crates/precompile/src/bls12_381/g1_mul.rs create mode 100644 crates/precompile/src/bls12_381/g2.rs create mode 100644 crates/precompile/src/bls12_381/g2_add.rs create mode 100644 crates/precompile/src/bls12_381/g2_msm.rs create mode 100644 crates/precompile/src/bls12_381/g2_mul.rs create mode 100644 crates/precompile/src/bls12_381/map_fp2_to_g2.rs create mode 100644 crates/precompile/src/bls12_381/map_fp_to_g1.rs create mode 100644 crates/precompile/src/bls12_381/mod.rs create mode 100644 crates/precompile/src/bls12_381/msm.rs create mode 100644 crates/precompile/src/bls12_381/pairing.rs create mode 100644 crates/precompile/src/bls12_381/utils.rs diff --git a/.github/workflows/ethereum-tests.yml b/.github/workflows/ethereum-tests.yml index 3b972f77..c4c1c8df 100644 --- a/.github/workflows/ethereum-tests.yml +++ b/.github/workflows/ethereum-tests.yml @@ -47,3 +47,5 @@ jobs: ethtests/LegacyTests/Constantinople/GeneralStateTests/ \ ethtests/EIPTests/StateTests/stEIP1153-transientStorage/ \ ethtests/EIPTests/StateTests/stEIP4844-blobtransactions/ \ + ethtests/EIPTests/StateTests/stEIP2537/ \ + diff --git a/Cargo.lock b/Cargo.lock index 9c1edc6c..b074209e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2963,6 +2963,7 @@ name = "revm-precompile" version = "6.0.0" dependencies = [ "aurora-engine-modexp", + "blst", "c-kzg", "criterion", "k256", diff --git a/bins/revme/Cargo.toml b/bins/revme/Cargo.toml index 95290714..84a695d7 100644 --- a/bins/revme/Cargo.toml +++ b/bins/revme/Cargo.toml @@ -20,6 +20,7 @@ revm = { path = "../../crates/revm", version = "8.0.0", default-features = false "std", "serde-json", "c-kzg", + "blst" ] } alloy-rlp = { version = "0.3", default-features = false, features = [ "arrayvec", diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index 14c009d7..a2f4e863 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -41,12 +41,15 @@ secp256k1 = { version = "0.29.0", default-features = false, features = [ "global-context", ], optional = true } +# BLS12-381 precompiles +blst = { version = "0.3.11", optional = true } + [dev-dependencies] criterion = { version = "0.5" } rand = { version = "0.8", features = ["std"] } [features] -default = ["std", "c-kzg", "secp256k1", "portable"] +default = ["std", "c-kzg", "secp256k1", "portable", "blst"] std = [ "revm-primitives/std", "k256/std", @@ -80,6 +83,9 @@ portable = ["revm-primitives/portable", "c-kzg?/portable"] # In Linux it passes. If you don't require to build wasm on win/mac, it is safe to use it and it is enabled by default. secp256k1 = ["dep:secp256k1"] +# Enables the BLS12-381 precompiles. +blst = ["dep:blst"] + [[bench]] name = "bench" path = "benches/bench.rs" diff --git a/crates/precompile/src/bls12_381/g1.rs b/crates/precompile/src/bls12_381/g1.rs new file mode 100644 index 00000000..28e5a845 --- /dev/null +++ b/crates/precompile/src/bls12_381/g1.rs @@ -0,0 +1,48 @@ +use blst::{blst_fp_from_bendian, blst_p1_affine, blst_p1_affine_in_g1}; +use revm_primitives::{Bytes, PrecompileError}; + +use super::utils::{fp_to_bytes, remove_padding, PADDED_FP_LENGTH}; + +/// Length of each of the elements in a g1 operation input. +pub(super) const G1_INPUT_ITEM_LENGTH: usize = 128; +/// Output length of a g1 operation. +const G1_OUTPUT_LENGTH: usize = 128; + +/// Encodes a G1 point in affine format into a byte slice with padded elements. +pub(super) fn encode_g1_point(input: *const blst_p1_affine) -> Bytes { + let mut out = vec![0u8; G1_OUTPUT_LENGTH]; + // SAFETY: out comes from fixed length array, input is a blst value. + unsafe { + fp_to_bytes(&mut out[..PADDED_FP_LENGTH], &(*input).x); + fp_to_bytes(&mut out[PADDED_FP_LENGTH..], &(*input).y); + } + out.into() +} + +/// Extracts a G1 point in Affine format from a 128 byte slice representation. +pub(super) fn extract_g1_input(input: &[u8]) -> Result<*const blst_p1_affine, PrecompileError> { + if input.len() != G1_INPUT_ITEM_LENGTH { + return Err(PrecompileError::Other(format!( + "Input should be {G1_INPUT_ITEM_LENGTH} bits, was {}", + input.len() + ))); + } + + let input_p0_x = remove_padding(&input[..PADDED_FP_LENGTH])?; + let input_p0_y = remove_padding(&input[PADDED_FP_LENGTH..G1_INPUT_ITEM_LENGTH])?; + + let mut out = blst_p1_affine::default(); + // SAFETY: input_p0_x and input_p0_y have fixed length, out is a blst value. + unsafe { + blst_fp_from_bendian(&mut out.x, input_p0_x.as_ptr()); + blst_fp_from_bendian(&mut out.y, input_p0_y.as_ptr()); + } + + // SAFETY: out is a blst value. + unsafe { + if !blst_p1_affine_in_g1(&out) { + return Err(PrecompileError::Other("Element not in G1".to_string())); + } + } + Ok(&mut out as *const _) +} diff --git a/crates/precompile/src/bls12_381/g1_add.rs b/crates/precompile/src/bls12_381/g1_add.rs new file mode 100644 index 00000000..e3adba01 --- /dev/null +++ b/crates/precompile/src/bls12_381/g1_add.rs @@ -0,0 +1,61 @@ +use blst::{ + blst_p1, blst_p1_add_or_double_affine, blst_p1_affine, blst_p1_from_affine, blst_p1_to_affine, +}; +use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; + +use crate::{u64_to_address, PrecompileWithAddress}; + +use super::g1::{encode_g1_point, extract_g1_input, G1_INPUT_ITEM_LENGTH}; + +/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G1ADD precompile. +pub const PRECOMPILE: PrecompileWithAddress = + PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(g1_add)); +/// BLS12_G1ADD precompile address. +pub const ADDRESS: u64 = 0x0b; +/// Base gas fee for BLS12-381 g1_add operation. +const BASE_GAS_FEE: u64 = 500; + +/// Input length of g1_add operation. +const INPUT_LENGTH: usize = 256; + +/// G1 addition call expects `256` bytes as an input that is interpreted as byte +/// concatenation of two G1 points (`128` bytes each). +/// Output is an encoding of addition operation result - single G1 point (`128` +/// bytes). +/// See also: +fn g1_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { + if BASE_GAS_FEE > gas_limit { + return Err(PrecompileError::OutOfGas); + } + + if input.len() != INPUT_LENGTH { + return Err(PrecompileError::Other(format!( + "G1ADD Input should be {INPUT_LENGTH} bits, was {}", + input.len() + ))); + } + + let a_aff = extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH])?; + let b_aff = extract_g1_input(&input[G1_INPUT_ITEM_LENGTH..])?; + + let mut b = blst_p1::default(); + // SAFETY: b and b_aff are blst values. + unsafe { + blst_p1_from_affine(&mut b, b_aff); + } + + let mut p = blst_p1::default(); + // SAFETY: p, b and a_aff are blst values. + unsafe { + blst_p1_add_or_double_affine(&mut p, &b, a_aff); + } + + let mut p_aff = blst_p1_affine::default(); + // SAFETY: p_aff and p are blst values. + unsafe { + blst_p1_to_affine(&mut p_aff, &p); + } + + let out = encode_g1_point(&p_aff); + Ok((BASE_GAS_FEE, out)) +} diff --git a/crates/precompile/src/bls12_381/g1_msm.rs b/crates/precompile/src/bls12_381/g1_msm.rs new file mode 100644 index 00000000..a339d860 --- /dev/null +++ b/crates/precompile/src/bls12_381/g1_msm.rs @@ -0,0 +1,77 @@ +use blst::{blst_p1, blst_p1_affine, blst_p1_from_affine, blst_p1_to_affine, p1_affines}; +use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; + +use crate::{u64_to_address, PrecompileWithAddress}; + +use super::{ + g1::{encode_g1_point, extract_g1_input, G1_INPUT_ITEM_LENGTH}, + g1_mul, + msm::msm_required_gas, + utils::{extract_scalar_input, NBITS, SCALAR_LENGTH}, +}; + +/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G1MSM precompile. +pub const PRECOMPILE: PrecompileWithAddress = + PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(g1_msm)); +/// BLS12_G1MSM precompile address. +pub const ADDRESS: u64 = 0x0d; + +/// Implements EIP-2537 G1MSM precompile. +/// G1 multi-scalar-multiplication call expects `160*k` bytes as an input that is interpreted +/// as byte concatenation of `k` slices each of them being a byte concatenation +/// of encoding of G1 point (`128` bytes) and encoding of a scalar value (`32` +/// bytes). +/// Output is an encoding of multi-scalar-multiplication operation result - single G1 +/// point (`128` bytes). +/// See also: +fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { + let input_len = input.len(); + if input_len == 0 || input_len % g1_mul::INPUT_LENGTH != 0 { + return Err(PrecompileError::Other(format!( + "G1MSM input length should be multiple of {}, was {}", + g1_mul::INPUT_LENGTH, + input_len + ))); + } + + let k = input_len / g1_mul::INPUT_LENGTH; + let required_gas = msm_required_gas(k, g1_mul::BASE_GAS_FEE); + if required_gas > gas_limit { + return Err(PrecompileError::OutOfGas); + } + + let mut g1_points: Vec = Vec::with_capacity(k); + let mut scalars: Vec = Vec::with_capacity(k * SCALAR_LENGTH); + for i in 0..k { + let p0_aff = extract_g1_input( + &input[i * g1_mul::INPUT_LENGTH..i * g1_mul::INPUT_LENGTH + G1_INPUT_ITEM_LENGTH], + )?; + let mut p0 = blst_p1::default(); + // SAFETY: p0 and p0_aff are blst values. + unsafe { + blst_p1_from_affine(&mut p0, p0_aff); + } + + g1_points.push(p0); + + scalars.extend_from_slice( + &extract_scalar_input( + &input[i * g1_mul::INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + ..i * g1_mul::INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + SCALAR_LENGTH], + )? + .b, + ); + } + + let points = p1_affines::from(&g1_points); + let multiexp = points.mult(&scalars, NBITS); + + let mut multiexp_aff = blst_p1_affine::default(); + // SAFETY: multiexp_aff and multiexp are blst values. + unsafe { + blst_p1_to_affine(&mut multiexp_aff, &multiexp); + } + + let out = encode_g1_point(&multiexp_aff); + Ok((required_gas, out)) +} diff --git a/crates/precompile/src/bls12_381/g1_mul.rs b/crates/precompile/src/bls12_381/g1_mul.rs new file mode 100644 index 00000000..171de875 --- /dev/null +++ b/crates/precompile/src/bls12_381/g1_mul.rs @@ -0,0 +1,61 @@ +use blst::{blst_p1, blst_p1_affine, blst_p1_from_affine, blst_p1_mult, blst_p1_to_affine}; +use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; + +use crate::{u64_to_address, PrecompileWithAddress}; + +use super::{ + g1::{encode_g1_point, extract_g1_input, G1_INPUT_ITEM_LENGTH}, + utils::{extract_scalar_input, NBITS}, +}; + +/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G1MUL precompile. +pub const PRECOMPILE: PrecompileWithAddress = + PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(g1_mul)); +/// BLS12_G1MUL precompile address. +pub const ADDRESS: u64 = 0x0c; +/// Base gas fee for BLS12-381 g1_mul operation. +pub(super) const BASE_GAS_FEE: u64 = 12000; + +/// Input length of g1_mul operation. +pub(super) const INPUT_LENGTH: usize = 160; + +/// G1 multiplication call expects `160` bytes as an input that is interpreted as +/// byte concatenation of encoding of G1 point (`128` bytes) and encoding of a +/// scalar value (`32` bytes). +/// Output is an encoding of multiplication operation result - single G1 point +/// (`128` bytes). +/// See also: +pub fn g1_mul(input: &Bytes, gas_limit: u64) -> PrecompileResult { + if BASE_GAS_FEE > gas_limit { + return Err(PrecompileError::OutOfGas); + } + if input.len() != INPUT_LENGTH { + return Err(PrecompileError::Other(format!( + "G1MUL Input should be {INPUT_LENGTH} bits, was {}", + input.len() + ))); + } + + let p0_aff = extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH])?; + let mut p0 = blst_p1::default(); + // SAFETY: p0 and p0_aff are blst values. + unsafe { + blst_p1_from_affine(&mut p0, p0_aff); + } + + let input_scalar0 = extract_scalar_input(&input[G1_INPUT_ITEM_LENGTH..])?; + + let mut p = blst_p1::default(); + // SAFETY: input_scalar0.b has fixed size, p and p0 are blst values. + unsafe { + blst_p1_mult(&mut p, &p0, input_scalar0.b.as_ptr(), NBITS); + } + let mut p_aff = blst_p1_affine::default(); + // SAFETY: p_aff and p are blst values. + unsafe { + blst_p1_to_affine(&mut p_aff, &p); + } + + let out = encode_g1_point(&p_aff); + Ok((BASE_GAS_FEE, out)) +} diff --git a/crates/precompile/src/bls12_381/g2.rs b/crates/precompile/src/bls12_381/g2.rs new file mode 100644 index 00000000..0c861e7f --- /dev/null +++ b/crates/precompile/src/bls12_381/g2.rs @@ -0,0 +1,64 @@ +use blst::{blst_fp_from_bendian, blst_p2_affine, blst_p2_affine_in_g2}; +use revm_primitives::{Bytes, PrecompileError}; + +use super::utils::{fp_to_bytes, remove_padding, FP_LENGTH, PADDED_FP_LENGTH}; + +/// Length of each of the elements in a g2 operation input. +pub(super) const G2_INPUT_ITEM_LENGTH: usize = 256; +/// Output length of a g2 operation. +const G2_OUTPUT_LENGTH: usize = 256; + +/// Encodes a G2 point in affine format into a byte slice with padded elements. +pub(super) fn encode_g2_point(input: *const blst_p2_affine) -> Bytes { + let mut out = vec![0u8; G2_OUTPUT_LENGTH]; + // SAFETY: out comes from fixed length array, input is a blst value. + unsafe { + fp_to_bytes(&mut out[..PADDED_FP_LENGTH], &(*input).x.fp[0]); + fp_to_bytes( + &mut out[PADDED_FP_LENGTH..2 * PADDED_FP_LENGTH], + &(*input).x.fp[1], + ); + fp_to_bytes( + &mut out[2 * PADDED_FP_LENGTH..3 * PADDED_FP_LENGTH], + &(*input).y.fp[0], + ); + fp_to_bytes( + &mut out[3 * PADDED_FP_LENGTH..4 * PADDED_FP_LENGTH], + &(*input).y.fp[1], + ); + } + out.into() +} + +/// Extracts a G2 point in Affine format from a 256 byte slice representation. +pub(super) fn extract_g2_input(input: &[u8]) -> Result<*const blst_p2_affine, PrecompileError> { + if input.len() != G2_INPUT_ITEM_LENGTH { + return Err(PrecompileError::Other(format!( + "Input should be {G2_INPUT_ITEM_LENGTH} bits, was {}", + input.len() + ))); + } + + let mut input_fps: [[u8; FP_LENGTH]; 4] = [[0; FP_LENGTH]; 4]; + for i in 0..4 { + input_fps[i] = remove_padding(&input[i * PADDED_FP_LENGTH..(i + 1) * PADDED_FP_LENGTH])?; + } + + let mut out = blst_p2_affine::default(); + // SAFETY: items in fps have fixed length, out is a blst value. + unsafe { + blst_fp_from_bendian(&mut out.x.fp[0], input_fps[0].as_ptr()); + blst_fp_from_bendian(&mut out.x.fp[1], input_fps[1].as_ptr()); + blst_fp_from_bendian(&mut out.y.fp[0], input_fps[2].as_ptr()); + blst_fp_from_bendian(&mut out.y.fp[1], input_fps[3].as_ptr()); + } + + // SAFETY: out is a blst value. + unsafe { + if !blst_p2_affine_in_g2(&out) { + return Err(PrecompileError::Other("Element not in G2".to_string())); + } + } + + Ok(&mut out as *const _) +} diff --git a/crates/precompile/src/bls12_381/g2_add.rs b/crates/precompile/src/bls12_381/g2_add.rs new file mode 100644 index 00000000..2d7e95ed --- /dev/null +++ b/crates/precompile/src/bls12_381/g2_add.rs @@ -0,0 +1,62 @@ +use blst::{ + blst_p2, blst_p2_add_or_double_affine, blst_p2_affine, blst_p2_from_affine, blst_p2_to_affine, +}; +use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; + +use crate::{u64_to_address, PrecompileWithAddress}; + +use super::g2::{encode_g2_point, extract_g2_input, G2_INPUT_ITEM_LENGTH}; + +/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G2ADD precompile. +pub const PRECOMPILE: PrecompileWithAddress = + PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(g2_add)); +/// BLS12_G2ADD precompile address. +pub const ADDRESS: u64 = 0x0e; +/// Base gas fee for BLS12-381 g2_add operation. +const BASE_GAS_FEE: u64 = 800; + +/// Input length of g2_add operation. +const INPUT_LENGTH: usize = 512; + +/// G2 addition call expects `512` bytes as an input that is interpreted as byte +/// concatenation of two G2 points (`256` bytes each). +/// +/// Output is an encoding of addition operation result - single G2 point (`256` +/// bytes). +/// See also +fn g2_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { + if BASE_GAS_FEE > gas_limit { + return Err(PrecompileError::OutOfGas); + } + + if input.len() != INPUT_LENGTH { + return Err(PrecompileError::Other(format!( + "G2ADD Input should be {INPUT_LENGTH} bits, was {}", + input.len() + ))); + } + + let a_aff = extract_g2_input(&input[..G2_INPUT_ITEM_LENGTH])?; + let b_aff = extract_g2_input(&input[G2_INPUT_ITEM_LENGTH..])?; + + let mut b = blst_p2::default(); + // SAFETY: b and b_aff are blst values. + unsafe { + blst_p2_from_affine(&mut b, b_aff); + } + + let mut p = blst_p2::default(); + // SAFETY: p, b and a_aff are blst values. + unsafe { + blst_p2_add_or_double_affine(&mut p, &b, a_aff); + } + + let mut p_aff = blst_p2_affine::default(); + // SAFETY: p_aff and p are blst values. + unsafe { + blst_p2_to_affine(&mut p_aff, &p); + } + + let out = encode_g2_point(&p_aff); + Ok((BASE_GAS_FEE, out)) +} diff --git a/crates/precompile/src/bls12_381/g2_msm.rs b/crates/precompile/src/bls12_381/g2_msm.rs new file mode 100644 index 00000000..8ea82c20 --- /dev/null +++ b/crates/precompile/src/bls12_381/g2_msm.rs @@ -0,0 +1,77 @@ +use blst::{blst_p2, blst_p2_affine, blst_p2_from_affine, blst_p2_to_affine, p2_affines}; +use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; + +use crate::{u64_to_address, PrecompileWithAddress}; + +use super::{ + g2::{encode_g2_point, extract_g2_input, G2_INPUT_ITEM_LENGTH}, + g2_mul, + msm::msm_required_gas, + utils::{extract_scalar_input, NBITS, SCALAR_LENGTH}, +}; + +/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G2MSM precompile. +pub const PRECOMPILE: PrecompileWithAddress = + PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(g2_msm)); +/// BLS12_G2MSM precompile address. +pub const ADDRESS: u64 = 0x10; + +/// Implements EIP-2537 G2MSM precompile. +/// G2 multi-scalar-multiplication call expects `288*k` bytes as an input that is interpreted +/// as byte concatenation of `k` slices each of them being a byte concatenation +/// of encoding of G2 point (`256` bytes) and encoding of a scalar value (`32` +/// bytes). +/// Output is an encoding of multi-scalar-multiplication operation result - single G2 +/// point (`256` bytes). +/// See also: +fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { + let input_len = input.len(); + if input_len == 0 || input_len % g2_mul::INPUT_LENGTH != 0 { + return Err(PrecompileError::Other(format!( + "G2MSM input length should be multiple of {}, was {}", + g2_mul::INPUT_LENGTH, + input_len + ))); + } + + let k = input_len / g2_mul::INPUT_LENGTH; + let required_gas = msm_required_gas(k, g2_mul::BASE_GAS_FEE); + if required_gas > gas_limit { + return Err(PrecompileError::OutOfGas); + } + + let mut g2_points: Vec = Vec::with_capacity(k); + let mut scalars: Vec = Vec::with_capacity(k * SCALAR_LENGTH); + for i in 0..k { + let p0_aff = extract_g2_input( + &input[i * g2_mul::INPUT_LENGTH..i * g2_mul::INPUT_LENGTH + G2_INPUT_ITEM_LENGTH], + )?; + let mut p0 = blst_p2::default(); + // SAFETY: p0 and p0_aff are blst values. + unsafe { + blst_p2_from_affine(&mut p0, p0_aff); + } + + g2_points.push(p0); + + scalars.extend_from_slice( + &extract_scalar_input( + &input[i * g2_mul::INPUT_LENGTH + G2_INPUT_ITEM_LENGTH + ..i * g2_mul::INPUT_LENGTH + G2_INPUT_ITEM_LENGTH + SCALAR_LENGTH], + )? + .b, + ); + } + + let points = p2_affines::from(&g2_points); + let multiexp = points.mult(&scalars, NBITS); + + let mut multiexp_aff = blst_p2_affine::default(); + // SAFETY: multiexp_aff and multiexp are blst values. + unsafe { + blst_p2_to_affine(&mut multiexp_aff, &multiexp); + } + + let out = encode_g2_point(&multiexp_aff); + Ok((required_gas, out)) +} diff --git a/crates/precompile/src/bls12_381/g2_mul.rs b/crates/precompile/src/bls12_381/g2_mul.rs new file mode 100644 index 00000000..be3f4f9f --- /dev/null +++ b/crates/precompile/src/bls12_381/g2_mul.rs @@ -0,0 +1,61 @@ +use blst::{blst_p2, blst_p2_affine, blst_p2_from_affine, blst_p2_mult, blst_p2_to_affine}; +use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; + +use crate::{u64_to_address, PrecompileWithAddress}; + +use super::{ + g2::{encode_g2_point, extract_g2_input, G2_INPUT_ITEM_LENGTH}, + utils::{extract_scalar_input, NBITS}, +}; + +/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G2MUL precompile. +pub const PRECOMPILE: PrecompileWithAddress = + PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(g2_mul)); +/// BLS12_G2MUL precompile address. +pub const ADDRESS: u64 = 0x0f; +/// Base gas fee for BLS12-381 g2_mul operation. +pub(super) const BASE_GAS_FEE: u64 = 45000; + +/// Input length of g2_mul operation. +pub(super) const INPUT_LENGTH: usize = 288; + +/// G2 multiplication call expects `288` bytes as an input that is interpreted as +/// byte concatenation of encoding of G2 point (`256` bytes) and encoding of a +/// scalar value (`32` bytes). +/// Output is an encoding of multiplication operation result - single G2 point +/// (`256` bytes). +/// See also: +fn g2_mul(input: &Bytes, gas_limit: u64) -> PrecompileResult { + if BASE_GAS_FEE > gas_limit { + return Err(PrecompileError::OutOfGas); + } + if input.len() != INPUT_LENGTH { + return Err(PrecompileError::Other(format!( + "G2MUL Input should be {INPUT_LENGTH} bits, was {}", + input.len() + ))); + } + + let p0_aff = extract_g2_input(&input[..G2_INPUT_ITEM_LENGTH])?; + let mut p0 = blst_p2::default(); + // SAFETY: p0 and p0_aff are blst values. + unsafe { + blst_p2_from_affine(&mut p0, p0_aff); + } + + let input_scalar0 = extract_scalar_input(&input[G2_INPUT_ITEM_LENGTH..])?; + + let mut p = blst_p2::default(); + // SAFETY: input_scalar0.b has fixed size, p and p0 are blst values. + unsafe { + blst_p2_mult(&mut p, &p0, input_scalar0.b.as_ptr(), NBITS); + } + let mut p_aff = blst_p2_affine::default(); + // SAFETY: p_aff and p are blst values. + unsafe { + blst_p2_to_affine(&mut p_aff, &p); + } + + let out = encode_g2_point(&p_aff); + Ok((BASE_GAS_FEE, out)) +} diff --git a/crates/precompile/src/bls12_381/map_fp2_to_g2.rs b/crates/precompile/src/bls12_381/map_fp2_to_g2.rs new file mode 100644 index 00000000..6448dda6 --- /dev/null +++ b/crates/precompile/src/bls12_381/map_fp2_to_g2.rs @@ -0,0 +1,70 @@ +use blst::{ + blst_fp, blst_fp2, blst_fp_from_bendian, blst_map_to_g2, blst_p2, blst_p2_affine, + blst_p2_to_affine, +}; +use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; + +use crate::{u64_to_address, PrecompileWithAddress}; + +use super::{ + g2::encode_g2_point, + utils::{remove_padding, PADDED_FP2_LENGTH, PADDED_FP_LENGTH}, +}; + +/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_MAP_FP2_TO_G2 precompile. +pub const PRECOMPILE: PrecompileWithAddress = + PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(map_fp2_to_g2)); +/// BLS12_MAP_FP2_TO_G2 precompile address. +pub const ADDRESS: u64 = 0x13; +/// Base gas fee for BLS12-381 map_fp2_to_g2 operation. +const BASE_GAS_FEE: u64 = 75000; + +/// Field-to-curve call expects 128 bytes as an input that is interpreted as a +/// an element of Fp2. Output of this call is 256 bytes and is an encoded G2 +/// point. +/// See also: +fn map_fp2_to_g2(input: &Bytes, gas_limit: u64) -> PrecompileResult { + if BASE_GAS_FEE > gas_limit { + return Err(PrecompileError::OutOfGas); + } + + if input.len() != PADDED_FP2_LENGTH { + return Err(PrecompileError::Other(format!( + "MAP_FP2_TO_G2 Input should be {PADDED_FP2_LENGTH} bits, was {}", + input.len() + ))); + } + + let input_p0_x = remove_padding(&input[..PADDED_FP_LENGTH])?; + let input_p0_y = remove_padding(&input[PADDED_FP_LENGTH..PADDED_FP2_LENGTH])?; + + let mut fp2 = blst_fp2::default(); + let mut fp_x = blst_fp::default(); + let mut fp_y = blst_fp::default(); + // SAFETY: input_p0_x has fixed length, fp_x is a blst value. + unsafe { + blst_fp_from_bendian(&mut fp_x, input_p0_x.as_ptr()); + } + // SAFETY: input_p0_y has fixed length, fp_y is a blst value. + unsafe { + blst_fp_from_bendian(&mut fp_y, input_p0_y.as_ptr()); + } + fp2.fp[0] = fp_x; + fp2.fp[1] = fp_y; + + let mut p = blst_p2::default(); + // SAFETY: p and fp2 are blst values. + unsafe { + // third argument is unused if null. + blst_map_to_g2(&mut p, &fp2, std::ptr::null()); + } + + let mut p_aff = blst_p2_affine::default(); + // SAFETY: p_aff and p are blst values. + unsafe { + blst_p2_to_affine(&mut p_aff, &p); + } + + let out = encode_g2_point(&p_aff); + Ok((BASE_GAS_FEE, out)) +} diff --git a/crates/precompile/src/bls12_381/map_fp_to_g1.rs b/crates/precompile/src/bls12_381/map_fp_to_g1.rs new file mode 100644 index 00000000..f0d273f3 --- /dev/null +++ b/crates/precompile/src/bls12_381/map_fp_to_g1.rs @@ -0,0 +1,60 @@ +use blst::{ + blst_fp, blst_fp_from_bendian, blst_map_to_g1, blst_p1, blst_p1_affine, blst_p1_to_affine, +}; +use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; + +use crate::{u64_to_address, PrecompileWithAddress}; + +use super::{ + g1::encode_g1_point, + utils::{remove_padding, PADDED_FP_LENGTH}, +}; + +/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_MAP_FP_TO_G1 precompile. +pub const PRECOMPILE: PrecompileWithAddress = + PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(map_fp_to_g1)); +/// BLS12_MAP_FP_TO_G1 precompile address. +pub const ADDRESS: u64 = 0x12; +/// Base gas fee for BLS12-381 map_fp_to_g1 operation. +const MAP_FP_TO_G1_BASE: u64 = 5500; + +/// Field-to-curve call expects 64 bytes as an input that is interpreted as an +/// element of Fp. Output of this call is 128 bytes and is an encoded G1 point. +/// See also: +fn map_fp_to_g1(input: &Bytes, gas_limit: u64) -> PrecompileResult { + if MAP_FP_TO_G1_BASE > gas_limit { + return Err(PrecompileError::OutOfGas); + } + + if input.len() != PADDED_FP_LENGTH { + return Err(PrecompileError::Other(format!( + "MAP_FP_TO_G1 Input should be {PADDED_FP_LENGTH} bits, was {}", + input.len() + ))); + } + + let input_p0 = remove_padding(input)?; + + let mut fp = blst_fp::default(); + + // SAFETY: input_p0 has fixed length, fp is a blst value. + unsafe { + blst_fp_from_bendian(&mut fp, input_p0.as_ptr()); + } + + let mut p = blst_p1::default(); + // SAFETY: p and fp are blst values. + unsafe { + // third argument is unused if null. + blst_map_to_g1(&mut p, &fp, std::ptr::null()); + } + + let mut p_aff = blst_p1_affine::default(); + // SAFETY: p_aff and p are blst values. + unsafe { + blst_p1_to_affine(&mut p_aff, &p); + } + + let out = encode_g1_point(&p_aff); + Ok((MAP_FP_TO_G1_BASE, out)) +} diff --git a/crates/precompile/src/bls12_381/mod.rs b/crates/precompile/src/bls12_381/mod.rs new file mode 100644 index 00000000..764c4a50 --- /dev/null +++ b/crates/precompile/src/bls12_381/mod.rs @@ -0,0 +1,31 @@ +use crate::PrecompileWithAddress; + +mod g1; +pub mod g1_add; +pub mod g1_msm; +pub mod g1_mul; +mod g2; +pub mod g2_add; +pub mod g2_msm; +pub mod g2_mul; +pub mod map_fp2_to_g2; +pub mod map_fp_to_g1; +mod msm; +pub mod pairing; +mod utils; + +/// Returns the BLS12-381 precompiles with their addresses. +pub fn precompiles() -> impl Iterator { + [ + g1_add::PRECOMPILE, + g1_mul::PRECOMPILE, + g1_msm::PRECOMPILE, + g2_add::PRECOMPILE, + g2_mul::PRECOMPILE, + g2_msm::PRECOMPILE, + pairing::PRECOMPILE, + map_fp_to_g1::PRECOMPILE, + map_fp2_to_g2::PRECOMPILE, + ] + .into_iter() +} diff --git a/crates/precompile/src/bls12_381/msm.rs b/crates/precompile/src/bls12_381/msm.rs new file mode 100644 index 00000000..e26ea3eb --- /dev/null +++ b/crates/precompile/src/bls12_381/msm.rs @@ -0,0 +1,28 @@ +/// Amount used to calculate the multi-scalar-multiplication discount. +const MSM_MULTIPLIER: u64 = 1000; +/// Table of gas discounts for multi-scalar-multiplication operations. +const MSM_DISCOUNT_TABLE: [u64; 128] = [ + 1200, 888, 764, 641, 594, 547, 500, 453, 438, 423, 408, 394, 379, 364, 349, 334, 330, 326, 322, + 318, 314, 310, 306, 302, 298, 294, 289, 285, 281, 277, 273, 269, 268, 266, 265, 263, 262, 260, + 259, 257, 256, 254, 253, 251, 250, 248, 247, 245, 244, 242, 241, 239, 238, 236, 235, 233, 232, + 231, 229, 228, 226, 225, 223, 222, 221, 220, 219, 219, 218, 217, 216, 216, 215, 214, 213, 213, + 212, 211, 211, 210, 209, 208, 208, 207, 206, 205, 205, 204, 203, 202, 202, 201, 200, 199, 199, + 198, 197, 196, 196, 195, 194, 193, 193, 192, 191, 191, 190, 189, 188, 188, 187, 186, 185, 185, + 184, 183, 182, 182, 181, 180, 179, 179, 178, 177, 176, 176, 175, 174, +]; + +/// Implements the gas schedule for G1/G2 Multiscalar-multiplication assuming 30 +/// MGas/second, see also: +pub(super) fn msm_required_gas(k: usize, multiplication_cost: u64) -> u64 { + if k == 0 { + return 0; + } + + let discount = if k < MSM_DISCOUNT_TABLE.len() { + MSM_DISCOUNT_TABLE[k - 1] + } else { + MSM_DISCOUNT_TABLE[MSM_DISCOUNT_TABLE.len() - 1] + }; + + (k as u64 * discount * multiplication_cost) / MSM_MULTIPLIER +} diff --git a/crates/precompile/src/bls12_381/pairing.rs b/crates/precompile/src/bls12_381/pairing.rs new file mode 100644 index 00000000..2cd5cf9a --- /dev/null +++ b/crates/precompile/src/bls12_381/pairing.rs @@ -0,0 +1,95 @@ +use blst::{blst_final_exp, blst_fp12, blst_fp12_is_one, blst_fp12_mul, blst_miller_loop}; +use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult, B256}; + +use crate::{u64_to_address, PrecompileWithAddress}; + +use super::{ + g1::{extract_g1_input, G1_INPUT_ITEM_LENGTH}, + g2::{extract_g2_input, G2_INPUT_ITEM_LENGTH}, +}; + +/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_PAIRING precompile. +pub const PRECOMPILE: PrecompileWithAddress = + PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(pairing)); +/// BLS12_PAIRING precompile address. +pub const ADDRESS: u64 = 0x11; + +/// Multiplier gas fee for BLS12-381 pairing operation. +const PAIRING_MULTIPLIER_BASE: u64 = 43000; +/// Offset gas fee for BLS12-381 pairing operation. +const PAIRING_OFFSET_BASE: u64 = 65000; +/// Input length of paitring operation. +const INPUT_LENGTH: usize = 384; + +/// Pairing call expects 384*k (k being a positive integer) bytes as an inputs +/// that is interpreted as byte concatenation of k slices. Each slice has the +/// following structure: +/// * 128 bytes of G1 point encoding +/// * 256 bytes of G2 point encoding +/// Each point is expected to be in the subgroup of order q. +/// Output is a 32 bytes where first 31 bytes are equal to 0x00 and the last byte +/// is 0x01 if pairing result is equal to the multiplicative identity in a pairing +/// target field and 0x00 otherwise. +/// See also: +fn pairing(input: &Bytes, gas_limit: u64) -> PrecompileResult { + let input_len = input.len(); + if input_len == 0 || input_len % INPUT_LENGTH != 0 { + return Err(PrecompileError::Other(format!( + "Pairing input length should be multiple of {INPUT_LENGTH}, was {input_len}" + ))); + } + + let k = input_len / INPUT_LENGTH; + let required_gas: u64 = PAIRING_MULTIPLIER_BASE * k as u64 + PAIRING_OFFSET_BASE; + if required_gas > gas_limit { + return Err(PrecompileError::OutOfGas); + } + + // accumulator for the fp12 multiplications of the miller loops. + let mut acc = blst_fp12::default(); + for i in 0..k { + let p1_aff = + extract_g1_input(&input[i * INPUT_LENGTH..i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH])?; + + let p2_aff = extract_g2_input( + &input[i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + ..i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + G2_INPUT_ITEM_LENGTH], + )?; + + if i > 0 { + // after the first slice (i>0) we use cur_ml to store the current + // miller loop and accumulate with the previous results using a fp12 + // multiplication. + let mut cur_ml = blst_fp12::default(); + let mut res = blst_fp12::default(); + // SAFETY: res, acc, cur_ml, p1_aff and p2_aff are blst values. + unsafe { + blst_miller_loop(&mut cur_ml, p2_aff, p1_aff); + blst_fp12_mul(&mut res, &acc, &cur_ml); + } + acc = res; + } else { + // on the first slice (i==0) there is no previous results and no need + // to accumulate. + // SAFETY: acc, p1_aff and p2_aff are blst values. + unsafe { + blst_miller_loop(&mut acc, p2_aff, p1_aff); + } + } + } + + // SAFETY: ret and acc are blst values. + let mut ret = blst_fp12::default(); + unsafe { + blst_final_exp(&mut ret, &acc); + } + + let mut result: u8 = 0; + // SAFETY: ret is a blst value. + unsafe { + if blst_fp12_is_one(&ret) { + result = 1; + } + } + Ok((required_gas, B256::with_last_byte(result).into())) +} diff --git a/crates/precompile/src/bls12_381/utils.rs b/crates/precompile/src/bls12_381/utils.rs new file mode 100644 index 00000000..38673d66 --- /dev/null +++ b/crates/precompile/src/bls12_381/utils.rs @@ -0,0 +1,65 @@ +use blst::{blst_bendian_from_fp, blst_fp, blst_scalar, blst_scalar_from_bendian}; +use revm_primitives::PrecompileError; + +/// Number of bits used in the BLS12-381 curve finite field elements. +pub(super) const NBITS: usize = 256; +/// Finite field element input length. +pub(super) const FP_LENGTH: usize = 48; +/// Finite field element padded input length. +pub(super) const PADDED_FP_LENGTH: usize = 64; +/// Quadratic extension of finite field element input length. +pub(super) const PADDED_FP2_LENGTH: usize = 128; +/// Input elements padding length. +pub(super) const PADDING_LENGTH: usize = 16; +/// Scalar length. +pub(super) const SCALAR_LENGTH: usize = 32; + +/// Encodes a single finite field element into a byte slice with padding. +pub(super) fn fp_to_bytes(out: &mut [u8], input: *const blst_fp) { + if out.len() != PADDED_FP_LENGTH { + return; + } + for item in out.iter_mut().take(PADDING_LENGTH) { + *item = 0; + } + // SAFETY: out length is checked previously, input is a blst value. + unsafe { + blst_bendian_from_fp(out[PADDING_LENGTH..].as_mut_ptr(), input); + } +} + +/// Removes zeros with which the precompile inputs are left padded to 64 bytes. +pub(super) fn remove_padding(input: &[u8]) -> Result<[u8; FP_LENGTH], PrecompileError> { + if input.len() != PADDED_FP_LENGTH { + return Err(PrecompileError::Other(format!( + "Padded Input should be {PADDED_FP_LENGTH} bits, was {}", + input.len() + ))); + } + if !input.iter().take(PADDING_LENGTH).all(|&x| x == 0) { + return Err(PrecompileError::Other(format!( + "{PADDING_LENGTH} top bytes of input are not zero", + ))); + } + + let sliced = &input[PADDING_LENGTH..PADDED_FP_LENGTH]; + <[u8; FP_LENGTH]>::try_from(sliced).map_err(|e| PrecompileError::Other(format!("{e}"))) +} + +/// Extracts an Scalar from a 32 byte slice representation. +pub(super) fn extract_scalar_input(input: &[u8]) -> Result { + if input.len() != SCALAR_LENGTH { + return Err(PrecompileError::Other(format!( + "Input should be {SCALAR_LENGTH} bits, was {}", + input.len() + ))); + } + + let mut out = blst_scalar::default(); + // SAFETY: input length is checked previously, out is a blst value. + unsafe { + blst_scalar_from_bendian(&mut out, input.as_ptr()); + } + + Ok(out) +} diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index 7903d38b..97c4282d 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -9,6 +9,8 @@ extern crate alloc as std; pub mod blake2; +#[cfg(feature = "blst")] +pub mod bls12_381; pub mod bn128; pub mod hash; pub mod identity; @@ -159,10 +161,16 @@ impl Precompiles { pub fn prague() -> &'static Self { static INSTANCE: OnceBox = OnceBox::new(); INSTANCE.get_or_init(|| { - let precompiles = Self::cancun().clone(); - // EIP-2537: Precompile for BLS12-381 curve operations - // TODO(alexey): add BLS12-381 precompiles - // precompiles.extend(bls12_381::precompiles()); + let precompiles = Self::berlin().clone(); + + // Don't include BLS12-381 precompiles in no_std builds. + #[cfg(feature = "blst")] + let precompiles = { + let mut precompiles = precompiles; + precompiles.extend(bls12_381::precompiles()); + precompiles + }; + Box::new(precompiles) }) } diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 7ddb7175..9b8446ad 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -70,7 +70,7 @@ alloy-provider = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6d alloy-transport-http = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6d" } [features] -default = ["std", "c-kzg", "secp256k1", "portable"] +default = ["std", "c-kzg", "secp256k1", "portable", "blst"] std = [ "serde?/std", "serde_json?/std", @@ -134,6 +134,7 @@ optional_beneficiary_reward = ["revm-interpreter/optional_beneficiary_reward"] # See comments in `revm-precompile` secp256k1 = ["revm-precompile/secp256k1"] c-kzg = ["revm-precompile/c-kzg"] +blst = ["revm-precompile/blst"] [[example]] name = "fork_ref_transact" From a4b466ab36abb0ca1792174da99e219a4180255f Mon Sep 17 00:00:00 2001 From: Alexey Shekhirin Date: Fri, 10 May 2024 13:13:36 +0100 Subject: [PATCH 062/105] fix(precompile): inherit Prague precompiles from Cancun (#1392) --- crates/precompile/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index 97c4282d..fe2486d3 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -161,7 +161,7 @@ impl Precompiles { pub fn prague() -> &'static Self { static INSTANCE: OnceBox = OnceBox::new(); INSTANCE.get_or_init(|| { - let precompiles = Self::berlin().clone(); + let precompiles = Self::cancun().clone(); // Don't include BLS12-381 precompiles in no_std builds. #[cfg(feature = "blst")] From ebbd76ac11e5e197d161cf55f53411446b520d62 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Fri, 10 May 2024 19:16:19 +0200 Subject: [PATCH 063/105] fix(precompile): blst dangling pointers, cleanup (#1391) * fix(precompile): blst dangling pointers, cleanup * chore: correct error message --- crates/precompile/src/bls12_381/g1.rs | 15 +++--- crates/precompile/src/bls12_381/g1_add.rs | 24 ++++------ crates/precompile/src/bls12_381/g1_msm.rs | 19 +++----- crates/precompile/src/bls12_381/g1_mul.rs | 24 ++++------ crates/precompile/src/bls12_381/g2.rs | 48 ++++++++----------- crates/precompile/src/bls12_381/g2_add.rs | 24 ++++------ crates/precompile/src/bls12_381/g2_msm.rs | 18 +++---- crates/precompile/src/bls12_381/g2_mul.rs | 24 ++++------ .../precompile/src/bls12_381/map_fp2_to_g2.rs | 32 +++++-------- .../precompile/src/bls12_381/map_fp_to_g1.rs | 28 ++++------- crates/precompile/src/bls12_381/msm.rs | 10 ++-- crates/precompile/src/bls12_381/pairing.rs | 12 ++--- crates/precompile/src/bls12_381/utils.rs | 26 ++++------ 13 files changed, 111 insertions(+), 193 deletions(-) diff --git a/crates/precompile/src/bls12_381/g1.rs b/crates/precompile/src/bls12_381/g1.rs index 28e5a845..163afb3e 100644 --- a/crates/precompile/src/bls12_381/g1.rs +++ b/crates/precompile/src/bls12_381/g1.rs @@ -1,8 +1,7 @@ +use super::utils::{fp_to_bytes, remove_padding, PADDED_FP_LENGTH}; use blst::{blst_fp_from_bendian, blst_p1_affine, blst_p1_affine_in_g1}; use revm_primitives::{Bytes, PrecompileError}; -use super::utils::{fp_to_bytes, remove_padding, PADDED_FP_LENGTH}; - /// Length of each of the elements in a g1 operation input. pub(super) const G1_INPUT_ITEM_LENGTH: usize = 128; /// Output length of a g1 operation. @@ -20,10 +19,10 @@ pub(super) fn encode_g1_point(input: *const blst_p1_affine) -> Bytes { } /// Extracts a G1 point in Affine format from a 128 byte slice representation. -pub(super) fn extract_g1_input(input: &[u8]) -> Result<*const blst_p1_affine, PrecompileError> { +pub(super) fn extract_g1_input(input: &[u8]) -> Result { if input.len() != G1_INPUT_ITEM_LENGTH { return Err(PrecompileError::Other(format!( - "Input should be {G1_INPUT_ITEM_LENGTH} bits, was {}", + "Input should be {G1_INPUT_ITEM_LENGTH} bytes, was {}", input.len() ))); } @@ -39,10 +38,8 @@ pub(super) fn extract_g1_input(input: &[u8]) -> Result<*const blst_p1_affine, Pr } // SAFETY: out is a blst value. - unsafe { - if !blst_p1_affine_in_g1(&out) { - return Err(PrecompileError::Other("Element not in G1".to_string())); - } + if unsafe { !blst_p1_affine_in_g1(&out) } { + return Err(PrecompileError::Other("Element not in G1".to_string())); } - Ok(&mut out as *const _) + Ok(out) } diff --git a/crates/precompile/src/bls12_381/g1_add.rs b/crates/precompile/src/bls12_381/g1_add.rs index e3adba01..358ab0cc 100644 --- a/crates/precompile/src/bls12_381/g1_add.rs +++ b/crates/precompile/src/bls12_381/g1_add.rs @@ -1,12 +1,10 @@ +use super::g1::{encode_g1_point, extract_g1_input, G1_INPUT_ITEM_LENGTH}; +use crate::{u64_to_address, PrecompileWithAddress}; use blst::{ blst_p1, blst_p1_add_or_double_affine, blst_p1_affine, blst_p1_from_affine, blst_p1_to_affine, }; use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; -use crate::{u64_to_address, PrecompileWithAddress}; - -use super::g1::{encode_g1_point, extract_g1_input, G1_INPUT_ITEM_LENGTH}; - /// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G1ADD precompile. pub const PRECOMPILE: PrecompileWithAddress = PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(g1_add)); @@ -30,31 +28,25 @@ fn g1_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { if input.len() != INPUT_LENGTH { return Err(PrecompileError::Other(format!( - "G1ADD Input should be {INPUT_LENGTH} bits, was {}", + "G1ADD input should be {INPUT_LENGTH} bytes, was {}", input.len() ))); } - let a_aff = extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH])?; - let b_aff = extract_g1_input(&input[G1_INPUT_ITEM_LENGTH..])?; + let a_aff = &extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH])?; + let b_aff = &extract_g1_input(&input[G1_INPUT_ITEM_LENGTH..])?; let mut b = blst_p1::default(); // SAFETY: b and b_aff are blst values. - unsafe { - blst_p1_from_affine(&mut b, b_aff); - } + unsafe { blst_p1_from_affine(&mut b, b_aff) }; let mut p = blst_p1::default(); // SAFETY: p, b and a_aff are blst values. - unsafe { - blst_p1_add_or_double_affine(&mut p, &b, a_aff); - } + unsafe { blst_p1_add_or_double_affine(&mut p, &b, a_aff) }; let mut p_aff = blst_p1_affine::default(); // SAFETY: p_aff and p are blst values. - unsafe { - blst_p1_to_affine(&mut p_aff, &p); - } + unsafe { blst_p1_to_affine(&mut p_aff, &p) }; let out = encode_g1_point(&p_aff); Ok((BASE_GAS_FEE, out)) diff --git a/crates/precompile/src/bls12_381/g1_msm.rs b/crates/precompile/src/bls12_381/g1_msm.rs index a339d860..c02f055b 100644 --- a/crates/precompile/src/bls12_381/g1_msm.rs +++ b/crates/precompile/src/bls12_381/g1_msm.rs @@ -1,14 +1,12 @@ -use blst::{blst_p1, blst_p1_affine, blst_p1_from_affine, blst_p1_to_affine, p1_affines}; -use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; - -use crate::{u64_to_address, PrecompileWithAddress}; - use super::{ g1::{encode_g1_point, extract_g1_input, G1_INPUT_ITEM_LENGTH}, g1_mul, msm::msm_required_gas, utils::{extract_scalar_input, NBITS, SCALAR_LENGTH}, }; +use crate::{u64_to_address, PrecompileWithAddress}; +use blst::{blst_p1, blst_p1_affine, blst_p1_from_affine, blst_p1_to_affine, p1_affines}; +use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; /// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G1MSM precompile. pub const PRECOMPILE: PrecompileWithAddress = @@ -43,15 +41,12 @@ fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { let mut g1_points: Vec = Vec::with_capacity(k); let mut scalars: Vec = Vec::with_capacity(k * SCALAR_LENGTH); for i in 0..k { - let p0_aff = extract_g1_input( + let p0_aff = &extract_g1_input( &input[i * g1_mul::INPUT_LENGTH..i * g1_mul::INPUT_LENGTH + G1_INPUT_ITEM_LENGTH], )?; let mut p0 = blst_p1::default(); // SAFETY: p0 and p0_aff are blst values. - unsafe { - blst_p1_from_affine(&mut p0, p0_aff); - } - + unsafe { blst_p1_from_affine(&mut p0, p0_aff) }; g1_points.push(p0); scalars.extend_from_slice( @@ -68,9 +63,7 @@ fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { let mut multiexp_aff = blst_p1_affine::default(); // SAFETY: multiexp_aff and multiexp are blst values. - unsafe { - blst_p1_to_affine(&mut multiexp_aff, &multiexp); - } + unsafe { blst_p1_to_affine(&mut multiexp_aff, &multiexp) }; let out = encode_g1_point(&multiexp_aff); Ok((required_gas, out)) diff --git a/crates/precompile/src/bls12_381/g1_mul.rs b/crates/precompile/src/bls12_381/g1_mul.rs index 171de875..8982cb58 100644 --- a/crates/precompile/src/bls12_381/g1_mul.rs +++ b/crates/precompile/src/bls12_381/g1_mul.rs @@ -1,12 +1,10 @@ -use blst::{blst_p1, blst_p1_affine, blst_p1_from_affine, blst_p1_mult, blst_p1_to_affine}; -use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; - -use crate::{u64_to_address, PrecompileWithAddress}; - use super::{ g1::{encode_g1_point, extract_g1_input, G1_INPUT_ITEM_LENGTH}, utils::{extract_scalar_input, NBITS}, }; +use crate::{u64_to_address, PrecompileWithAddress}; +use blst::{blst_p1, blst_p1_affine, blst_p1_from_affine, blst_p1_mult, blst_p1_to_affine}; +use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; /// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G1MUL precompile. pub const PRECOMPILE: PrecompileWithAddress = @@ -31,30 +29,24 @@ pub fn g1_mul(input: &Bytes, gas_limit: u64) -> PrecompileResult { } if input.len() != INPUT_LENGTH { return Err(PrecompileError::Other(format!( - "G1MUL Input should be {INPUT_LENGTH} bits, was {}", + "G1MUL input should be {INPUT_LENGTH} bytes, was {}", input.len() ))); } - let p0_aff = extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH])?; + let p0_aff = &extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH])?; let mut p0 = blst_p1::default(); // SAFETY: p0 and p0_aff are blst values. - unsafe { - blst_p1_from_affine(&mut p0, p0_aff); - } + unsafe { blst_p1_from_affine(&mut p0, p0_aff) }; let input_scalar0 = extract_scalar_input(&input[G1_INPUT_ITEM_LENGTH..])?; let mut p = blst_p1::default(); // SAFETY: input_scalar0.b has fixed size, p and p0 are blst values. - unsafe { - blst_p1_mult(&mut p, &p0, input_scalar0.b.as_ptr(), NBITS); - } + unsafe { blst_p1_mult(&mut p, &p0, input_scalar0.b.as_ptr(), NBITS) }; let mut p_aff = blst_p1_affine::default(); // SAFETY: p_aff and p are blst values. - unsafe { - blst_p1_to_affine(&mut p_aff, &p); - } + unsafe { blst_p1_to_affine(&mut p_aff, &p) }; let out = encode_g1_point(&p_aff); Ok((BASE_GAS_FEE, out)) diff --git a/crates/precompile/src/bls12_381/g2.rs b/crates/precompile/src/bls12_381/g2.rs index 0c861e7f..538bc5be 100644 --- a/crates/precompile/src/bls12_381/g2.rs +++ b/crates/precompile/src/bls12_381/g2.rs @@ -1,45 +1,41 @@ +use super::utils::{fp_to_bytes, remove_padding, FP_LENGTH, PADDED_FP_LENGTH}; use blst::{blst_fp_from_bendian, blst_p2_affine, blst_p2_affine_in_g2}; use revm_primitives::{Bytes, PrecompileError}; -use super::utils::{fp_to_bytes, remove_padding, FP_LENGTH, PADDED_FP_LENGTH}; - /// Length of each of the elements in a g2 operation input. pub(super) const G2_INPUT_ITEM_LENGTH: usize = 256; /// Output length of a g2 operation. const G2_OUTPUT_LENGTH: usize = 256; /// Encodes a G2 point in affine format into a byte slice with padded elements. -pub(super) fn encode_g2_point(input: *const blst_p2_affine) -> Bytes { +pub(super) fn encode_g2_point(input: &blst_p2_affine) -> Bytes { let mut out = vec![0u8; G2_OUTPUT_LENGTH]; - // SAFETY: out comes from fixed length array, input is a blst value. - unsafe { - fp_to_bytes(&mut out[..PADDED_FP_LENGTH], &(*input).x.fp[0]); - fp_to_bytes( - &mut out[PADDED_FP_LENGTH..2 * PADDED_FP_LENGTH], - &(*input).x.fp[1], - ); - fp_to_bytes( - &mut out[2 * PADDED_FP_LENGTH..3 * PADDED_FP_LENGTH], - &(*input).y.fp[0], - ); - fp_to_bytes( - &mut out[3 * PADDED_FP_LENGTH..4 * PADDED_FP_LENGTH], - &(*input).y.fp[1], - ); - } + fp_to_bytes(&mut out[..PADDED_FP_LENGTH], &input.x.fp[0]); + fp_to_bytes( + &mut out[PADDED_FP_LENGTH..2 * PADDED_FP_LENGTH], + &input.x.fp[1], + ); + fp_to_bytes( + &mut out[2 * PADDED_FP_LENGTH..3 * PADDED_FP_LENGTH], + &input.y.fp[0], + ); + fp_to_bytes( + &mut out[3 * PADDED_FP_LENGTH..4 * PADDED_FP_LENGTH], + &input.y.fp[1], + ); out.into() } /// Extracts a G2 point in Affine format from a 256 byte slice representation. -pub(super) fn extract_g2_input(input: &[u8]) -> Result<*const blst_p2_affine, PrecompileError> { +pub(super) fn extract_g2_input(input: &[u8]) -> Result { if input.len() != G2_INPUT_ITEM_LENGTH { return Err(PrecompileError::Other(format!( - "Input should be {G2_INPUT_ITEM_LENGTH} bits, was {}", + "Input should be {G2_INPUT_ITEM_LENGTH} bytes, was {}", input.len() ))); } - let mut input_fps: [[u8; FP_LENGTH]; 4] = [[0; FP_LENGTH]; 4]; + let mut input_fps: [&[u8; FP_LENGTH]; 4] = [&[0; FP_LENGTH]; 4]; for i in 0..4 { input_fps[i] = remove_padding(&input[i * PADDED_FP_LENGTH..(i + 1) * PADDED_FP_LENGTH])?; } @@ -54,11 +50,9 @@ pub(super) fn extract_g2_input(input: &[u8]) -> Result<*const blst_p2_affine, Pr } // SAFETY: out is a blst value. - unsafe { - if !blst_p2_affine_in_g2(&out) { - return Err(PrecompileError::Other("Element not in G2".to_string())); - } + if unsafe { !blst_p2_affine_in_g2(&out) } { + return Err(PrecompileError::Other("Element not in G2".to_string())); } - Ok(&mut out as *const _) + Ok(out) } diff --git a/crates/precompile/src/bls12_381/g2_add.rs b/crates/precompile/src/bls12_381/g2_add.rs index 2d7e95ed..28ca3f81 100644 --- a/crates/precompile/src/bls12_381/g2_add.rs +++ b/crates/precompile/src/bls12_381/g2_add.rs @@ -1,12 +1,10 @@ +use super::g2::{encode_g2_point, extract_g2_input, G2_INPUT_ITEM_LENGTH}; +use crate::{u64_to_address, PrecompileWithAddress}; use blst::{ blst_p2, blst_p2_add_or_double_affine, blst_p2_affine, blst_p2_from_affine, blst_p2_to_affine, }; use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; -use crate::{u64_to_address, PrecompileWithAddress}; - -use super::g2::{encode_g2_point, extract_g2_input, G2_INPUT_ITEM_LENGTH}; - /// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G2ADD precompile. pub const PRECOMPILE: PrecompileWithAddress = PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(g2_add)); @@ -31,31 +29,25 @@ fn g2_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { if input.len() != INPUT_LENGTH { return Err(PrecompileError::Other(format!( - "G2ADD Input should be {INPUT_LENGTH} bits, was {}", + "G2ADD input should be {INPUT_LENGTH} bytes, was {}", input.len() ))); } - let a_aff = extract_g2_input(&input[..G2_INPUT_ITEM_LENGTH])?; - let b_aff = extract_g2_input(&input[G2_INPUT_ITEM_LENGTH..])?; + let a_aff = &extract_g2_input(&input[..G2_INPUT_ITEM_LENGTH])?; + let b_aff = &extract_g2_input(&input[G2_INPUT_ITEM_LENGTH..])?; let mut b = blst_p2::default(); // SAFETY: b and b_aff are blst values. - unsafe { - blst_p2_from_affine(&mut b, b_aff); - } + unsafe { blst_p2_from_affine(&mut b, b_aff) }; let mut p = blst_p2::default(); // SAFETY: p, b and a_aff are blst values. - unsafe { - blst_p2_add_or_double_affine(&mut p, &b, a_aff); - } + unsafe { blst_p2_add_or_double_affine(&mut p, &b, a_aff) }; let mut p_aff = blst_p2_affine::default(); // SAFETY: p_aff and p are blst values. - unsafe { - blst_p2_to_affine(&mut p_aff, &p); - } + unsafe { blst_p2_to_affine(&mut p_aff, &p) }; let out = encode_g2_point(&p_aff); Ok((BASE_GAS_FEE, out)) diff --git a/crates/precompile/src/bls12_381/g2_msm.rs b/crates/precompile/src/bls12_381/g2_msm.rs index 8ea82c20..a17c5c47 100644 --- a/crates/precompile/src/bls12_381/g2_msm.rs +++ b/crates/precompile/src/bls12_381/g2_msm.rs @@ -1,14 +1,12 @@ -use blst::{blst_p2, blst_p2_affine, blst_p2_from_affine, blst_p2_to_affine, p2_affines}; -use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; - -use crate::{u64_to_address, PrecompileWithAddress}; - use super::{ g2::{encode_g2_point, extract_g2_input, G2_INPUT_ITEM_LENGTH}, g2_mul, msm::msm_required_gas, utils::{extract_scalar_input, NBITS, SCALAR_LENGTH}, }; +use crate::{u64_to_address, PrecompileWithAddress}; +use blst::{blst_p2, blst_p2_affine, blst_p2_from_affine, blst_p2_to_affine, p2_affines}; +use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; /// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G2MSM precompile. pub const PRECOMPILE: PrecompileWithAddress = @@ -43,14 +41,12 @@ fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { let mut g2_points: Vec = Vec::with_capacity(k); let mut scalars: Vec = Vec::with_capacity(k * SCALAR_LENGTH); for i in 0..k { - let p0_aff = extract_g2_input( + let p0_aff = &extract_g2_input( &input[i * g2_mul::INPUT_LENGTH..i * g2_mul::INPUT_LENGTH + G2_INPUT_ITEM_LENGTH], )?; let mut p0 = blst_p2::default(); // SAFETY: p0 and p0_aff are blst values. - unsafe { - blst_p2_from_affine(&mut p0, p0_aff); - } + unsafe { blst_p2_from_affine(&mut p0, p0_aff) }; g2_points.push(p0); @@ -68,9 +64,7 @@ fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { let mut multiexp_aff = blst_p2_affine::default(); // SAFETY: multiexp_aff and multiexp are blst values. - unsafe { - blst_p2_to_affine(&mut multiexp_aff, &multiexp); - } + unsafe { blst_p2_to_affine(&mut multiexp_aff, &multiexp) }; let out = encode_g2_point(&multiexp_aff); Ok((required_gas, out)) diff --git a/crates/precompile/src/bls12_381/g2_mul.rs b/crates/precompile/src/bls12_381/g2_mul.rs index be3f4f9f..d7d6883b 100644 --- a/crates/precompile/src/bls12_381/g2_mul.rs +++ b/crates/precompile/src/bls12_381/g2_mul.rs @@ -1,12 +1,10 @@ -use blst::{blst_p2, blst_p2_affine, blst_p2_from_affine, blst_p2_mult, blst_p2_to_affine}; -use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; - -use crate::{u64_to_address, PrecompileWithAddress}; - use super::{ g2::{encode_g2_point, extract_g2_input, G2_INPUT_ITEM_LENGTH}, utils::{extract_scalar_input, NBITS}, }; +use crate::{u64_to_address, PrecompileWithAddress}; +use blst::{blst_p2, blst_p2_affine, blst_p2_from_affine, blst_p2_mult, blst_p2_to_affine}; +use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; /// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G2MUL precompile. pub const PRECOMPILE: PrecompileWithAddress = @@ -31,30 +29,24 @@ fn g2_mul(input: &Bytes, gas_limit: u64) -> PrecompileResult { } if input.len() != INPUT_LENGTH { return Err(PrecompileError::Other(format!( - "G2MUL Input should be {INPUT_LENGTH} bits, was {}", + "G2MUL input should be {INPUT_LENGTH} bytes, was {}", input.len() ))); } - let p0_aff = extract_g2_input(&input[..G2_INPUT_ITEM_LENGTH])?; + let p0_aff = &extract_g2_input(&input[..G2_INPUT_ITEM_LENGTH])?; let mut p0 = blst_p2::default(); // SAFETY: p0 and p0_aff are blst values. - unsafe { - blst_p2_from_affine(&mut p0, p0_aff); - } + unsafe { blst_p2_from_affine(&mut p0, p0_aff) }; let input_scalar0 = extract_scalar_input(&input[G2_INPUT_ITEM_LENGTH..])?; let mut p = blst_p2::default(); // SAFETY: input_scalar0.b has fixed size, p and p0 are blst values. - unsafe { - blst_p2_mult(&mut p, &p0, input_scalar0.b.as_ptr(), NBITS); - } + unsafe { blst_p2_mult(&mut p, &p0, input_scalar0.b.as_ptr(), NBITS) }; let mut p_aff = blst_p2_affine::default(); // SAFETY: p_aff and p are blst values. - unsafe { - blst_p2_to_affine(&mut p_aff, &p); - } + unsafe { blst_p2_to_affine(&mut p_aff, &p) }; let out = encode_g2_point(&p_aff); Ok((BASE_GAS_FEE, out)) diff --git a/crates/precompile/src/bls12_381/map_fp2_to_g2.rs b/crates/precompile/src/bls12_381/map_fp2_to_g2.rs index 6448dda6..4615ffd8 100644 --- a/crates/precompile/src/bls12_381/map_fp2_to_g2.rs +++ b/crates/precompile/src/bls12_381/map_fp2_to_g2.rs @@ -1,16 +1,14 @@ +use super::{ + g2::encode_g2_point, + utils::{remove_padding, PADDED_FP2_LENGTH, PADDED_FP_LENGTH}, +}; +use crate::{u64_to_address, PrecompileWithAddress}; use blst::{ blst_fp, blst_fp2, blst_fp_from_bendian, blst_map_to_g2, blst_p2, blst_p2_affine, blst_p2_to_affine, }; use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; -use crate::{u64_to_address, PrecompileWithAddress}; - -use super::{ - g2::encode_g2_point, - utils::{remove_padding, PADDED_FP2_LENGTH, PADDED_FP_LENGTH}, -}; - /// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_MAP_FP2_TO_G2 precompile. pub const PRECOMPILE: PrecompileWithAddress = PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(map_fp2_to_g2)); @@ -30,7 +28,7 @@ fn map_fp2_to_g2(input: &Bytes, gas_limit: u64) -> PrecompileResult { if input.len() != PADDED_FP2_LENGTH { return Err(PrecompileError::Other(format!( - "MAP_FP2_TO_G2 Input should be {PADDED_FP2_LENGTH} bits, was {}", + "MAP_FP2_TO_G2 input should be {PADDED_FP2_LENGTH} bytes, was {}", input.len() ))); } @@ -42,28 +40,20 @@ fn map_fp2_to_g2(input: &Bytes, gas_limit: u64) -> PrecompileResult { let mut fp_x = blst_fp::default(); let mut fp_y = blst_fp::default(); // SAFETY: input_p0_x has fixed length, fp_x is a blst value. - unsafe { - blst_fp_from_bendian(&mut fp_x, input_p0_x.as_ptr()); - } + unsafe { blst_fp_from_bendian(&mut fp_x, input_p0_x.as_ptr()) }; // SAFETY: input_p0_y has fixed length, fp_y is a blst value. - unsafe { - blst_fp_from_bendian(&mut fp_y, input_p0_y.as_ptr()); - } + unsafe { blst_fp_from_bendian(&mut fp_y, input_p0_y.as_ptr()) }; fp2.fp[0] = fp_x; fp2.fp[1] = fp_y; let mut p = blst_p2::default(); // SAFETY: p and fp2 are blst values. - unsafe { - // third argument is unused if null. - blst_map_to_g2(&mut p, &fp2, std::ptr::null()); - } + // third argument is unused if null. + unsafe { blst_map_to_g2(&mut p, &fp2, core::ptr::null()) }; let mut p_aff = blst_p2_affine::default(); // SAFETY: p_aff and p are blst values. - unsafe { - blst_p2_to_affine(&mut p_aff, &p); - } + unsafe { blst_p2_to_affine(&mut p_aff, &p) }; let out = encode_g2_point(&p_aff); Ok((BASE_GAS_FEE, out)) diff --git a/crates/precompile/src/bls12_381/map_fp_to_g1.rs b/crates/precompile/src/bls12_381/map_fp_to_g1.rs index f0d273f3..b161f7d3 100644 --- a/crates/precompile/src/bls12_381/map_fp_to_g1.rs +++ b/crates/precompile/src/bls12_381/map_fp_to_g1.rs @@ -1,14 +1,12 @@ -use blst::{ - blst_fp, blst_fp_from_bendian, blst_map_to_g1, blst_p1, blst_p1_affine, blst_p1_to_affine, -}; -use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; - -use crate::{u64_to_address, PrecompileWithAddress}; - use super::{ g1::encode_g1_point, utils::{remove_padding, PADDED_FP_LENGTH}, }; +use crate::{u64_to_address, PrecompileWithAddress}; +use blst::{ + blst_fp, blst_fp_from_bendian, blst_map_to_g1, blst_p1, blst_p1_affine, blst_p1_to_affine, +}; +use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; /// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_MAP_FP_TO_G1 precompile. pub const PRECOMPILE: PrecompileWithAddress = @@ -28,7 +26,7 @@ fn map_fp_to_g1(input: &Bytes, gas_limit: u64) -> PrecompileResult { if input.len() != PADDED_FP_LENGTH { return Err(PrecompileError::Other(format!( - "MAP_FP_TO_G1 Input should be {PADDED_FP_LENGTH} bits, was {}", + "MAP_FP_TO_G1 input should be {PADDED_FP_LENGTH} bytes, was {}", input.len() ))); } @@ -38,22 +36,16 @@ fn map_fp_to_g1(input: &Bytes, gas_limit: u64) -> PrecompileResult { let mut fp = blst_fp::default(); // SAFETY: input_p0 has fixed length, fp is a blst value. - unsafe { - blst_fp_from_bendian(&mut fp, input_p0.as_ptr()); - } + unsafe { blst_fp_from_bendian(&mut fp, input_p0.as_ptr()) }; let mut p = blst_p1::default(); // SAFETY: p and fp are blst values. - unsafe { - // third argument is unused if null. - blst_map_to_g1(&mut p, &fp, std::ptr::null()); - } + // third argument is unused if null. + unsafe { blst_map_to_g1(&mut p, &fp, core::ptr::null()) }; let mut p_aff = blst_p1_affine::default(); // SAFETY: p_aff and p are blst values. - unsafe { - blst_p1_to_affine(&mut p_aff, &p); - } + unsafe { blst_p1_to_affine(&mut p_aff, &p) }; let out = encode_g1_point(&p_aff); Ok((MAP_FP_TO_G1_BASE, out)) diff --git a/crates/precompile/src/bls12_381/msm.rs b/crates/precompile/src/bls12_381/msm.rs index e26ea3eb..9ddeedc0 100644 --- a/crates/precompile/src/bls12_381/msm.rs +++ b/crates/precompile/src/bls12_381/msm.rs @@ -1,7 +1,8 @@ /// Amount used to calculate the multi-scalar-multiplication discount. const MSM_MULTIPLIER: u64 = 1000; + /// Table of gas discounts for multi-scalar-multiplication operations. -const MSM_DISCOUNT_TABLE: [u64; 128] = [ +static MSM_DISCOUNT_TABLE: [u16; 128] = [ 1200, 888, 764, 641, 594, 547, 500, 453, 438, 423, 408, 394, 379, 364, 349, 334, 330, 326, 322, 318, 314, 310, 306, 302, 298, 294, 289, 285, 281, 277, 273, 269, 268, 266, 265, 263, 262, 260, 259, 257, 256, 254, 253, 251, 250, 248, 247, 245, 244, 242, 241, 239, 238, 236, 235, 233, 232, @@ -18,11 +19,8 @@ pub(super) fn msm_required_gas(k: usize, multiplication_cost: u64) -> u64 { return 0; } - let discount = if k < MSM_DISCOUNT_TABLE.len() { - MSM_DISCOUNT_TABLE[k - 1] - } else { - MSM_DISCOUNT_TABLE[MSM_DISCOUNT_TABLE.len() - 1] - }; + let index = core::cmp::min(k - 1, MSM_DISCOUNT_TABLE.len() - 1); + let discount = MSM_DISCOUNT_TABLE[index] as u64; (k as u64 * discount * multiplication_cost) / MSM_MULTIPLIER } diff --git a/crates/precompile/src/bls12_381/pairing.rs b/crates/precompile/src/bls12_381/pairing.rs index 2cd5cf9a..fb83e448 100644 --- a/crates/precompile/src/bls12_381/pairing.rs +++ b/crates/precompile/src/bls12_381/pairing.rs @@ -1,12 +1,10 @@ -use blst::{blst_final_exp, blst_fp12, blst_fp12_is_one, blst_fp12_mul, blst_miller_loop}; -use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult, B256}; - -use crate::{u64_to_address, PrecompileWithAddress}; - use super::{ g1::{extract_g1_input, G1_INPUT_ITEM_LENGTH}, g2::{extract_g2_input, G2_INPUT_ITEM_LENGTH}, }; +use crate::{u64_to_address, PrecompileWithAddress}; +use blst::{blst_final_exp, blst_fp12, blst_fp12_is_one, blst_fp12_mul, blst_miller_loop}; +use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult, B256}; /// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_PAIRING precompile. pub const PRECOMPILE: PrecompileWithAddress = @@ -49,9 +47,9 @@ fn pairing(input: &Bytes, gas_limit: u64) -> PrecompileResult { let mut acc = blst_fp12::default(); for i in 0..k { let p1_aff = - extract_g1_input(&input[i * INPUT_LENGTH..i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH])?; + &extract_g1_input(&input[i * INPUT_LENGTH..i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH])?; - let p2_aff = extract_g2_input( + let p2_aff = &extract_g2_input( &input[i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH ..i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + G2_INPUT_ITEM_LENGTH], )?; diff --git a/crates/precompile/src/bls12_381/utils.rs b/crates/precompile/src/bls12_381/utils.rs index 38673d66..3617a752 100644 --- a/crates/precompile/src/bls12_381/utils.rs +++ b/crates/precompile/src/bls12_381/utils.rs @@ -19,47 +19,41 @@ pub(super) fn fp_to_bytes(out: &mut [u8], input: *const blst_fp) { if out.len() != PADDED_FP_LENGTH { return; } - for item in out.iter_mut().take(PADDING_LENGTH) { - *item = 0; - } + let (padding, rest) = out.split_at_mut(PADDING_LENGTH); + padding.fill(0); // SAFETY: out length is checked previously, input is a blst value. - unsafe { - blst_bendian_from_fp(out[PADDING_LENGTH..].as_mut_ptr(), input); - } + unsafe { blst_bendian_from_fp(rest.as_mut_ptr(), input) }; } /// Removes zeros with which the precompile inputs are left padded to 64 bytes. -pub(super) fn remove_padding(input: &[u8]) -> Result<[u8; FP_LENGTH], PrecompileError> { +pub(super) fn remove_padding(input: &[u8]) -> Result<&[u8; FP_LENGTH], PrecompileError> { if input.len() != PADDED_FP_LENGTH { return Err(PrecompileError::Other(format!( - "Padded Input should be {PADDED_FP_LENGTH} bits, was {}", + "Padded input should be {PADDED_FP_LENGTH} bytes, was {}", input.len() ))); } - if !input.iter().take(PADDING_LENGTH).all(|&x| x == 0) { + let (padding, unpadded) = input.split_at(PADDING_LENGTH); + if !padding.iter().all(|&x| x == 0) { return Err(PrecompileError::Other(format!( "{PADDING_LENGTH} top bytes of input are not zero", ))); } - - let sliced = &input[PADDING_LENGTH..PADDED_FP_LENGTH]; - <[u8; FP_LENGTH]>::try_from(sliced).map_err(|e| PrecompileError::Other(format!("{e}"))) + Ok(unpadded.try_into().unwrap()) } /// Extracts an Scalar from a 32 byte slice representation. pub(super) fn extract_scalar_input(input: &[u8]) -> Result { if input.len() != SCALAR_LENGTH { return Err(PrecompileError::Other(format!( - "Input should be {SCALAR_LENGTH} bits, was {}", + "Input should be {SCALAR_LENGTH} bytes, was {}", input.len() ))); } let mut out = blst_scalar::default(); // SAFETY: input length is checked previously, out is a blst value. - unsafe { - blst_scalar_from_bendian(&mut out, input.as_ptr()); - } + unsafe { blst_scalar_from_bendian(&mut out, input.as_ptr()) }; Ok(out) } From 7286dc548477fdb56278086908fd82b8467b7bd8 Mon Sep 17 00:00:00 2001 From: Kolby Moroz Liebl <31669092+KolbyML@users.noreply.github.com> Date: Fri, 10 May 2024 23:57:03 -0600 Subject: [PATCH 064/105] chore: add Trin to used by list (#1393) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 29c9ad2d..0d748be0 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ cargo run -p revm --features std,serde-json,ethersdb --example generate_block_tr * [Zeth](https://github.com/risc0/zeth) is an open-source ZK block prover for Ethereum built on the RISC Zero zkVM. * [VERBS](https://github.com/simtopia/verbs) an open-source Ethereum agent-based modelling and simulation library with a Python API. * [Hardhat](https://github.com/NomicFoundation/hardhat) is a development environment to compile, deploy, test, and debug your Ethereum software. +* [Trin](https://github.com/ethereum/trin) is Portal Network client. An execution and consensus layer Ethereum light client written in Rust. Portal Network client's provide complete, provable, and distributed execution archival access. * ... (If you want to add project to the list, ping me or open the PR) From aeefcda7fa124a8695228e5b8ab4118083f80a03 Mon Sep 17 00:00:00 2001 From: rakita Date: Sat, 11 May 2024 12:03:51 +0200 Subject: [PATCH 065/105] fix(eip2935): Preload blockchash storage address (#1395) --- crates/revm/src/handler/mainnet/pre_execution.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/crates/revm/src/handler/mainnet/pre_execution.rs b/crates/revm/src/handler/mainnet/pre_execution.rs index 64b41e70..c0f4fe7b 100644 --- a/crates/revm/src/handler/mainnet/pre_execution.rs +++ b/crates/revm/src/handler/mainnet/pre_execution.rs @@ -7,8 +7,8 @@ use crate::{ primitives::{ db::Database, Account, EVMError, Env, Spec, - SpecId::{CANCUN, SHANGHAI}, - TransactTo, U256, + SpecId::{CANCUN, PRAGUE, SHANGHAI}, + TransactTo, BLOCKHASH_STORAGE_ADDRESS, U256, }, Context, ContextPrecompiles, }; @@ -39,6 +39,16 @@ pub fn load_accounts( )?; } + // Load blockhash storage address + // EIP-2935: Serve historical block hashes from state + if SPEC::enabled(PRAGUE) { + context.evm.inner.journaled_state.initial_account_load( + BLOCKHASH_STORAGE_ADDRESS, + &[], + &mut context.evm.inner.db, + )?; + } + context.evm.load_access_list()?; Ok(()) } From d4b0ebc618a214872c4dd5f7b75f446edf97622f Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 12 May 2024 14:36:13 +0300 Subject: [PATCH 066/105] feat: Add bytes to Bytecode (#1396) * fix(eip2935): Preload blockchash storage address * chore: add bytes fn --- crates/primitives/src/bytecode.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/crates/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index 2e446726..232d61f6 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -110,6 +110,26 @@ impl Bytecode { !matches!(self, Self::LegacyRaw(_)) } + /// Returns bytes + #[inline] + pub fn bytes(&self) -> Bytes { + match self { + Self::LegacyRaw(bytes) => bytes.clone(), + Self::LegacyAnalyzed(analyzed) => analyzed.bytecode().clone(), + Self::Eof(eof) => eof.raw().clone(), + } + } + + /// Returns bytes slice + #[inline] + pub fn bytes_slice(&self) -> &[u8] { + match self { + Self::LegacyRaw(bytes) => bytes, + Self::LegacyAnalyzed(analyzed) => analyzed.bytecode(), + Self::Eof(eof) => eof.raw(), + } + } + /// Returns a reference to the original bytecode. #[inline] pub fn original_bytes(&self) -> Bytes { From d54bd99e88cc2d80c9d57b4434590eb2495682fb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 12 May 2024 13:43:19 +0200 Subject: [PATCH 067/105] chore: release (#1261) Signed-off-by: GitHub Action Co-authored-by: GitHub Action --- Cargo.lock | 10 +++++----- bins/revm-test/Cargo.toml | 2 +- bins/revme/CHANGELOG.md | 16 +++++++++++++++ bins/revme/Cargo.toml | 4 ++-- crates/interpreter/CHANGELOG.md | 35 +++++++++++++++++++++++++++++++++ crates/interpreter/Cargo.toml | 4 ++-- crates/precompile/CHANGELOG.md | 18 +++++++++++++++++ crates/precompile/Cargo.toml | 4 ++-- crates/primitives/CHANGELOG.md | 23 ++++++++++++++++++++++ crates/primitives/Cargo.toml | 2 +- crates/revm/CHANGELOG.md | 33 +++++++++++++++++++++++++++++++ crates/revm/Cargo.toml | 6 +++--- 12 files changed, 141 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b074209e..a6e1d020 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2921,7 +2921,7 @@ dependencies = [ [[package]] name = "revm" -version = "8.0.0" +version = "9.0.0" dependencies = [ "alloy-provider", "alloy-rpc-types", @@ -2947,7 +2947,7 @@ dependencies = [ [[package]] name = "revm-interpreter" -version = "4.0.0" +version = "5.0.0" dependencies = [ "bincode", "paste", @@ -2960,7 +2960,7 @@ dependencies = [ [[package]] name = "revm-precompile" -version = "6.0.0" +version = "7.0.0" dependencies = [ "aurora-engine-modexp", "blst", @@ -2978,7 +2978,7 @@ dependencies = [ [[package]] name = "revm-primitives" -version = "3.1.1" +version = "4.0.0" dependencies = [ "alloy-primitives", "auto_impl", @@ -3011,7 +3011,7 @@ dependencies = [ [[package]] name = "revme" -version = "0.4.0" +version = "0.5.0" dependencies = [ "alloy-rlp", "hash-db", diff --git a/bins/revm-test/Cargo.toml b/bins/revm-test/Cargo.toml index f26c4e78..ef50c940 100644 --- a/bins/revm-test/Cargo.toml +++ b/bins/revm-test/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] bytes = "1.6" hex = "0.4" -revm = { path = "../../crates/revm", version = "8.0.0", default-features=false } +revm = { path = "../../crates/revm", version = "9.0.0", default-features=false } microbench = "0.5" alloy-sol-macro = "0.7.0" alloy-sol-types = "0.7.0" diff --git a/bins/revme/CHANGELOG.md b/bins/revme/CHANGELOG.md index 34abf004..41e89545 100644 --- a/bins/revme/CHANGELOG.md +++ b/bins/revme/CHANGELOG.md @@ -6,6 +6,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.5.0](https://github.com/bluealloy/revm/compare/revme-v0.4.0...revme-v0.5.0) - 2024-05-12 + +### Added +- *(precompile)* Prague - EIP-2537 - BLS12-381 curve operations ([#1389](https://github.com/bluealloy/revm/pull/1389)) +- add trace option in `revme evm` ([#1376](https://github.com/bluealloy/revm/pull/1376)) +- *(revme)* add --keep-going to statetest command ([#1277](https://github.com/bluealloy/revm/pull/1277)) +- EOF (Ethereum Object Format) ([#1143](https://github.com/bluealloy/revm/pull/1143)) + +### Fixed +- *(revme)* Print one json outcome in statetest ([#1347](https://github.com/bluealloy/revm/pull/1347)) +- Drops check for .json when testing a single file ([#1301](https://github.com/bluealloy/revm/pull/1301)) + +### Other +- *(revme)* increment statetest bar *after* running the test ([#1377](https://github.com/bluealloy/revm/pull/1377)) +- *(interpreter)* branch less in as_usize_or_fail ([#1374](https://github.com/bluealloy/revm/pull/1374)) + ## [0.4.0](https://github.com/bluealloy/revm/compare/revme-v0.3.1...revme-v0.4.0) - 2024-04-02 ### Added diff --git a/bins/revme/Cargo.toml b/bins/revme/Cargo.toml index 84a695d7..71d9d654 100644 --- a/bins/revme/Cargo.toml +++ b/bins/revme/Cargo.toml @@ -6,7 +6,7 @@ keywords = ["ethereum", "evm"] license = "MIT" repository = "https://github.com/bluealloy/revm" description = "Rust Ethereum Virtual Machine Executable" -version = "0.4.0" +version = "0.5.0" [dependencies] hash-db = "0.15" @@ -15,7 +15,7 @@ hashbrown = "0.14" indicatif = "0.17" microbench = "0.5" plain_hasher = "0.2" -revm = { path = "../../crates/revm", version = "8.0.0", default-features = false, features = [ +revm = { path = "../../crates/revm", version = "9.0.0", default-features = false, features = [ "ethersdb", "std", "serde-json", diff --git a/crates/interpreter/CHANGELOG.md b/crates/interpreter/CHANGELOG.md index 97303ef6..be64279f 100644 --- a/crates/interpreter/CHANGELOG.md +++ b/crates/interpreter/CHANGELOG.md @@ -6,6 +6,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [5.0.0](https://github.com/bluealloy/revm/compare/revm-interpreter-v4.0.0...revm-interpreter-v5.0.0) - 2024-05-12 + +### Added +- implement EIP-2935 ([#1354](https://github.com/bluealloy/revm/pull/1354)) +- parse opcodes from strings ([#1358](https://github.com/bluealloy/revm/pull/1358)) +- *(interpreter)* add helpers for spending all gas ([#1360](https://github.com/bluealloy/revm/pull/1360)) +- add helper methods to CallInputs ([#1345](https://github.com/bluealloy/revm/pull/1345)) +- *(revm)* make `FrameOrResult` serializable ([#1282](https://github.com/bluealloy/revm/pull/1282)) +- add flag to force hashbrown usage ([#1284](https://github.com/bluealloy/revm/pull/1284)) +- EOF (Ethereum Object Format) ([#1143](https://github.com/bluealloy/revm/pull/1143)) +- *(interpreter)* derive Eq for InterpreterAction ([#1262](https://github.com/bluealloy/revm/pull/1262)) +- *(interpreter)* remove SPEC generic from gas calculation functions ([#1243](https://github.com/bluealloy/revm/pull/1243)) +- *(interpreter)* test Host object-safety, allow `dyn Host` in instructions ([#1245](https://github.com/bluealloy/revm/pull/1245)) + +### Fixed +- return the correct error in resize_memory ([#1359](https://github.com/bluealloy/revm/pull/1359)) +- correct some stack IO ([#1302](https://github.com/bluealloy/revm/pull/1302)) + +### Other +- add Trin to used by list ([#1393](https://github.com/bluealloy/revm/pull/1393)) +- refactor lints ([#1386](https://github.com/bluealloy/revm/pull/1386)) +- remove unused file ([#1379](https://github.com/bluealloy/revm/pull/1379)) +- *(interpreter)* branch less in as_usize_or_fail ([#1374](https://github.com/bluealloy/revm/pull/1374)) +- re-use num_words in gas::cost_per_word ([#1371](https://github.com/bluealloy/revm/pull/1371)) +- *(interpreter)* rewrite gas accounting for memory expansion ([#1361](https://github.com/bluealloy/revm/pull/1361)) +- remove bounds check in DUP, SWAP/EXCHANGE ([#1346](https://github.com/bluealloy/revm/pull/1346)) +- don't clone bytes in `Bytecode::bytes` ([#1344](https://github.com/bluealloy/revm/pull/1344)) +- shrink OpCodeInfo and add more methods ([#1307](https://github.com/bluealloy/revm/pull/1307)) +- *(interpreter)* rename some macros ([#1304](https://github.com/bluealloy/revm/pull/1304)) +- *(interpreter)* remove EOF branch in CODE{SIZE,COPY} ([#1308](https://github.com/bluealloy/revm/pull/1308)) +- fix some warnings ([#1305](https://github.com/bluealloy/revm/pull/1305)) +- *(interpreter)* rename wrapping_* opcodes ([#1306](https://github.com/bluealloy/revm/pull/1306)) +- Add the modifies_memory macro ([#1270](https://github.com/bluealloy/revm/pull/1270)) +- *(interpreter)* use `pop_top!` where possible ([#1267](https://github.com/bluealloy/revm/pull/1267)) + ## [4.0.0](https://github.com/bluealloy/revm/compare/revm-interpreter-v3.4.0...revm-interpreter-v4.0.0) - 2024-04-02 ### Added diff --git a/crates/interpreter/Cargo.toml b/crates/interpreter/Cargo.toml index db705bd9..cd6b3d96 100644 --- a/crates/interpreter/Cargo.toml +++ b/crates/interpreter/Cargo.toml @@ -6,7 +6,7 @@ keywords = ["no_std", "ethereum", "evm", "revm", "interpreter"] license = "MIT" name = "revm-interpreter" repository = "https://github.com/bluealloy/revm" -version = "4.0.0" +version = "5.0.0" readme = "../../README.md" [package.metadata.docs.rs] @@ -22,7 +22,7 @@ rust_2018_idioms = "deny" all = "warn" [dependencies] -revm-primitives = { path = "../primitives", version = "3.1.1", default-features = false } +revm-primitives = { path = "../primitives", version = "4.0.0", default-features = false } paste = { version = "1.0", optional = true } phf = { version = "0.11", default-features = false, optional = true, features = [ diff --git a/crates/precompile/CHANGELOG.md b/crates/precompile/CHANGELOG.md index 008c66f6..ac868f2e 100644 --- a/crates/precompile/CHANGELOG.md +++ b/crates/precompile/CHANGELOG.md @@ -6,6 +6,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [7.0.0](https://github.com/bluealloy/revm/compare/revm-precompile-v6.0.0...revm-precompile-v7.0.0) - 2024-05-12 + +### Added +- *(precompile)* Prague - EIP-2537 - BLS12-381 curve operations ([#1389](https://github.com/bluealloy/revm/pull/1389)) +- *(precompile)* add Prague hardfork specification ([#1387](https://github.com/bluealloy/revm/pull/1387)) +- add flag to force hashbrown usage ([#1284](https://github.com/bluealloy/revm/pull/1284)) +- EOF (Ethereum Object Format) ([#1143](https://github.com/bluealloy/revm/pull/1143)) + +### Fixed +- *(precompile)* blst dangling pointers, cleanup ([#1391](https://github.com/bluealloy/revm/pull/1391)) +- *(precompile)* inherit Prague precompiles from Cancun ([#1392](https://github.com/bluealloy/revm/pull/1392)) + +### Other +- bump c-kzg to 1.0.2 ([#1390](https://github.com/bluealloy/revm/pull/1390)) +- refactor lints ([#1386](https://github.com/bluealloy/revm/pull/1386)) +- *(deps)* bump aurora-engine-modexp from 1.0.0 to 1.1.0 ([#1339](https://github.com/bluealloy/revm/pull/1339)) +- *(deps)* bump secp256k1 from 0.28.2 to 0.29.0 ([#1260](https://github.com/bluealloy/revm/pull/1260)) + ## [6.0.0](https://github.com/bluealloy/revm/compare/revm-precompile-v5.1.0...revm-precompile-v6.0.0) - 2024-04-02 ### Fixed diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index a2f4e863..bd145fa9 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -6,7 +6,7 @@ keywords = ["no_std", "ethereum", "evm", "revm", "precompiles"] license = "MIT" name = "revm-precompile" repository = "https://github.com/bluealloy/revm" -version = "6.0.0" +version = "7.0.0" [package.metadata.docs.rs] all-features = true @@ -21,7 +21,7 @@ rust_2018_idioms = "deny" all = "warn" [dependencies] -revm-primitives = { path = "../primitives", version = "3.1.1", default-features = false } +revm-primitives = { path = "../primitives", version = "4.0.0", default-features = false } bn = { package = "substrate-bn", version = "0.6", default-features = false } once_cell = { version = "1.19", default-features = false, features = ["alloc"] } ripemd = { version = "0.1", default-features = false } diff --git a/crates/primitives/CHANGELOG.md b/crates/primitives/CHANGELOG.md index 79148d55..ad68b29b 100644 --- a/crates/primitives/CHANGELOG.md +++ b/crates/primitives/CHANGELOG.md @@ -6,6 +6,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [4.0.0](https://github.com/bluealloy/revm/compare/revm-primitives-v3.1.1...revm-primitives-v4.0.0) - 2024-05-12 + +### Added +- Add bytes to Bytecode ([#1396](https://github.com/bluealloy/revm/pull/1396)) +- implement EIP-2935 ([#1354](https://github.com/bluealloy/revm/pull/1354)) +- add `Bytecode::original_bytecode_slice` to match `BytecodeLocked` ([#1286](https://github.com/bluealloy/revm/pull/1286)) +- add flag to force hashbrown usage ([#1284](https://github.com/bluealloy/revm/pull/1284)) +- EOF (Ethereum Object Format) ([#1143](https://github.com/bluealloy/revm/pull/1143)) +- pass rand feature to alloy_primitives ([#1276](https://github.com/bluealloy/revm/pull/1276)) +- *(interpreter)* remove SPEC generic from gas calculation functions ([#1243](https://github.com/bluealloy/revm/pull/1243)) + +### Other +- add Trin to used by list ([#1393](https://github.com/bluealloy/revm/pull/1393)) +- bump c-kzg to 1.0.2 ([#1390](https://github.com/bluealloy/revm/pull/1390)) +- refactor lints ([#1386](https://github.com/bluealloy/revm/pull/1386)) +- add blob_count and max_blobs to `TooManyBlobs` err enum ([#1375](https://github.com/bluealloy/revm/pull/1375)) +- bump alloy & specify dep rev ([#1380](https://github.com/bluealloy/revm/pull/1380)) +- don't clone bytes in `Bytecode::bytes` ([#1344](https://github.com/bluealloy/revm/pull/1344)) +- shrink OpCodeInfo and add more methods ([#1307](https://github.com/bluealloy/revm/pull/1307)) +- Implement `with_chain_id` for `CfgEnv` ([#1327](https://github.com/bluealloy/revm/pull/1327)) +- *(interpreter)* remove EOF branch in CODE{SIZE,COPY} ([#1308](https://github.com/bluealloy/revm/pull/1308)) +- Update documentation ([#1275](https://github.com/bluealloy/revm/pull/1275)) + ## [3.1.1](https://github.com/bluealloy/revm/compare/revm-primitives-v3.1.0...revm-primitives-v3.1.1) - 2024-04-02 ### Fixed diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index b23697b1..a9d009d2 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -6,7 +6,7 @@ keywords = ["no_std", "ethereum", "evm", "revm", "types"] license = "MIT" name = "revm-primitives" repository = "https://github.com/bluealloy/revm" -version = "3.1.1" +version = "4.0.0" readme = "../../README.md" [package.metadata.docs.rs] diff --git a/crates/revm/CHANGELOG.md b/crates/revm/CHANGELOG.md index 1b01a633..fc2408cb 100644 --- a/crates/revm/CHANGELOG.md +++ b/crates/revm/CHANGELOG.md @@ -6,6 +6,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [9.0.0](https://github.com/bluealloy/revm/compare/revm-v8.0.0...revm-v9.0.0) - 2024-05-12 + +### Added +- *(precompile)* Prague - EIP-2537 - BLS12-381 curve operations ([#1389](https://github.com/bluealloy/revm/pull/1389)) +- add a hook to execute individual frames ([#1369](https://github.com/bluealloy/revm/pull/1369)) +- *(Handler)* Add ClearHandle ([#1368](https://github.com/bluealloy/revm/pull/1368)) +- Add uniswap V2 WETH-USDC swap example ([#1353](https://github.com/bluealloy/revm/pull/1353)) +- *(interpreter)* add helpers for spending all gas ([#1360](https://github.com/bluealloy/revm/pull/1360)) +- add helper methods to CallInputs ([#1345](https://github.com/bluealloy/revm/pull/1345)) +- *(revm)* make `FrameOrResult` serializable ([#1282](https://github.com/bluealloy/revm/pull/1282)) +- add flag to force hashbrown usage ([#1284](https://github.com/bluealloy/revm/pull/1284)) +- EOF (Ethereum Object Format) ([#1143](https://github.com/bluealloy/revm/pull/1143)) +- *(`db`)* Introduce `alloydb` ([#1257](https://github.com/bluealloy/revm/pull/1257)) +- *(interpreter)* remove SPEC generic from gas calculation functions ([#1243](https://github.com/bluealloy/revm/pull/1243)) +- *(interpreter)* test Host object-safety, allow `dyn Host` in instructions ([#1245](https://github.com/bluealloy/revm/pull/1245)) + +### Fixed +- *(eip2935)* Preload blockchash storage address ([#1395](https://github.com/bluealloy/revm/pull/1395)) +- return the correct error in resize_memory ([#1359](https://github.com/bluealloy/revm/pull/1359)) + +### Other +- add Trin to used by list ([#1393](https://github.com/bluealloy/revm/pull/1393)) +- refactor lints ([#1386](https://github.com/bluealloy/revm/pull/1386)) +- bump alloy & specify dep rev ([#1380](https://github.com/bluealloy/revm/pull/1380)) +- *(interpreter)* branch less in as_usize_or_fail ([#1374](https://github.com/bluealloy/revm/pull/1374)) +- *(ci)* bump action/deploy ([#1372](https://github.com/bluealloy/revm/pull/1372)) +- shrink OpCodeInfo and add more methods ([#1307](https://github.com/bluealloy/revm/pull/1307)) +- *(deps)* bump anyhow from 1.0.81 to 1.0.82 ([#1293](https://github.com/bluealloy/revm/pull/1293)) +- fix some warnings ([#1305](https://github.com/bluealloy/revm/pull/1305)) +- Update documentation ([#1275](https://github.com/bluealloy/revm/pull/1275)) +- *(interpreter)* use `pop_top!` where possible ([#1267](https://github.com/bluealloy/revm/pull/1267)) +- add and use EvmContext::take_error ([#1264](https://github.com/bluealloy/revm/pull/1264)) + ## [8.0.0](https://github.com/bluealloy/revm/compare/revm-v7.2.0...revm-v8.0.0) - 2024-04-02 ### Added diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 9b8446ad..5f2407ec 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -6,7 +6,7 @@ keywords = ["no_std", "ethereum", "evm", "revm"] license = "MIT" name = "revm" repository = "https://github.com/bluealloy/revm" -version = "8.0.0" +version = "9.0.0" readme = "../../README.md" [package.metadata.docs.rs] @@ -23,8 +23,8 @@ all = "warn" [dependencies] # revm -revm-interpreter = { path = "../interpreter", version = "4.0.0", default-features = false } -revm-precompile = { path = "../precompile", version = "6.0.0", default-features = false } +revm-interpreter = { path = "../interpreter", version = "5.0.0", default-features = false } +revm-precompile = { path = "../precompile", version = "7.0.0", default-features = false } # misc auto_impl = { version = "1.2", default-features = false } From 472de2cd3bdd436faddb2b3c04c9dc94978e3780 Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 12 May 2024 14:55:37 +0300 Subject: [PATCH 068/105] chore: main CHANGELOG, tag v36 (#1397) --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d60f592..bd62fd2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ Because this is workspace with multi libraries, tags will be simplified, and with this document you can match version of project with git tag. +# v36 tag +date: 12.05.2024 + +Support for prague EIPs. +* EOF not fully tested but most of implementation is there. +* EIP-2537: BLS12-381 curve operations +* EIP-2935: Serve historical block hashes from state + +EOF removed BytecodeLocked, OpCode table got changed, and CallInputs got refactored. + +revme: 0.4.0 -> 0.5.0 (⚠️ API breaking changes) +revm: 8.0.0 -> 9.0.0 (⚠️ API breaking changes) +revm-interpreter: 4.0.0 -> 5.0.0 (⚠️ API breaking changes) +revm-primitives: 3.1.1 -> 4.0.0 (⚠️ API breaking changes) +revm-precompile: 6.0.0 -> 7.0.0 (⚠️ API breaking changes) +revm-test: 0.1.0 + # v35 tag date: 02.04.2024 From a04c7cdcd820a0e8187fa813532cbedd4d9dee1d Mon Sep 17 00:00:00 2001 From: rakita Date: Sun, 12 May 2024 15:16:20 +0300 Subject: [PATCH 069/105] chore: remove alloydb example as the crate is not published (#1398) --- Cargo.lock | 2 -- crates/revm/Cargo.toml | 29 +++++++++++++++-------------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a6e1d020..c08fc320 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2924,9 +2924,7 @@ name = "revm" version = "9.0.0" dependencies = [ "alloy-provider", - "alloy-rpc-types", "alloy-sol-types", - "alloy-transport", "alloy-transport-http", "anyhow", "auto_impl", diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 5f2407ec..9f9c9db9 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -49,9 +49,9 @@ ethers-providers = { version = "2.0", optional = true } ethers-core = { version = "2.0", optional = true } # alloydb -alloy-provider = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6d", optional = true, default-features = false } -alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6d", optional = true, default-features = false } -alloy-transport = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6d", optional = true, default-features = false } +# alloy-provider = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6d", optional = true, default-features = false } +# alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6d", optional = true, default-features = false } +# alloy-transport = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6d", optional = true, default-features = false } [dev-dependencies] alloy-sol-types = { version = "0.7.0", default-features = false, features = [ @@ -106,13 +106,14 @@ ethersdb = [ "ethers-core", ] # Negate optimism default handler -alloydb = [ - "std", - "tokio", - "alloy-provider", - "alloy-rpc-types", - "alloy-transport", -] +# +# alloydb = [ +# "std", +# "tokio", +# "alloy-provider", +# "alloy-rpc-types", +# "alloy-transport", +# ] dev = [ "memory_limit", @@ -151,10 +152,10 @@ name = "db_by_ref" path = "../../examples/db_by_ref.rs" required-features = ["std", "serde-json"] -[[example]] -name = "uniswap_v2_usdc_swap" -path = "../../examples/uniswap_v2_usdc_swap.rs" -required-features = ["alloydb"] +#[[example]] +#name = "uniswap_v2_usdc_swap" +#path = "../../examples/uniswap_v2_usdc_swap.rs" +#required-features = ["alloydb"] [[bench]] name = "bench" From 919aae566de2d67256fb324a240a76aebd67cd03 Mon Sep 17 00:00:00 2001 From: rakita Date: Mon, 13 May 2024 10:31:56 +0300 Subject: [PATCH 070/105] chore: Remove Host constrain from calc_call_gas (#1409) * chore: Remove Host constrain from calc_call_gas * make it build --- crates/interpreter/src/instructions/contract.rs | 8 ++++---- .../interpreter/src/instructions/contract/call_helpers.rs | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index acb896f4..c3f701f2 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -469,7 +469,7 @@ pub fn call(interpreter: &mut Interpreter, host: & interpreter.instruction_result = InstructionResult::FatalExternalError; return; }; - let Some(mut gas_limit) = calc_call_gas::( + let Some(mut gas_limit) = calc_call_gas::( interpreter, is_cold, has_transfer, @@ -520,7 +520,7 @@ pub fn call_code(interpreter: &mut Interpreter, ho return; }; - let Some(mut gas_limit) = calc_call_gas::( + let Some(mut gas_limit) = calc_call_gas::( interpreter, is_cold, value != U256::ZERO, @@ -571,7 +571,7 @@ pub fn delegate_call(interpreter: &mut Interpreter return; }; let Some(gas_limit) = - calc_call_gas::(interpreter, is_cold, false, false, local_gas_limit) + calc_call_gas::(interpreter, is_cold, false, false, local_gas_limit) else { return; }; @@ -613,7 +613,7 @@ pub fn static_call(interpreter: &mut Interpreter, }; let Some(gas_limit) = - calc_call_gas::(interpreter, is_cold, false, false, local_gas_limit) + calc_call_gas::(interpreter, is_cold, false, false, local_gas_limit) else { return; }; diff --git a/crates/interpreter/src/instructions/contract/call_helpers.rs b/crates/interpreter/src/instructions/contract/call_helpers.rs index 8746f2ec..5570efe3 100644 --- a/crates/interpreter/src/instructions/contract/call_helpers.rs +++ b/crates/interpreter/src/instructions/contract/call_helpers.rs @@ -2,7 +2,6 @@ use crate::{ gas, interpreter::Interpreter, primitives::{Bytes, Spec, SpecId::*, U256}, - Host, }; use core::{cmp::min, ops::Range}; @@ -43,7 +42,7 @@ pub fn resize_memory_and_return_range( } #[inline] -pub fn calc_call_gas( +pub fn calc_call_gas( interpreter: &mut Interpreter, is_cold: bool, has_transfer: bool, From 4666bd3432aed18a5c89789fedd27bfdbd26c664 Mon Sep 17 00:00:00 2001 From: rakita Date: Mon, 13 May 2024 10:32:16 +0300 Subject: [PATCH 071/105] chore: pop_address should use crate scope (#1410) --- crates/interpreter/src/instructions/macros.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index abac40bc..a4ee4f4b 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -138,10 +138,10 @@ macro_rules! resize_memory { #[macro_export] macro_rules! pop_address { ($interp:expr, $x1:ident) => { - pop_address_ret!($interp, $x1, ()) + $crate::pop_address_ret!($interp, $x1, ()) }; ($interp:expr, $x1:ident, $x2:ident) => { - pop_address_ret!($interp, $x1, $x2, ()) + $crate::pop_address_ret!($interp, $x1, $x2, ()) }; } From db7b3cf3e77845d0fea6695919e1cb8b144f5381 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 09:32:39 +0200 Subject: [PATCH 072/105] chore(deps): bump serde from 1.0.200 to 1.0.201 (#1407) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.200 to 1.0.201. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.200...v1.0.201) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c08fc320..73b2072b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3396,18 +3396,18 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.200" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" +checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.200" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" +checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" dependencies = [ "proc-macro2", "quote", From a2e3d395a3087a6f9372a2ab0f825d8f9a983038 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 09:32:46 +0200 Subject: [PATCH 073/105] chore(deps): bump serde_json from 1.0.115 to 1.0.117 (#1406) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.115 to 1.0.117. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.115...v1.0.117) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73b2072b..f07a30a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3416,9 +3416,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.115" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "indexmap", "itoa", From fa99b9076861d53d6190b07a211c6cd81a2fbd69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 09:32:55 +0200 Subject: [PATCH 074/105] chore(deps): bump paste from 1.0.14 to 1.0.15 (#1405) Bumps [paste](https://github.com/dtolnay/paste) from 1.0.14 to 1.0.15. - [Release notes](https://github.com/dtolnay/paste/releases) - [Commits](https://github.com/dtolnay/paste/compare/1.0.14...1.0.15) --- updated-dependencies: - dependency-name: paste dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f07a30a1..8b92f82a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2427,9 +2427,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pem" From 4ac1e6619d1bf95e0974b010157029b8222a8aad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 09:33:04 +0200 Subject: [PATCH 075/105] chore(deps): bump anyhow from 1.0.82 to 1.0.83 (#1404) Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.82 to 1.0.83. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.82...1.0.83) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- crates/revm/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8b92f82a..00264cd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -360,9 +360,9 @@ checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anyhow" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" [[package]] name = "arbitrary" diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 9f9c9db9..9c1830e4 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -58,7 +58,7 @@ alloy-sol-types = { version = "0.7.0", default-features = false, features = [ "std", ] } ethers-contract = { version = "2.0.14", default-features = false } -anyhow = "1.0.82" +anyhow = "1.0.83" criterion = "0.5" indicatif = "0.17" reqwest = { version = "0.12" } From 29b22246f7e1bb13361c3d0ac3129c0316c15742 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 09:33:12 +0200 Subject: [PATCH 076/105] chore(deps): bump thiserror from 1.0.59 to 1.0.60 (#1403) Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.59 to 1.0.60. - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.59...1.0.60) --- updated-dependencies: - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 00264cd4..578b2634 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3722,18 +3722,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" +checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" +checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2", "quote", From 287ae36260646120f0007485afe17c222579ea9e Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 13 May 2024 11:01:19 +0300 Subject: [PATCH 077/105] docs: point to gas! in Gas::record_cost (#1413) --- crates/interpreter/src/gas.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/interpreter/src/gas.rs b/crates/interpreter/src/gas.rs index 192dcc7b..ac0af307 100644 --- a/crates/interpreter/src/gas.rs +++ b/crates/interpreter/src/gas.rs @@ -121,7 +121,7 @@ impl Gas { /// /// Returns `false` if the gas limit is exceeded. #[inline] - #[must_use] + #[must_use = "prefer using `gas!` instead to return an out-of-gas error on failure"] pub fn record_cost(&mut self, cost: u64) -> bool { let (remaining, overflow) = self.remaining.overflowing_sub(cost); let success = !overflow; From 38c4d3e756291b8a11f48bdce6f4248582824890 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 13 May 2024 11:03:59 +0300 Subject: [PATCH 078/105] fix(primitives): specify the optimism cfg on spec_to_generic (#1412) --- crates/primitives/src/specification.rs | 73 ++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index fbd8d22a..52abf9ec 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -208,10 +208,77 @@ spec!(CANYON, CanyonSpec); #[cfg(feature = "optimism")] spec!(ECOTONE, EcotoneSpec); +#[cfg(not(feature = "optimism"))] +#[macro_export] +macro_rules! spec_to_generic { + ($spec_id:expr, $e:expr) => {{ + match $spec_id { + $crate::SpecId::FRONTIER | SpecId::FRONTIER_THAWING => { + use $crate::FrontierSpec as SPEC; + $e + } + $crate::SpecId::HOMESTEAD | SpecId::DAO_FORK => { + use $crate::HomesteadSpec as SPEC; + $e + } + $crate::SpecId::TANGERINE => { + use $crate::TangerineSpec as SPEC; + $e + } + $crate::SpecId::SPURIOUS_DRAGON => { + use $crate::SpuriousDragonSpec as SPEC; + $e + } + $crate::SpecId::BYZANTIUM => { + use $crate::ByzantiumSpec as SPEC; + $e + } + $crate::SpecId::PETERSBURG | $crate::SpecId::CONSTANTINOPLE => { + use $crate::PetersburgSpec as SPEC; + $e + } + $crate::SpecId::ISTANBUL | $crate::SpecId::MUIR_GLACIER => { + use $crate::IstanbulSpec as SPEC; + $e + } + $crate::SpecId::BERLIN => { + use $crate::BerlinSpec as SPEC; + $e + } + $crate::SpecId::LONDON + | $crate::SpecId::ARROW_GLACIER + | $crate::SpecId::GRAY_GLACIER => { + use $crate::LondonSpec as SPEC; + $e + } + $crate::SpecId::MERGE => { + use $crate::MergeSpec as SPEC; + $e + } + $crate::SpecId::SHANGHAI => { + use $crate::ShanghaiSpec as SPEC; + $e + } + $crate::SpecId::CANCUN => { + use $crate::CancunSpec as SPEC; + $e + } + $crate::SpecId::LATEST => { + use $crate::LatestSpec as SPEC; + $e + } + $crate::SpecId::PRAGUE => { + use $crate::PragueSpec as SPEC; + $e + } + } + }}; +} + +#[cfg(feature = "optimism")] #[macro_export] macro_rules! spec_to_generic { ($spec_id:expr, $e:expr) => {{ - // We are transitioning from var to generic spec. match $spec_id { $crate::SpecId::FRONTIER | SpecId::FRONTIER_THAWING => { use $crate::FrontierSpec as SPEC; @@ -271,22 +338,18 @@ macro_rules! spec_to_generic { use $crate::PragueSpec as SPEC; $e } - #[cfg(feature = "optimism")] $crate::SpecId::BEDROCK => { use $crate::BedrockSpec as SPEC; $e } - #[cfg(feature = "optimism")] $crate::SpecId::REGOLITH => { use $crate::RegolithSpec as SPEC; $e } - #[cfg(feature = "optimism")] $crate::SpecId::CANYON => { use $crate::CanyonSpec as SPEC; $e } - #[cfg(feature = "optimism")] $crate::SpecId::ECOTONE => { use $crate::EcotoneSpec as SPEC; $e From a67c30e34acbbe728e5298c183d27b31cd6d8b24 Mon Sep 17 00:00:00 2001 From: rakita Date: Mon, 13 May 2024 17:23:08 +0300 Subject: [PATCH 079/105] feat(EOF): remove TXCREATE (#1415) --- crates/interpreter/src/gas/calc.rs | 16 +--- .../interpreter/src/instructions/contract.rs | 84 +------------------ crates/interpreter/src/opcode.rs | 2 +- crates/primitives/src/env.rs | 55 +----------- crates/primitives/src/result.rs | 9 -- crates/revm/src/handler/mainnet/validation.rs | 3 +- 6 files changed, 10 insertions(+), 159 deletions(-) diff --git a/crates/interpreter/src/gas/calc.rs b/crates/interpreter/src/gas/calc.rs index 828e6112..dd434fcd 100644 --- a/crates/interpreter/src/gas/calc.rs +++ b/crates/interpreter/src/gas/calc.rs @@ -1,7 +1,7 @@ use super::constants::*; use crate::{ num_words, - primitives::{Address, Bytes, SpecId, U256}, + primitives::{Address, SpecId, U256}, SelfDestructResult, }; use std::vec::Vec; @@ -358,18 +358,10 @@ pub fn validate_initial_tx_gas( input: &[u8], is_create: bool, access_list: &[(Address, Vec)], - initcodes: &[Bytes], ) -> u64 { let mut initial_gas = 0; - let mut zero_data_len = input.iter().filter(|v| **v == 0).count() as u64; - let mut non_zero_data_len = input.len() as u64 - zero_data_len; - - // Enabling of initcode is checked in `validate_env` handler. - for initcode in initcodes { - let zeros = initcode.iter().filter(|v| **v == 0).count() as u64; - zero_data_len += zeros; - non_zero_data_len += initcode.len() as u64 - zeros; - } + let zero_data_len = input.iter().filter(|v| **v == 0).count() as u64; + let non_zero_data_len = input.len() as u64 - zero_data_len; // initdate stipend initial_gas += zero_data_len * TRANSACTION_ZERO_DATA; @@ -403,7 +395,7 @@ pub fn validate_initial_tx_gas( }; // EIP-3860: Limit and meter initcode - // Initcode stipend for bytecode analysis + // Init code stipend for bytecode analysis if spec_id.is_enabled_in(SpecId::SHANGHAI) && is_create { initial_gas += initcode_cost(input.len() as u64) } diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index c3f701f2..c0cc0cf0 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -6,11 +6,10 @@ pub use call_helpers::{ use revm_primitives::{keccak256, BerlinSpec}; use crate::{ - analysis::validate_eof, - gas::{self, cost_per_word, BASE, EOF_CREATE_GAS, KECCAK256WORD}, + gas::{self, cost_per_word, EOF_CREATE_GAS, KECCAK256WORD}, instructions::utility::read_u16, interpreter::Interpreter, - primitives::{Address, Bytes, Eof, Spec, SpecId::*, B256, U256}, + primitives::{Address, Bytes, Eof, Spec, SpecId::*, U256}, CallInputs, CallScheme, CallValue, CreateInputs, CreateScheme, EOFCreateInput, Host, InstructionResult, InterpreterAction, InterpreterResult, LoadAccountResult, MAX_INITCODE_SIZE, }; @@ -91,85 +90,6 @@ pub fn eofcreate(interpreter: &mut Interpreter, _host: &mut H) interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(1) }; } -pub fn txcreate(interpreter: &mut Interpreter, host: &mut H) { - require_eof!(interpreter); - gas!(interpreter, EOF_CREATE_GAS); - pop!( - interpreter, - tx_initcode_hash, - value, - salt, - data_offset, - data_size - ); - let tx_initcode_hash = B256::from(tx_initcode_hash); - - // resize memory and get return range. - let Some(return_range) = resize_memory(interpreter, data_offset, data_size) else { - return; - }; - - // fetch initcode, if not found push ZERO. - let Some(initcode) = host - .env() - .tx - .eof_initcodes_hashed - .get(&tx_initcode_hash) - .cloned() - else { - push!(interpreter, U256::ZERO); - return; - }; - - // deduct gas for validation - gas_or_fail!(interpreter, cost_per_word(initcode.len() as u64, BASE)); - - // deduct gas for hash. TODO check order of actions. - gas_or_fail!( - interpreter, - cost_per_word(initcode.len() as u64, KECCAK256WORD) - ); - - let Ok(eof) = Eof::decode(initcode.clone()) else { - push!(interpreter, U256::ZERO); - return; - }; - - // Data section should be full, push zero to stack and return if not. - if !eof.body.is_data_filled { - push!(interpreter, U256::ZERO); - return; - } - - // Validate initcode - if validate_eof(&eof).is_err() { - push!(interpreter, U256::ZERO); - return; - } - - // Create new address. Gas for it is already deducted. - let created_address = interpreter - .contract - .caller - .create2(salt.to_be_bytes(), tx_initcode_hash); - - let gas_limit = interpreter.gas().remaining(); - // spend all gas. It will be reimbursed after frame returns. - gas!(interpreter, gas_limit); - - interpreter.next_action = InterpreterAction::EOFCreate { - inputs: Box::new(EOFCreateInput::new( - interpreter.contract.target_address, - created_address, - value, - eof, - gas_limit, - return_range, - )), - }; - interpreter.instruction_result = InstructionResult::CallOrCreate; -} - pub fn return_contract(interpreter: &mut Interpreter, _host: &mut H) { require_init_eof!(interpreter); let deploy_container_index = unsafe { read_u16(interpreter.instruction_pointer) }; diff --git a/crates/interpreter/src/opcode.rs b/crates/interpreter/src/opcode.rs index 5114c2ae..1bed9cb4 100644 --- a/crates/interpreter/src/opcode.rs +++ b/crates/interpreter/src/opcode.rs @@ -759,7 +759,7 @@ opcodes! { // 0xEA // 0xEB 0xEC => EOFCREATE => contract::eofcreate => stack_io(4, 1), immediate_size(1); - 0xED => TXCREATE => contract::txcreate => stack_io(5, 1); + // 0xED 0xEE => RETURNCONTRACT => contract::return_contract => stack_io(2, 0), immediate_size(1), terminating; // 0xEF 0xF0 => CREATE => contract::create:: => stack_io(3, 1), not_eof; diff --git a/crates/primitives/src/env.rs b/crates/primitives/src/env.rs index 99b55571..44b07369 100644 --- a/crates/primitives/src/env.rs +++ b/crates/primitives/src/env.rs @@ -3,8 +3,8 @@ pub mod handler_cfg; pub use handler_cfg::{CfgEnvWithHandlerCfg, EnvWithHandlerCfg, HandlerCfg}; use crate::{ - calc_blob_gasprice, Account, Address, Bytes, HashMap, InvalidHeader, InvalidTransaction, Spec, - SpecId, B256, GAS_PER_BLOB, KECCAK_EMPTY, MAX_BLOB_NUMBER_PER_BLOCK, MAX_INITCODE_SIZE, U256, + calc_blob_gasprice, Account, Address, Bytes, InvalidHeader, InvalidTransaction, Spec, SpecId, + B256, GAS_PER_BLOB, KECCAK_EMPTY, MAX_BLOB_NUMBER_PER_BLOCK, MAX_INITCODE_SIZE, U256, VERSIONED_HASH_VERSION_KZG, }; use core::cmp::{min, Ordering}; @@ -189,41 +189,6 @@ impl Env { } } - if SPEC::enabled(SpecId::PRAGUE) { - if !self.tx.eof_initcodes.is_empty() { - // If initcode is set other fields must be empty - if !self.tx.blob_hashes.is_empty() { - return Err(InvalidTransaction::BlobVersionedHashesNotSupported); - } - // EOF Create tx extends EIP-1559 tx. It must have max_fee_per_blob_gas - if self.tx.max_fee_per_blob_gas.is_some() { - return Err(InvalidTransaction::MaxFeePerBlobGasNotSupported); - } - // EOF Create must have a to address - if matches!(self.tx.transact_to, TransactTo::Call(_)) { - return Err(InvalidTransaction::EofCrateShouldHaveToAddress); - } - } else { - // If initcode is set check its bounds. - if self.tx.eof_initcodes.len() > 256 { - return Err(InvalidTransaction::EofInitcodesNumberLimit); - } - if self - .tx - .eof_initcodes_hashed - .iter() - .any(|(_, i)| i.len() >= MAX_INITCODE_SIZE) - { - return Err(InvalidTransaction::EofInitcodesSizeLimit); - } - } - } else { - // Initcode set when not supported. - if !self.tx.eof_initcodes.is_empty() { - return Err(InvalidTransaction::EofInitcodesNotSupported); - } - } - Ok(()) } @@ -584,20 +549,6 @@ pub struct TxEnv { /// [EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844 pub max_fee_per_blob_gas: Option, - /// EOF Initcodes for EOF CREATE transaction - /// - /// Incorporated as part of the Prague upgrade via [EOF] - /// - /// [EOF]: https://eips.ethereum.org/EIPS/eip-4844 - pub eof_initcodes: Vec, - - /// Internal Temporary field that stores the hashes of the EOF initcodes. - /// - /// Those are always cleared after the transaction is executed. - /// And calculated/overwritten every time transaction starts. - /// They are calculated from the [`Self::eof_initcodes`] field. - pub eof_initcodes_hashed: HashMap, - #[cfg_attr(feature = "serde", serde(flatten))] #[cfg(feature = "optimism")] /// Optimism fields. @@ -642,8 +593,6 @@ impl Default for TxEnv { access_list: Vec::new(), blob_hashes: Vec::new(), max_fee_per_blob_gas: None, - eof_initcodes: Vec::new(), - eof_initcodes_hashed: HashMap::new(), #[cfg(feature = "optimism")] optimism: OptimismFields::default(), } diff --git a/crates/primitives/src/result.rs b/crates/primitives/src/result.rs index 659c4fe3..d5a0f90f 100644 --- a/crates/primitives/src/result.rs +++ b/crates/primitives/src/result.rs @@ -248,12 +248,6 @@ pub enum InvalidTransaction { }, /// Blob transaction contains a versioned hash with an incorrect version BlobVersionNotSupported, - /// EOF TxCreate transaction is not supported before Prague hardfork. - EofInitcodesNotSupported, - /// EOF TxCreate transaction max initcode number reached. - EofInitcodesNumberLimit, - /// EOF initcode in TXCreate is too large. - EofInitcodesSizeLimit, /// EOF crate should have `to` address EofCrateShouldHaveToAddress, /// System transactions are not supported post-regolith hardfork. @@ -346,10 +340,7 @@ impl fmt::Display for InvalidTransaction { write!(f, "too many blobs, have {have}, max {max}") } Self::BlobVersionNotSupported => write!(f, "blob version not supported"), - Self::EofInitcodesNotSupported => write!(f, "EOF initcodes not supported"), Self::EofCrateShouldHaveToAddress => write!(f, "EOF crate should have `to` address"), - Self::EofInitcodesSizeLimit => write!(f, "EOF initcodes size limit"), - Self::EofInitcodesNumberLimit => write!(f, "EOF initcodes number limit"), #[cfg(feature = "optimism")] Self::DepositSystemTxPostRegolith => { write!( diff --git a/crates/revm/src/handler/mainnet/validation.rs b/crates/revm/src/handler/mainnet/validation.rs index 22dfb5f4..176e0e82 100644 --- a/crates/revm/src/handler/mainnet/validation.rs +++ b/crates/revm/src/handler/mainnet/validation.rs @@ -42,10 +42,9 @@ pub fn validate_initial_tx_gas( let input = &env.tx.data; let is_create = env.tx.transact_to.is_create(); let access_list = &env.tx.access_list; - let initcodes = &env.tx.eof_initcodes; let initial_gas_spend = - gas::validate_initial_tx_gas(SPEC::SPEC_ID, input, is_create, access_list, initcodes); + gas::validate_initial_tx_gas(SPEC::SPEC_ID, input, is_create, access_list); // Additional check to see if limit is big enough to cover initial gas. if initial_gas_spend > env.tx.gas_limit { From d185018d33fd73a880eaa54bdcd6e463f8a6d11a Mon Sep 17 00:00:00 2001 From: rakita Date: Mon, 13 May 2024 18:20:57 +0300 Subject: [PATCH 080/105] chore(EOF): rename extcall opcode/names (#1416) * fix(primitives): specify the optimism cfg on spec_to_generic (#1412) * chore(EOF): rename extcall opcode/names --- crates/interpreter/src/instructions/contract.rs | 4 ++-- crates/interpreter/src/opcode.rs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index c0cc0cf0..9e2cd81d 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -234,7 +234,7 @@ pub fn extcall(interpreter: &mut Interpreter, host interpreter.instruction_result = InstructionResult::CallOrCreate; } -pub fn extdcall(interpreter: &mut Interpreter, host: &mut H) { +pub fn extdelegatecall(interpreter: &mut Interpreter, host: &mut H) { require_eof!(interpreter); pop_address!(interpreter, target_address); @@ -267,7 +267,7 @@ pub fn extdcall(interpreter: &mut Interpreter, hos interpreter.instruction_result = InstructionResult::CallOrCreate; } -pub fn extscall(interpreter: &mut Interpreter, host: &mut H) { +pub fn extstaticcall(interpreter: &mut Interpreter, host: &mut H) { require_eof!(interpreter); pop_address!(interpreter, target_address); diff --git a/crates/interpreter/src/opcode.rs b/crates/interpreter/src/opcode.rs index 1bed9cb4..28483a1a 100644 --- a/crates/interpreter/src/opcode.rs +++ b/crates/interpreter/src/opcode.rs @@ -769,11 +769,11 @@ opcodes! { 0xF4 => DELEGATECALL => contract::delegate_call:: => stack_io(6, 1), not_eof; 0xF5 => CREATE2 => contract::create:: => stack_io(4, 1), not_eof; // 0xF6 - 0xF7 => RETURNDATALOAD => system::returndataload => stack_io(1, 1); - 0xF8 => EXTCALL => contract::extcall:: => stack_io(4, 1); - 0xF9 => EXFCALL => contract::extdcall:: => stack_io(3, 1); - 0xFA => STATICCALL => contract::static_call:: => stack_io(6, 1), not_eof; - 0xFB => EXTSCALL => contract::extscall => stack_io(3, 1); + 0xF7 => RETURNDATALOAD => system::returndataload => stack_io(1, 1); + 0xF8 => EXTCALL => contract::extcall:: => stack_io(4, 1); + 0xF9 => EXTDELEGATECALL => contract::extdelegatecall:: => stack_io(3, 1); + 0xFA => STATICCALL => contract::static_call:: => stack_io(6, 1), not_eof; + 0xFB => EXTSTATICCALL => contract::extstaticcall => stack_io(3, 1); // 0xFC 0xFD => REVERT => control::revert:: => stack_io(2, 0), terminating; 0xFE => INVALID => control::invalid => stack_io(0, 0), terminating; From 84d1372e072564ae4f3334a60e9074d2790f6293 Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 14 May 2024 16:36:59 +0300 Subject: [PATCH 081/105] feat(EOF): Add CALLF/JUMPF stack checks (#1417) * feat(EOF): Add CALLF stack check * fix tests * jump stack check --- .../interpreter/src/instructions/control.rs | 138 ++++++++++++++++-- crates/interpreter/src/interpreter.rs | 2 +- .../src/bytecode/eof/types_section.rs | 8 + 3 files changed, 132 insertions(+), 16 deletions(-) diff --git a/crates/interpreter/src/instructions/control.rs b/crates/interpreter/src/instructions/control.rs index f1c5417a..db2bc70a 100644 --- a/crates/interpreter/src/instructions/control.rs +++ b/crates/interpreter/src/instructions/control.rs @@ -87,13 +87,24 @@ pub fn callf(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::LOW); let idx = unsafe { read_u16(interpreter.instruction_pointer) } as usize; - // TODO Check stack with EOF types. - if interpreter.function_stack.return_stack_len() == 1024 { + if interpreter.function_stack.return_stack_len() >= 1024 { interpreter.instruction_result = InstructionResult::EOFFunctionStackOverflow; return; } + // get target types + let Some(types) = interpreter.eof().unwrap().body.types_section.get(idx) else { + panic!("Invalid EOF in execution, expecting correct intermediate in callf") + }; + + // Check max stack height for target code section. + // safe to subtract as max_stack_height is always more than inputs. + if interpreter.stack.len() + (types.max_stack_size - types.inputs as u16) as usize > 1024 { + interpreter.instruction_result = InstructionResult::StackOverflow; + return; + } + // push current idx and PC to the callf stack. // PC is incremented by 2 to point to the next instruction after callf. interpreter @@ -120,7 +131,17 @@ pub fn jumpf(interpreter: &mut Interpreter, _host: &mut H) { let idx = unsafe { read_u16(interpreter.instruction_pointer) } as usize; - // TODO(EOF) do types stack checks + // get target types + let Some(types) = interpreter.eof().unwrap().body.types_section.get(idx) else { + panic!("Invalid EOF in execution, expecting correct intermediate in jumpf") + }; + + // Check max stack height for target code section. + // safe to subtract as max_stack_height is always more than inputs. + if interpreter.stack.len() + (types.max_stack_size - types.inputs as u16) as usize > 1024 { + interpreter.instruction_result = InstructionResult::StackOverflow; + return; + } interpreter.function_stack.set_current_code_idx(idx); interpreter.load_eof_code(idx, 0) @@ -183,7 +204,7 @@ pub fn unknown(interpreter: &mut Interpreter, _host: &mut H) { #[cfg(test)] mod test { - use revm_primitives::{bytes, Bytecode, Eof, PragueSpec}; + use revm_primitives::{bytes, eof::TypesSection, Bytecode, Eof, PragueSpec}; use super::*; use crate::{ @@ -281,27 +302,39 @@ mod test { Eof::decode(bytes).unwrap() } - #[test] - fn callf_retf_jumpf() { - let table = make_instruction_table::<_, PragueSpec>(); - let mut host = DummyHost::default(); + fn eof_setup(bytes1: Bytes, bytes2: Bytes) -> Interpreter { + eof_setup_with_types(bytes1, bytes2, TypesSection::default()) + } + + /// Two code section and types section is for last code. + fn eof_setup_with_types(bytes1: Bytes, bytes2: Bytes, types: TypesSection) -> Interpreter { let mut eof = dummy_eof(); eof.body.code_section.clear(); + eof.body.types_section.clear(); eof.header.code_sizes.clear(); - let bytes1 = Bytes::from([CALLF, 0x00, 0x01, JUMPF, 0x00, 0x01]); eof.header.code_sizes.push(bytes1.len() as u16); eof.body.code_section.push(bytes1.clone()); - let bytes2 = Bytes::from([STOP, RETF]); + eof.body.types_section.push(TypesSection::new(0, 0, 11)); + eof.header.code_sizes.push(bytes2.len() as u16); eof.body.code_section.push(bytes2.clone()); + eof.body.types_section.push(types); let mut interp = Interpreter::new_bytecode(Bytecode::Eof(eof)); interp.gas = Gas::new(10000); + interp + } - assert_eq!(interp.function_stack.current_code_idx, 0); - assert!(interp.function_stack.return_stack.is_empty()); + #[test] + fn callf_retf_stop() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + + let bytes1 = Bytes::from([CALLF, 0x00, 0x01, STOP]); + let bytes2 = Bytes::from([RETF]); + let mut interp = eof_setup(bytes1, bytes2.clone()); // CALLF interp.step(&table, &mut host); @@ -313,8 +346,6 @@ mod test { ); assert_eq!(interp.instruction_pointer, bytes2.as_ptr()); - // STOP - interp.step(&table, &mut host); // RETF interp.step(&table, &mut host); @@ -322,10 +353,87 @@ mod test { assert_eq!(interp.function_stack.return_stack, Vec::new()); assert_eq!(interp.program_counter(), 3); + // STOP + interp.step(&table, &mut host); + assert_eq!(interp.instruction_result, InstructionResult::Stop); + } + + #[test] + fn callf_stop() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + + let bytes1 = Bytes::from([CALLF, 0x00, 0x01]); + let bytes2 = Bytes::from([STOP]); + let mut interp = eof_setup(bytes1, bytes2.clone()); + + // CALLF + interp.step(&table, &mut host); + + assert_eq!(interp.function_stack.current_code_idx, 1); + assert_eq!( + interp.function_stack.return_stack[0], + FunctionReturnFrame::new(0, 3) + ); + assert_eq!(interp.instruction_pointer, bytes2.as_ptr()); + + // STOP + interp.step(&table, &mut host); + assert_eq!(interp.instruction_result, InstructionResult::Stop); + } + + #[test] + fn callf_stack_overflow() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + + let bytes1 = Bytes::from([CALLF, 0x00, 0x01]); + let bytes2 = Bytes::from([STOP]); + let mut interp = + eof_setup_with_types(bytes1, bytes2.clone(), TypesSection::new(0, 0, 1025)); + + // CALLF + interp.step(&table, &mut host); + + // stack overflow + assert_eq!(interp.instruction_result, InstructionResult::StackOverflow); + } + + #[test] + fn jumpf_stop() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + + let bytes1 = Bytes::from([JUMPF, 0x00, 0x01]); + let bytes2 = Bytes::from([STOP]); + let mut interp = eof_setup(bytes1, bytes2.clone()); + // JUMPF interp.step(&table, &mut host); + assert_eq!(interp.function_stack.current_code_idx, 1); - assert_eq!(interp.function_stack.return_stack, Vec::new()); + assert!(interp.function_stack.return_stack.is_empty()); assert_eq!(interp.instruction_pointer, bytes2.as_ptr()); + + // STOP + interp.step(&table, &mut host); + assert_eq!(interp.instruction_result, InstructionResult::Stop); + } + + #[test] + fn jumpf_stack_overflow() { + let table = make_instruction_table::<_, PragueSpec>(); + let mut host = DummyHost::default(); + + let bytes1 = Bytes::from([JUMPF, 0x00, 0x01]); + let bytes2 = Bytes::from([STOP]); + let mut interp = + eof_setup_with_types(bytes1, bytes2.clone(), TypesSection::new(0, 0, 1025)); + + // JUMPF + interp.step(&table, &mut host); + + // stack overflow + assert_eq!(interp.instruction_result, InstructionResult::StackOverflow); } } diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index 3546e48d..a27752b2 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -137,7 +137,7 @@ impl Interpreter { pub(crate) fn load_eof_code(&mut self, idx: usize, pc: usize) { // SAFETY: eof flag is true only if bytecode is Eof. let Bytecode::Eof(eof) = &self.contract.bytecode else { - panic!("Expected EOF bytecode") + panic!("Expected EOF code section") }; let Some(code) = eof.body.code(idx) else { panic!("Code not found") diff --git a/crates/primitives/src/bytecode/eof/types_section.rs b/crates/primitives/src/bytecode/eof/types_section.rs index 7695dc97..5acc3b71 100644 --- a/crates/primitives/src/bytecode/eof/types_section.rs +++ b/crates/primitives/src/bytecode/eof/types_section.rs @@ -20,6 +20,14 @@ pub struct TypesSection { } impl TypesSection { + /// Returns new `TypesSection` with the given inputs, outputs, and max_stack_size. + pub fn new(inputs: u8, outputs: u8, max_stack_size: u16) -> Self { + Self { + inputs, + outputs, + max_stack_size, + } + } /// Calculates the difference between the number of input and output stack elements. #[inline] pub const fn io_diff(&self) -> i32 { From 4763c8b1af5e0422f3c55dadbd86bc755399f8d9 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 15 May 2024 11:23:37 +0200 Subject: [PATCH 082/105] feat: add Opcode::modifies_memory back (#1421) --- crates/interpreter/src/opcode.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/crates/interpreter/src/opcode.rs b/crates/interpreter/src/opcode.rs index 28483a1a..b5b6ffd1 100644 --- a/crates/interpreter/src/opcode.rs +++ b/crates/interpreter/src/opcode.rs @@ -313,6 +313,28 @@ impl OpCode { pub const fn get(self) -> u8 { self.0 } + + /// Returns true if the opcode modifies memory. + /// + /// + #[inline] + pub const fn modifies_memory(&self) -> bool { + matches!( + *self, + OpCode::EXTCODECOPY + | OpCode::MLOAD + | OpCode::MSTORE + | OpCode::MSTORE8 + | OpCode::MCOPY + | OpCode::CODECOPY + | OpCode::CALLDATACOPY + | OpCode::RETURNDATACOPY + | OpCode::CALL + | OpCode::CALLCODE + | OpCode::DELEGATECALL + | OpCode::STATICCALL + ) + } } /// Information about opcode, such as name, and stack inputs and outputs. From 6e81b880c928a008cab16621b090c657014979e8 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 16 May 2024 16:41:22 +0300 Subject: [PATCH 083/105] feat: adjust gas-costs for EIP-2935 BLOCKHASH (#1422) --- crates/interpreter/src/instructions/host.rs | 24 +++++++++---------- crates/interpreter/src/instructions/macros.rs | 24 ------------------- 2 files changed, 11 insertions(+), 37 deletions(-) diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index 43cba873..eea5dc20 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -110,17 +110,16 @@ pub fn blockhash(interpreter: &mut Interpreter, ho let block_number = host.env().block.number; match block_number.checked_sub(*number) { + // blockhash should push zero if number is same as current block number. Some(diff) if !diff.is_zero() => { let diff = as_usize_saturated!(diff); - // blockhash should push zero if number is same as current block number. if SPEC::enabled(PRAGUE) && diff <= BLOCKHASH_SERVE_WINDOW { - let value = sload!( - interpreter, - host, - BLOCKHASH_STORAGE_ADDRESS, - number.wrapping_rem(U256::from(BLOCKHASH_SERVE_WINDOW)) - ); + let index = number.wrapping_rem(U256::from(BLOCKHASH_SERVE_WINDOW)); + let Some((value, _)) = host.sload(BLOCKHASH_STORAGE_ADDRESS, index) else { + interpreter.instruction_result = InstructionResult::FatalExternalError; + return; + }; *number = value; return; } else if diff <= BLOCK_HASH_HISTORY { @@ -143,12 +142,11 @@ pub fn blockhash(interpreter: &mut Interpreter, ho pub fn sload(interpreter: &mut Interpreter, host: &mut H) { pop_top!(interpreter, index); - let value = sload!( - interpreter, - host, - interpreter.contract.target_address, - *index - ); + let Some((value, is_cold)) = host.sload(interpreter.contract.target_address, *index) else { + interpreter.instruction_result = InstructionResult::FatalExternalError; + return; + }; + gas!(interpreter, gas::sload_cost(SPEC::SPEC_ID, is_cold)); *index = value; } diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index a4ee4f4b..2592956e 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -45,30 +45,6 @@ macro_rules! check { }; } -/// Performs an `SLOAD` on the target account and storage index. -/// -/// If the slot could not be loaded, or if the gas cost could not be charged, the expanded code -/// sets the instruction result and returns accordingly. -/// -/// # Note -/// -/// This macro charges gas. -/// -/// # Returns -/// -/// Expands to the value of the storage slot. -#[macro_export] -macro_rules! sload { - ($interp:expr, $host:expr, $address:expr, $index:expr) => {{ - let Some((value, is_cold)) = $host.sload($address, $index) else { - $interp.instruction_result = $crate::InstructionResult::FatalExternalError; - return; - }; - $crate::gas!($interp, $crate::gas::sload_cost(SPEC::SPEC_ID, is_cold)); - value - }}; -} - /// Records a `gas` cost and fails the instruction if it would exceed the available gas. #[macro_export] macro_rules! gas { From f07c0ef1c27d7a7a6b160849f4f2c88dcd843cfe Mon Sep 17 00:00:00 2001 From: rakita Date: Thu, 16 May 2024 16:47:41 +0300 Subject: [PATCH 084/105] Revert "feat: implement EIP-2935 (#1354)" (#1424) * Revert "feat: implement EIP-2935 (#1354)" This reverts commit 3e089f35ed2a98278ddbae8f5dd816ccc373fa31. * dont revert some commend changes * Revert "fix(eip2935): Preload blockchash storage address (#1395)" This reverts commit aeefcda7fa124a8695228e5b8ab4118083f80a03. --- crates/interpreter/src/instructions/host.rs | 38 +++++-------------- crates/interpreter/src/opcode.rs | 2 +- crates/primitives/src/constants.rs | 31 +++------------ .../revm/src/handler/mainnet/pre_execution.rs | 14 +------ 4 files changed, 19 insertions(+), 66 deletions(-) diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index eea5dc20..bad571de 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -5,7 +5,7 @@ use crate::{ Host, InstructionResult, SStoreResult, }; use core::cmp::min; -use revm_primitives::{BLOCKHASH_SERVE_WINDOW, BLOCKHASH_STORAGE_ADDRESS, BLOCK_HASH_HISTORY}; +use revm_primitives::BLOCK_HASH_HISTORY; use std::vec::Vec; pub fn balance(interpreter: &mut Interpreter, host: &mut H) { @@ -103,40 +103,22 @@ pub fn extcodecopy(interpreter: &mut Interpreter, .set_data(memory_offset, code_offset, len, &code.original_bytes()); } -pub fn blockhash(interpreter: &mut Interpreter, host: &mut H) { +pub fn blockhash(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BLOCKHASH); pop_top!(interpreter, number); - let block_number = host.env().block.number; - - match block_number.checked_sub(*number) { + if let Some(diff) = host.env().block.number.checked_sub(*number) { + let diff = as_usize_saturated!(diff); // blockhash should push zero if number is same as current block number. - Some(diff) if !diff.is_zero() => { - let diff = as_usize_saturated!(diff); - - if SPEC::enabled(PRAGUE) && diff <= BLOCKHASH_SERVE_WINDOW { - let index = number.wrapping_rem(U256::from(BLOCKHASH_SERVE_WINDOW)); - let Some((value, _)) = host.sload(BLOCKHASH_STORAGE_ADDRESS, index) else { - interpreter.instruction_result = InstructionResult::FatalExternalError; - return; - }; - *number = value; - return; - } else if diff <= BLOCK_HASH_HISTORY { - let Some(hash) = host.block_hash(*number) else { - interpreter.instruction_result = InstructionResult::FatalExternalError; - return; - }; - *number = U256::from_be_bytes(hash.0); + if diff <= BLOCK_HASH_HISTORY && diff != 0 { + let Some(hash) = host.block_hash(*number) else { + interpreter.instruction_result = InstructionResult::FatalExternalError; return; - } - } - _ => { - // If blockhash is requested for the current block, the hash should be 0, so we fall - // through. + }; + *number = U256::from_be_bytes(hash.0); + return; } } - *number = U256::ZERO; } diff --git a/crates/interpreter/src/opcode.rs b/crates/interpreter/src/opcode.rs index b5b6ffd1..672d1ecd 100644 --- a/crates/interpreter/src/opcode.rs +++ b/crates/interpreter/src/opcode.rs @@ -604,7 +604,7 @@ opcodes! { 0x3D => RETURNDATASIZE => system::returndatasize:: => stack_io(0, 1); 0x3E => RETURNDATACOPY => system::returndatacopy:: => stack_io(3, 0); 0x3F => EXTCODEHASH => host::extcodehash:: => stack_io(1, 1), not_eof; - 0x40 => BLOCKHASH => host::blockhash:: => stack_io(1, 1); + 0x40 => BLOCKHASH => host::blockhash => stack_io(1, 1); 0x41 => COINBASE => host_env::coinbase => stack_io(0, 1); 0x42 => TIMESTAMP => host_env::timestamp => stack_io(0, 1); 0x43 => NUMBER => host_env::block_number => stack_io(0, 1); diff --git a/crates/primitives/src/constants.rs b/crates/primitives/src/constants.rs index c8223300..1ad219dc 100644 --- a/crates/primitives/src/constants.rs +++ b/crates/primitives/src/constants.rs @@ -1,41 +1,22 @@ -use alloy_primitives::{address, Address}; +use crate::Address; /// EIP-170: Contract code size limit -/// -/// By default the limit is `0x6000` (~25kb) +/// By default limit is 0x6000 (~25kb) pub const MAX_CODE_SIZE: usize = 0x6000; -/// Number of block hashes that EVM can access in the past (pre-Prague). +/// Number of block hashes that EVM can access in the past pub const BLOCK_HASH_HISTORY: usize = 256; -/// EIP-2935: Serve historical block hashes from state -/// -/// Number of block hashes the EVM can access in the past (Prague). -/// -/// # Note -/// -/// This is named `HISTORY_SERVE_WINDOW` in the EIP. -pub const BLOCKHASH_SERVE_WINDOW: usize = 8192; - -/// EIP-2935: Serve historical block hashes from state -/// -/// The address where historical blockhashes are available. -/// -/// # Note -/// -/// This is named `HISTORY_STORAGE_ADDRESS` in the EIP. -pub const BLOCKHASH_STORAGE_ADDRESS: Address = address!("25a219378dad9b3503c8268c9ca836a52427a4fb"); - /// EIP-3860: Limit and meter initcode /// -/// Limit of maximum initcode size is `2 * MAX_CODE_SIZE`. +/// Limit of maximum initcode size is 2 * MAX_CODE_SIZE pub const MAX_INITCODE_SIZE: usize = 2 * MAX_CODE_SIZE; -/// The address of precompile 3, which is handled specially in a few places. +/// Precompile 3 is special in few places pub const PRECOMPILE3: Address = Address::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]); -// === EIP-4844 constants === +// --- EIP-4844 constants --- /// Gas consumption of a single data blob (== blob byte size). pub const GAS_PER_BLOB: u64 = 1 << 17; diff --git a/crates/revm/src/handler/mainnet/pre_execution.rs b/crates/revm/src/handler/mainnet/pre_execution.rs index c0f4fe7b..64b41e70 100644 --- a/crates/revm/src/handler/mainnet/pre_execution.rs +++ b/crates/revm/src/handler/mainnet/pre_execution.rs @@ -7,8 +7,8 @@ use crate::{ primitives::{ db::Database, Account, EVMError, Env, Spec, - SpecId::{CANCUN, PRAGUE, SHANGHAI}, - TransactTo, BLOCKHASH_STORAGE_ADDRESS, U256, + SpecId::{CANCUN, SHANGHAI}, + TransactTo, U256, }, Context, ContextPrecompiles, }; @@ -39,16 +39,6 @@ pub fn load_accounts( )?; } - // Load blockhash storage address - // EIP-2935: Serve historical block hashes from state - if SPEC::enabled(PRAGUE) { - context.evm.inner.journaled_state.initial_account_load( - BLOCKHASH_STORAGE_ADDRESS, - &[], - &mut context.evm.inner.db, - )?; - } - context.evm.load_access_list()?; Ok(()) } From eed27d92266776d653a1d08c46ffa9699d64d527 Mon Sep 17 00:00:00 2001 From: rakita Date: Thu, 16 May 2024 17:29:07 +0300 Subject: [PATCH 085/105] Revert "Revert "feat: implement EIP-2935 (#1354)" (#1424)" (#1426) This reverts commit f07c0ef1c27d7a7a6b160849f4f2c88dcd843cfe. --- crates/interpreter/src/instructions/host.rs | 38 ++++++++++++++----- crates/interpreter/src/opcode.rs | 2 +- crates/primitives/src/constants.rs | 31 ++++++++++++--- .../revm/src/handler/mainnet/pre_execution.rs | 14 ++++++- 4 files changed, 66 insertions(+), 19 deletions(-) diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index bad571de..eea5dc20 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -5,7 +5,7 @@ use crate::{ Host, InstructionResult, SStoreResult, }; use core::cmp::min; -use revm_primitives::BLOCK_HASH_HISTORY; +use revm_primitives::{BLOCKHASH_SERVE_WINDOW, BLOCKHASH_STORAGE_ADDRESS, BLOCK_HASH_HISTORY}; use std::vec::Vec; pub fn balance(interpreter: &mut Interpreter, host: &mut H) { @@ -103,22 +103,40 @@ pub fn extcodecopy(interpreter: &mut Interpreter, .set_data(memory_offset, code_offset, len, &code.original_bytes()); } -pub fn blockhash(interpreter: &mut Interpreter, host: &mut H) { +pub fn blockhash(interpreter: &mut Interpreter, host: &mut H) { gas!(interpreter, gas::BLOCKHASH); pop_top!(interpreter, number); - if let Some(diff) = host.env().block.number.checked_sub(*number) { - let diff = as_usize_saturated!(diff); + let block_number = host.env().block.number; + + match block_number.checked_sub(*number) { // blockhash should push zero if number is same as current block number. - if diff <= BLOCK_HASH_HISTORY && diff != 0 { - let Some(hash) = host.block_hash(*number) else { - interpreter.instruction_result = InstructionResult::FatalExternalError; + Some(diff) if !diff.is_zero() => { + let diff = as_usize_saturated!(diff); + + if SPEC::enabled(PRAGUE) && diff <= BLOCKHASH_SERVE_WINDOW { + let index = number.wrapping_rem(U256::from(BLOCKHASH_SERVE_WINDOW)); + let Some((value, _)) = host.sload(BLOCKHASH_STORAGE_ADDRESS, index) else { + interpreter.instruction_result = InstructionResult::FatalExternalError; + return; + }; + *number = value; + return; + } else if diff <= BLOCK_HASH_HISTORY { + let Some(hash) = host.block_hash(*number) else { + interpreter.instruction_result = InstructionResult::FatalExternalError; + return; + }; + *number = U256::from_be_bytes(hash.0); return; - }; - *number = U256::from_be_bytes(hash.0); - return; + } + } + _ => { + // If blockhash is requested for the current block, the hash should be 0, so we fall + // through. } } + *number = U256::ZERO; } diff --git a/crates/interpreter/src/opcode.rs b/crates/interpreter/src/opcode.rs index 672d1ecd..b5b6ffd1 100644 --- a/crates/interpreter/src/opcode.rs +++ b/crates/interpreter/src/opcode.rs @@ -604,7 +604,7 @@ opcodes! { 0x3D => RETURNDATASIZE => system::returndatasize:: => stack_io(0, 1); 0x3E => RETURNDATACOPY => system::returndatacopy:: => stack_io(3, 0); 0x3F => EXTCODEHASH => host::extcodehash:: => stack_io(1, 1), not_eof; - 0x40 => BLOCKHASH => host::blockhash => stack_io(1, 1); + 0x40 => BLOCKHASH => host::blockhash:: => stack_io(1, 1); 0x41 => COINBASE => host_env::coinbase => stack_io(0, 1); 0x42 => TIMESTAMP => host_env::timestamp => stack_io(0, 1); 0x43 => NUMBER => host_env::block_number => stack_io(0, 1); diff --git a/crates/primitives/src/constants.rs b/crates/primitives/src/constants.rs index 1ad219dc..c8223300 100644 --- a/crates/primitives/src/constants.rs +++ b/crates/primitives/src/constants.rs @@ -1,22 +1,41 @@ -use crate::Address; +use alloy_primitives::{address, Address}; /// EIP-170: Contract code size limit -/// By default limit is 0x6000 (~25kb) +/// +/// By default the limit is `0x6000` (~25kb) pub const MAX_CODE_SIZE: usize = 0x6000; -/// Number of block hashes that EVM can access in the past +/// Number of block hashes that EVM can access in the past (pre-Prague). pub const BLOCK_HASH_HISTORY: usize = 256; +/// EIP-2935: Serve historical block hashes from state +/// +/// Number of block hashes the EVM can access in the past (Prague). +/// +/// # Note +/// +/// This is named `HISTORY_SERVE_WINDOW` in the EIP. +pub const BLOCKHASH_SERVE_WINDOW: usize = 8192; + +/// EIP-2935: Serve historical block hashes from state +/// +/// The address where historical blockhashes are available. +/// +/// # Note +/// +/// This is named `HISTORY_STORAGE_ADDRESS` in the EIP. +pub const BLOCKHASH_STORAGE_ADDRESS: Address = address!("25a219378dad9b3503c8268c9ca836a52427a4fb"); + /// EIP-3860: Limit and meter initcode /// -/// Limit of maximum initcode size is 2 * MAX_CODE_SIZE +/// Limit of maximum initcode size is `2 * MAX_CODE_SIZE`. pub const MAX_INITCODE_SIZE: usize = 2 * MAX_CODE_SIZE; -/// Precompile 3 is special in few places +/// The address of precompile 3, which is handled specially in a few places. pub const PRECOMPILE3: Address = Address::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]); -// --- EIP-4844 constants --- +// === EIP-4844 constants === /// Gas consumption of a single data blob (== blob byte size). pub const GAS_PER_BLOB: u64 = 1 << 17; diff --git a/crates/revm/src/handler/mainnet/pre_execution.rs b/crates/revm/src/handler/mainnet/pre_execution.rs index 64b41e70..c0f4fe7b 100644 --- a/crates/revm/src/handler/mainnet/pre_execution.rs +++ b/crates/revm/src/handler/mainnet/pre_execution.rs @@ -7,8 +7,8 @@ use crate::{ primitives::{ db::Database, Account, EVMError, Env, Spec, - SpecId::{CANCUN, SHANGHAI}, - TransactTo, U256, + SpecId::{CANCUN, PRAGUE, SHANGHAI}, + TransactTo, BLOCKHASH_STORAGE_ADDRESS, U256, }, Context, ContextPrecompiles, }; @@ -39,6 +39,16 @@ pub fn load_accounts( )?; } + // Load blockhash storage address + // EIP-2935: Serve historical block hashes from state + if SPEC::enabled(PRAGUE) { + context.evm.inner.journaled_state.initial_account_load( + BLOCKHASH_STORAGE_ADDRESS, + &[], + &mut context.evm.inner.db, + )?; + } + context.evm.load_access_list()?; Ok(()) } From 7046d5e30e08e913ea160de32a5a338868b62e40 Mon Sep 17 00:00:00 2001 From: rakita Date: Thu, 16 May 2024 18:35:14 +0300 Subject: [PATCH 086/105] fix: blockchash for devnet-0 (#1427) * fix: load blockchash only from serve_window * fix: devnet-0 blockchash behaviour --- crates/interpreter/src/instructions/host.rs | 36 +++-------------- crates/revm/src/context.rs | 44 ++++++++++++++++++--- 2 files changed, 44 insertions(+), 36 deletions(-) diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index eea5dc20..20a2bcfe 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -5,7 +5,6 @@ use crate::{ Host, InstructionResult, SStoreResult, }; use core::cmp::min; -use revm_primitives::{BLOCKHASH_SERVE_WINDOW, BLOCKHASH_STORAGE_ADDRESS, BLOCK_HASH_HISTORY}; use std::vec::Vec; pub fn balance(interpreter: &mut Interpreter, host: &mut H) { @@ -108,36 +107,11 @@ pub fn blockhash(interpreter: &mut Interpreter, ho pop_top!(interpreter, number); let block_number = host.env().block.number; - - match block_number.checked_sub(*number) { - // blockhash should push zero if number is same as current block number. - Some(diff) if !diff.is_zero() => { - let diff = as_usize_saturated!(diff); - - if SPEC::enabled(PRAGUE) && diff <= BLOCKHASH_SERVE_WINDOW { - let index = number.wrapping_rem(U256::from(BLOCKHASH_SERVE_WINDOW)); - let Some((value, _)) = host.sload(BLOCKHASH_STORAGE_ADDRESS, index) else { - interpreter.instruction_result = InstructionResult::FatalExternalError; - return; - }; - *number = value; - return; - } else if diff <= BLOCK_HASH_HISTORY { - let Some(hash) = host.block_hash(*number) else { - interpreter.instruction_result = InstructionResult::FatalExternalError; - return; - }; - *number = U256::from_be_bytes(hash.0); - return; - } - } - _ => { - // If blockhash is requested for the current block, the hash should be 0, so we fall - // through. - } - } - - *number = U256::ZERO; + let Some(hash) = host.block_hash(block_number) else { + interpreter.instruction_result = InstructionResult::FatalExternalError; + return; + }; + *number = U256::from_be_bytes(hash.0); } pub fn sload(interpreter: &mut Interpreter, host: &mut H) { diff --git a/crates/revm/src/context.rs b/crates/revm/src/context.rs index 343dfcf9..f3c776a0 100644 --- a/crates/revm/src/context.rs +++ b/crates/revm/src/context.rs @@ -8,11 +8,15 @@ pub use context_precompiles::{ }; pub use evm_context::EvmContext; pub use inner_evm_context::InnerEvmContext; +use revm_interpreter::as_usize_saturated; use crate::{ db::{Database, EmptyDB}, interpreter::{Host, LoadAccountResult, SStoreResult, SelfDestructResult}, - primitives::{Address, Bytecode, Env, HandlerCfg, Log, B256, U256}, + primitives::{ + Address, Bytecode, EVMError, Env, HandlerCfg, Log, B256, BLOCKHASH_SERVE_WINDOW, + BLOCKHASH_STORAGE_ADDRESS, BLOCK_HASH_HISTORY, PRAGUE, U256, + }, }; use std::boxed::Box; @@ -106,10 +110,40 @@ impl Host for Context { } fn block_hash(&mut self, number: U256) -> Option { - self.evm - .block_hash(number) - .map_err(|e| self.evm.error = Err(e)) - .ok() + let block_number = self.env().block.number; + + match block_number.checked_sub(number) { + // blockhash should push zero if number is same as current block number. + Some(diff) if !diff.is_zero() => { + let diff = as_usize_saturated!(diff); + + if diff <= BLOCK_HASH_HISTORY { + return self + .evm + .block_hash(number) + .map_err(|e| self.evm.error = Err(e)) + .ok(); + } + + if self.evm.journaled_state.spec.is_enabled_in(PRAGUE) + && diff <= BLOCKHASH_SERVE_WINDOW + { + let index = number.wrapping_rem(U256::from(BLOCKHASH_SERVE_WINDOW)); + return self + .evm + .db + .storage(BLOCKHASH_STORAGE_ADDRESS, index) + .map_err(|e| self.evm.error = Err(EVMError::Database(e))) + .ok() + .map(|v| v.into()); + } + } + _ => { + // If blockhash is requested for the current block, the hash should be 0, so we fall + // through. + } + } + Some(B256::ZERO) } fn load_account(&mut self, address: Address) -> Option { From 05f3c5bdccb3d7c4229a40137dc28ccf4bb0b213 Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Fri, 17 May 2024 12:20:47 +0300 Subject: [PATCH 087/105] fix(interpreter): avoid overflow when checking if mem limit reached (#1429) --- crates/interpreter/src/interpreter/shared_memory.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/interpreter/src/interpreter/shared_memory.rs b/crates/interpreter/src/interpreter/shared_memory.rs index e76015a5..cc63e1bf 100644 --- a/crates/interpreter/src/interpreter/shared_memory.rs +++ b/crates/interpreter/src/interpreter/shared_memory.rs @@ -90,7 +90,7 @@ impl SharedMemory { #[cfg(feature = "memory_limit")] #[inline] pub fn limit_reached(&self, new_size: usize) -> bool { - (self.last_checkpoint + new_size) as u64 > self.memory_limit + self.last_checkpoint.saturating_add(new_size) as u64 > self.memory_limit } /// Prepares the shared memory for a new context. From 22398201c6cf8954a4a497038aa515710650f369 Mon Sep 17 00:00:00 2001 From: rakita Date: Fri, 17 May 2024 15:51:38 +0300 Subject: [PATCH 088/105] chore: cleanup host blockhash fn (#1430) --- crates/revm/src/context.rs | 62 ++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/crates/revm/src/context.rs b/crates/revm/src/context.rs index f3c776a0..aa2ae4be 100644 --- a/crates/revm/src/context.rs +++ b/crates/revm/src/context.rs @@ -110,39 +110,37 @@ impl Host for Context { } fn block_hash(&mut self, number: U256) -> Option { - let block_number = self.env().block.number; - - match block_number.checked_sub(number) { - // blockhash should push zero if number is same as current block number. - Some(diff) if !diff.is_zero() => { - let diff = as_usize_saturated!(diff); - - if diff <= BLOCK_HASH_HISTORY { - return self - .evm - .block_hash(number) - .map_err(|e| self.evm.error = Err(e)) - .ok(); - } - - if self.evm.journaled_state.spec.is_enabled_in(PRAGUE) - && diff <= BLOCKHASH_SERVE_WINDOW - { - let index = number.wrapping_rem(U256::from(BLOCKHASH_SERVE_WINDOW)); - return self - .evm - .db - .storage(BLOCKHASH_STORAGE_ADDRESS, index) - .map_err(|e| self.evm.error = Err(EVMError::Database(e))) - .ok() - .map(|v| v.into()); - } - } - _ => { - // If blockhash is requested for the current block, the hash should be 0, so we fall - // through. - } + let block_number = as_usize_saturated!(self.env().block.number); + let requested_number = as_usize_saturated!(number); + + let Some(diff) = block_number.checked_sub(requested_number) else { + return Some(B256::ZERO); + }; + + // blockhash should push zero if number is same as current block number. + if diff == 0 { + return Some(B256::ZERO); + } + + if diff <= BLOCK_HASH_HISTORY { + return self + .evm + .block_hash(number) + .map_err(|e| self.evm.error = Err(e)) + .ok(); } + + if self.evm.journaled_state.spec.is_enabled_in(PRAGUE) && diff <= BLOCKHASH_SERVE_WINDOW { + let index = number.wrapping_rem(U256::from(BLOCKHASH_SERVE_WINDOW)); + return self + .evm + .db + .storage(BLOCKHASH_STORAGE_ADDRESS, index) + .map_err(|e| self.evm.error = Err(EVMError::Database(e))) + .ok() + .map(|v| v.into()); + } + Some(B256::ZERO) } From 8fd85f17c843eb7a112041cee3c477b18d798058 Mon Sep 17 00:00:00 2001 From: Alexey Shekhirin Date: Fri, 17 May 2024 16:14:25 +0300 Subject: [PATCH 089/105] fix(precompile): BLS G2 MSM (#1428) * test(precompile): add BLS test vectors * fix(gakonst): dont blow up on bls p2_affines * uncomment g1 msm required gas * chore: small refactors * rm artifacts * add new bls test jsons * remove fail-tests these should be added again at some point * fix: perform subgroup checks only on msm, pairing, and scalar multiplications * fix docs --------- Co-authored-by: Georgios Konstantopoulos Co-authored-by: rakita Co-authored-by: Dan Cline <6798349+Rjected@users.noreply.github.com> --- Cargo.lock | 40 ++++++ crates/precompile/Cargo.toml | 5 + crates/precompile/src/bls12_381.rs | 134 ++++++++++++++++++ crates/precompile/src/bls12_381/g1.rs | 47 +++++- crates/precompile/src/bls12_381/g1_add.rs | 9 +- crates/precompile/src/bls12_381/g1_msm.rs | 6 +- crates/precompile/src/bls12_381/g1_mul.rs | 7 +- crates/precompile/src/bls12_381/g2.rs | 46 +++++- crates/precompile/src/bls12_381/g2_add.rs | 9 +- crates/precompile/src/bls12_381/g2_msm.rs | 23 ++- crates/precompile/src/bls12_381/g2_mul.rs | 7 +- .../precompile/src/bls12_381/map_fp2_to_g2.rs | 2 +- .../precompile/src/bls12_381/map_fp_to_g1.rs | 2 +- crates/precompile/src/bls12_381/mod.rs | 31 ---- crates/precompile/src/bls12_381/pairing.rs | 15 +- .../precompile/test-vectors/add_G1_bls.json | 65 +++++++++ .../precompile/test-vectors/add_G2_bls.json | 65 +++++++++ .../test-vectors/map_fp2_to_G2_bls.json | 37 +++++ .../test-vectors/map_fp_to_G1_bls.json | 37 +++++ .../precompile/test-vectors/mul_G1_bls.json | 79 +++++++++++ .../precompile/test-vectors/mul_G2_bls.json | 79 +++++++++++ .../test-vectors/multiexp_G1_bls.json | 79 +++++++++++ .../test-vectors/multiexp_G2_bls.json | 86 +++++++++++ .../test-vectors/pairing_check_bls.json | 44 ++++++ 24 files changed, 893 insertions(+), 61 deletions(-) create mode 100644 crates/precompile/src/bls12_381.rs delete mode 100644 crates/precompile/src/bls12_381/mod.rs create mode 100644 crates/precompile/test-vectors/add_G1_bls.json create mode 100644 crates/precompile/test-vectors/add_G2_bls.json create mode 100644 crates/precompile/test-vectors/map_fp2_to_G2_bls.json create mode 100644 crates/precompile/test-vectors/map_fp_to_G1_bls.json create mode 100644 crates/precompile/test-vectors/mul_G1_bls.json create mode 100644 crates/precompile/test-vectors/mul_G2_bls.json create mode 100644 crates/precompile/test-vectors/multiexp_G1_bls.json create mode 100644 crates/precompile/test-vectors/multiexp_G2_bls.json create mode 100644 crates/precompile/test-vectors/pairing_check_bls.json diff --git a/Cargo.lock b/Cargo.lock index 578b2634..e6914d00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2836,6 +2836,12 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + [[package]] name = "reqwest" version = "0.11.27" @@ -2964,12 +2970,17 @@ dependencies = [ "blst", "c-kzg", "criterion", + "eyre", "k256", "once_cell", "rand", "revm-primitives", "ripemd", + "rstest", "secp256k1", + "serde", + "serde_derive", + "serde_json", "sha2", "substrate-bn", ] @@ -3099,6 +3110,35 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "rstest" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5316d2a1479eeef1ea21e7f9ddc67c191d497abc8fc3ba2467857abbb68330" +dependencies = [ + "futures", + "futures-timer", + "rstest_macros", + "rustc_version 0.4.0", +] + +[[package]] +name = "rstest_macros" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04a9df72cc1f67020b0d63ad9bfe4a323e459ea7eb68e03bd9824db49f9a4c25" +dependencies = [ + "cfg-if", + "glob", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version 0.4.0", + "syn 2.0.55", + "unicode-ident", +] + [[package]] name = "ruint" version = "1.12.1" diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index bd145fa9..f761e726 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -47,6 +47,11 @@ blst = { version = "0.3.11", optional = true } [dev-dependencies] criterion = { version = "0.5" } rand = { version = "0.8", features = ["std"] } +eyre = "0.6.12" +rstest = "0.19.0" +serde = "1.0" +serde_json = "1.0" +serde_derive = "1.0" [features] default = ["std", "c-kzg", "secp256k1", "portable", "blst"] diff --git a/crates/precompile/src/bls12_381.rs b/crates/precompile/src/bls12_381.rs new file mode 100644 index 00000000..fd5daae0 --- /dev/null +++ b/crates/precompile/src/bls12_381.rs @@ -0,0 +1,134 @@ +use crate::PrecompileWithAddress; + +mod g1; +pub mod g1_add; +pub mod g1_msm; +pub mod g1_mul; +mod g2; +pub mod g2_add; +pub mod g2_msm; +pub mod g2_mul; +pub mod map_fp2_to_g2; +pub mod map_fp_to_g1; +mod msm; +pub mod pairing; +mod utils; + +/// Returns the BLS12-381 precompiles with their addresses. +pub fn precompiles() -> impl Iterator { + [ + g1_add::PRECOMPILE, + g1_mul::PRECOMPILE, + g1_msm::PRECOMPILE, + g2_add::PRECOMPILE, + g2_mul::PRECOMPILE, + g2_msm::PRECOMPILE, + pairing::PRECOMPILE, + map_fp_to_g1::PRECOMPILE, + map_fp2_to_g2::PRECOMPILE, + ] + .into_iter() +} + +#[cfg(test)] +mod test { + use super::g1_add; + use super::g1_msm; + use super::g1_mul; + use super::g2_add; + use super::g2_msm; + use super::g2_mul; + use super::map_fp2_to_g2; + use super::map_fp_to_g1; + use super::msm::msm_required_gas; + use super::pairing; + use eyre::Result; + use revm_primitives::{hex::FromHex, Bytes, PrecompileResult}; + use rstest::rstest; + use serde_derive::{Deserialize, Serialize}; + use std::{fs, path::Path}; + + #[derive(Serialize, Deserialize, Debug)] + #[serde(rename_all = "PascalCase")] + struct TestVector { + input: String, + expected: String, + name: String, + gas: u64, + error: Option, + } + + #[derive(Serialize, Deserialize, Debug)] + struct TestVectors(Vec); + + fn load_test_vectors>(path: P) -> Result { + let file_contents = fs::read_to_string(path)?; + Ok(serde_json::from_str(&file_contents)?) + } + + #[rstest] + #[case::g1_add(g1_add::g1_add, "add_G1_bls.json")] + #[case::g1_mul(g1_mul::g1_mul, "mul_G1_bls.json")] + #[case::g1_msm(g1_msm::g1_msm, "multiexp_G1_bls.json")] + #[case::g2_add(g2_add::g2_add, "add_G2_bls.json")] + #[case::g2_mul(g2_mul::g2_mul, "mul_G2_bls.json")] + #[case::g2_msm(g2_msm::g2_msm, "multiexp_G2_bls.json")] + #[case::pairing(pairing::pairing, "pairing_check_bls.json")] + #[case::map_fp_to_g1(map_fp_to_g1::map_fp_to_g1, "map_fp_to_G1_bls.json")] + #[case::map_fp2_to_g2(map_fp2_to_g2::map_fp2_to_g2, "map_fp2_to_G2_bls.json")] + fn test_bls( + #[case] precompile: fn(input: &Bytes, gas_limit: u64) -> PrecompileResult, + #[case] file_name: &str, + ) { + let test_vectors = load_test_vectors(format!("test-vectors/{file_name}")) + .unwrap_or_else(|e| panic!("Failed to load test vectors from {file_name}: {e}")); + + for vector in test_vectors.0 { + let test_name = format!("{file_name}/{}", vector.name); + let input = Bytes::from_hex(vector.input.clone()).unwrap_or_else(|e| { + panic!( + "could not deserialize input {} as hex in {test_name}: {e}", + &vector.input + ) + }); + let target_gas: u64 = 30_000_000; + let res = precompile(&input, target_gas); + if vector.error.unwrap_or_default() { + assert!(res.is_err(), "expected error didn't happen in {test_name}"); + } else { + let (actual_gas, actual_output) = + res.unwrap_or_else(|e| panic!("precompile call failed for {test_name}: {e}")); + assert_eq!( + vector.gas, actual_gas, + "expected gas: {}, actual gas: {} in {test_name}", + vector.gas, actual_gas + ); + let expected_output = Bytes::from_hex(vector.expected).unwrap(); + assert_eq!( + expected_output, actual_output, + "expected output: {expected_output}, actual output: {actual_output} in {test_name}"); + } + } + } + + #[rstest] + #[case::g1_empty(0, g1_mul::BASE_GAS_FEE, 0)] + #[case::g1_one_item(160, g1_mul::BASE_GAS_FEE, 14400)] + #[case::g1_two_items(320, g1_mul::BASE_GAS_FEE, 21312)] + #[case::g1_ten_items(1600, g1_mul::BASE_GAS_FEE, 50760)] + #[case::g1_sixty_four_items(10240, g1_mul::BASE_GAS_FEE, 170496)] + #[case::g1_one_hundred_twenty_eight_items(20480, g1_mul::BASE_GAS_FEE, 267264)] + #[case::g1_one_hundred_twenty_nine_items(20640, g1_mul::BASE_GAS_FEE, 269352)] + #[case::g1_two_hundred_fifty_six_items(40960, g1_mul::BASE_GAS_FEE, 534528)] + fn test_g1_msm_required_gas( + #[case] input_len: usize, + #[case] multiplication_cost: u64, + #[case] expected_output: u64, + ) { + let k = input_len / g1_mul::INPUT_LENGTH; + + let actual_output = msm_required_gas(k, multiplication_cost); + + assert_eq!(expected_output, actual_output); + } +} diff --git a/crates/precompile/src/bls12_381/g1.rs b/crates/precompile/src/bls12_381/g1.rs index 163afb3e..9d4f630d 100644 --- a/crates/precompile/src/bls12_381/g1.rs +++ b/crates/precompile/src/bls12_381/g1.rs @@ -1,5 +1,5 @@ use super::utils::{fp_to_bytes, remove_padding, PADDED_FP_LENGTH}; -use blst::{blst_fp_from_bendian, blst_p1_affine, blst_p1_affine_in_g1}; +use blst::{blst_fp_from_bendian, blst_p1_affine, blst_p1_affine_in_g1, blst_p1_affine_on_curve}; use revm_primitives::{Bytes, PrecompileError}; /// Length of each of the elements in a g1 operation input. @@ -19,7 +19,12 @@ pub(super) fn encode_g1_point(input: *const blst_p1_affine) -> Bytes { } /// Extracts a G1 point in Affine format from a 128 byte slice representation. -pub(super) fn extract_g1_input(input: &[u8]) -> Result { +/// +/// NOTE: This function will perform a G1 subgroup check if `subgroup_check` is set to `true`. +pub(super) fn extract_g1_input( + input: &[u8], + subgroup_check: bool, +) -> Result { if input.len() != G1_INPUT_ITEM_LENGTH { return Err(PrecompileError::Other(format!( "Input should be {G1_INPUT_ITEM_LENGTH} bytes, was {}", @@ -37,9 +42,41 @@ pub(super) fn extract_g1_input(input: &[u8]) -> Result -fn g1_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { +pub(super) fn g1_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { if BASE_GAS_FEE > gas_limit { return Err(PrecompileError::OutOfGas); } @@ -33,8 +33,11 @@ fn g1_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { ))); } - let a_aff = &extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH])?; - let b_aff = &extract_g1_input(&input[G1_INPUT_ITEM_LENGTH..])?; + // NB: There is no subgroup check for the G1 addition precompile. + // + // So we set the subgroup checks here to `false` + let a_aff = &extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH], false)?; + let b_aff = &extract_g1_input(&input[G1_INPUT_ITEM_LENGTH..], false)?; let mut b = blst_p1::default(); // SAFETY: b and b_aff are blst values. diff --git a/crates/precompile/src/bls12_381/g1_msm.rs b/crates/precompile/src/bls12_381/g1_msm.rs index c02f055b..503a7b74 100644 --- a/crates/precompile/src/bls12_381/g1_msm.rs +++ b/crates/precompile/src/bls12_381/g1_msm.rs @@ -22,7 +22,7 @@ pub const ADDRESS: u64 = 0x0d; /// Output is an encoding of multi-scalar-multiplication operation result - single G1 /// point (`128` bytes). /// See also: -fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { +pub(super) fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { let input_len = input.len(); if input_len == 0 || input_len % g1_mul::INPUT_LENGTH != 0 { return Err(PrecompileError::Other(format!( @@ -41,8 +41,12 @@ fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { let mut g1_points: Vec = Vec::with_capacity(k); let mut scalars: Vec = Vec::with_capacity(k * SCALAR_LENGTH); for i in 0..k { + // NB: Scalar multiplications, MSMs and pairings MUST perform a subgroup check. + // + // So we set the subgroup_check flag to `true` let p0_aff = &extract_g1_input( &input[i * g1_mul::INPUT_LENGTH..i * g1_mul::INPUT_LENGTH + G1_INPUT_ITEM_LENGTH], + true, )?; let mut p0 = blst_p1::default(); // SAFETY: p0 and p0_aff are blst values. diff --git a/crates/precompile/src/bls12_381/g1_mul.rs b/crates/precompile/src/bls12_381/g1_mul.rs index 8982cb58..305458e2 100644 --- a/crates/precompile/src/bls12_381/g1_mul.rs +++ b/crates/precompile/src/bls12_381/g1_mul.rs @@ -23,7 +23,7 @@ pub(super) const INPUT_LENGTH: usize = 160; /// Output is an encoding of multiplication operation result - single G1 point /// (`128` bytes). /// See also: -pub fn g1_mul(input: &Bytes, gas_limit: u64) -> PrecompileResult { +pub(super) fn g1_mul(input: &Bytes, gas_limit: u64) -> PrecompileResult { if BASE_GAS_FEE > gas_limit { return Err(PrecompileError::OutOfGas); } @@ -34,7 +34,10 @@ pub fn g1_mul(input: &Bytes, gas_limit: u64) -> PrecompileResult { ))); } - let p0_aff = &extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH])?; + // NB: Scalar multiplications, MSMs and pairings MUST perform a subgroup check. + // + // So we set the subgroup_check flag to `true` + let p0_aff = &extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH], true)?; let mut p0 = blst_p1::default(); // SAFETY: p0 and p0_aff are blst values. unsafe { blst_p1_from_affine(&mut p0, p0_aff) }; diff --git a/crates/precompile/src/bls12_381/g2.rs b/crates/precompile/src/bls12_381/g2.rs index 538bc5be..321fc5f6 100644 --- a/crates/precompile/src/bls12_381/g2.rs +++ b/crates/precompile/src/bls12_381/g2.rs @@ -1,5 +1,5 @@ use super::utils::{fp_to_bytes, remove_padding, FP_LENGTH, PADDED_FP_LENGTH}; -use blst::{blst_fp_from_bendian, blst_p2_affine, blst_p2_affine_in_g2}; +use blst::{blst_fp_from_bendian, blst_p2_affine, blst_p2_affine_in_g2, blst_p2_affine_on_curve}; use revm_primitives::{Bytes, PrecompileError}; /// Length of each of the elements in a g2 operation input. @@ -27,7 +27,12 @@ pub(super) fn encode_g2_point(input: &blst_p2_affine) -> Bytes { } /// Extracts a G2 point in Affine format from a 256 byte slice representation. -pub(super) fn extract_g2_input(input: &[u8]) -> Result { +/// +/// NOTE: This function will perform a G2 subgroup check if `subgroup_check` is set to `true`. +pub(super) fn extract_g2_input( + input: &[u8], + subgroup_check: bool, +) -> Result { if input.len() != G2_INPUT_ITEM_LENGTH { return Err(PrecompileError::Other(format!( "Input should be {G2_INPUT_ITEM_LENGTH} bytes, was {}", @@ -49,9 +54,40 @@ pub(super) fn extract_g2_input(input: &[u8]) -> Result -fn g2_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { +pub(super) fn g2_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { if BASE_GAS_FEE > gas_limit { return Err(PrecompileError::OutOfGas); } @@ -34,8 +34,11 @@ fn g2_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { ))); } - let a_aff = &extract_g2_input(&input[..G2_INPUT_ITEM_LENGTH])?; - let b_aff = &extract_g2_input(&input[G2_INPUT_ITEM_LENGTH..])?; + // NB: There is no subgroup check for the G2 addition precompile. + // + // So we set the subgroup checks here to `false` + let a_aff = &extract_g2_input(&input[..G2_INPUT_ITEM_LENGTH], false)?; + let b_aff = &extract_g2_input(&input[G2_INPUT_ITEM_LENGTH..], false)?; let mut b = blst_p2::default(); // SAFETY: b and b_aff are blst values. diff --git a/crates/precompile/src/bls12_381/g2_msm.rs b/crates/precompile/src/bls12_381/g2_msm.rs index a17c5c47..0becd2b5 100644 --- a/crates/precompile/src/bls12_381/g2_msm.rs +++ b/crates/precompile/src/bls12_381/g2_msm.rs @@ -22,7 +22,7 @@ pub const ADDRESS: u64 = 0x10; /// Output is an encoding of multi-scalar-multiplication operation result - single G2 /// point (`256` bytes). /// See also: -fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { +pub(super) fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { let input_len = input.len(); if input_len == 0 || input_len % g2_mul::INPUT_LENGTH != 0 { return Err(PrecompileError::Other(format!( @@ -41,9 +41,19 @@ fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { let mut g2_points: Vec = Vec::with_capacity(k); let mut scalars: Vec = Vec::with_capacity(k * SCALAR_LENGTH); for i in 0..k { - let p0_aff = &extract_g2_input( - &input[i * g2_mul::INPUT_LENGTH..i * g2_mul::INPUT_LENGTH + G2_INPUT_ITEM_LENGTH], - )?; + let slice = + &input[i * g2_mul::INPUT_LENGTH..i * g2_mul::INPUT_LENGTH + G2_INPUT_ITEM_LENGTH]; + // BLST batch API for p2_affines blows up when you pass it a point at infinity and returns point at infinity + // so we just skip the element, and return 256 bytes in the response + if slice.iter().all(|i| *i == 0) { + continue; + } + + // NB: Scalar multiplications, MSMs and pairings MUST perform a subgroup check. + // + // So we set the subgroup_check flag to `true` + let p0_aff = &extract_g2_input(slice, true)?; + let mut p0 = blst_p2::default(); // SAFETY: p0 and p0_aff are blst values. unsafe { blst_p2_from_affine(&mut p0, p0_aff) }; @@ -59,6 +69,11 @@ fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { ); } + // return infinity point if all points are infinity + if g2_points.is_empty() { + return Ok((required_gas, vec![0; 256].into())); + } + let points = p2_affines::from(&g2_points); let multiexp = points.mult(&scalars, NBITS); diff --git a/crates/precompile/src/bls12_381/g2_mul.rs b/crates/precompile/src/bls12_381/g2_mul.rs index d7d6883b..62cb903e 100644 --- a/crates/precompile/src/bls12_381/g2_mul.rs +++ b/crates/precompile/src/bls12_381/g2_mul.rs @@ -23,7 +23,7 @@ pub(super) const INPUT_LENGTH: usize = 288; /// Output is an encoding of multiplication operation result - single G2 point /// (`256` bytes). /// See also: -fn g2_mul(input: &Bytes, gas_limit: u64) -> PrecompileResult { +pub(super) fn g2_mul(input: &Bytes, gas_limit: u64) -> PrecompileResult { if BASE_GAS_FEE > gas_limit { return Err(PrecompileError::OutOfGas); } @@ -34,7 +34,10 @@ fn g2_mul(input: &Bytes, gas_limit: u64) -> PrecompileResult { ))); } - let p0_aff = &extract_g2_input(&input[..G2_INPUT_ITEM_LENGTH])?; + // NB: Scalar multiplications, MSMs and pairings MUST perform a subgroup check. + // + // So we set the subgroup_check flag to `true` + let p0_aff = &extract_g2_input(&input[..G2_INPUT_ITEM_LENGTH], true)?; let mut p0 = blst_p2::default(); // SAFETY: p0 and p0_aff are blst values. unsafe { blst_p2_from_affine(&mut p0, p0_aff) }; diff --git a/crates/precompile/src/bls12_381/map_fp2_to_g2.rs b/crates/precompile/src/bls12_381/map_fp2_to_g2.rs index 4615ffd8..51a90ac3 100644 --- a/crates/precompile/src/bls12_381/map_fp2_to_g2.rs +++ b/crates/precompile/src/bls12_381/map_fp2_to_g2.rs @@ -21,7 +21,7 @@ const BASE_GAS_FEE: u64 = 75000; /// an element of Fp2. Output of this call is 256 bytes and is an encoded G2 /// point. /// See also: -fn map_fp2_to_g2(input: &Bytes, gas_limit: u64) -> PrecompileResult { +pub(super) fn map_fp2_to_g2(input: &Bytes, gas_limit: u64) -> PrecompileResult { if BASE_GAS_FEE > gas_limit { return Err(PrecompileError::OutOfGas); } diff --git a/crates/precompile/src/bls12_381/map_fp_to_g1.rs b/crates/precompile/src/bls12_381/map_fp_to_g1.rs index b161f7d3..a6d9f48e 100644 --- a/crates/precompile/src/bls12_381/map_fp_to_g1.rs +++ b/crates/precompile/src/bls12_381/map_fp_to_g1.rs @@ -19,7 +19,7 @@ const MAP_FP_TO_G1_BASE: u64 = 5500; /// Field-to-curve call expects 64 bytes as an input that is interpreted as an /// element of Fp. Output of this call is 128 bytes and is an encoded G1 point. /// See also: -fn map_fp_to_g1(input: &Bytes, gas_limit: u64) -> PrecompileResult { +pub(super) fn map_fp_to_g1(input: &Bytes, gas_limit: u64) -> PrecompileResult { if MAP_FP_TO_G1_BASE > gas_limit { return Err(PrecompileError::OutOfGas); } diff --git a/crates/precompile/src/bls12_381/mod.rs b/crates/precompile/src/bls12_381/mod.rs deleted file mode 100644 index 764c4a50..00000000 --- a/crates/precompile/src/bls12_381/mod.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::PrecompileWithAddress; - -mod g1; -pub mod g1_add; -pub mod g1_msm; -pub mod g1_mul; -mod g2; -pub mod g2_add; -pub mod g2_msm; -pub mod g2_mul; -pub mod map_fp2_to_g2; -pub mod map_fp_to_g1; -mod msm; -pub mod pairing; -mod utils; - -/// Returns the BLS12-381 precompiles with their addresses. -pub fn precompiles() -> impl Iterator { - [ - g1_add::PRECOMPILE, - g1_mul::PRECOMPILE, - g1_msm::PRECOMPILE, - g2_add::PRECOMPILE, - g2_mul::PRECOMPILE, - g2_msm::PRECOMPILE, - pairing::PRECOMPILE, - map_fp_to_g1::PRECOMPILE, - map_fp2_to_g2::PRECOMPILE, - ] - .into_iter() -} diff --git a/crates/precompile/src/bls12_381/pairing.rs b/crates/precompile/src/bls12_381/pairing.rs index fb83e448..2a699a08 100644 --- a/crates/precompile/src/bls12_381/pairing.rs +++ b/crates/precompile/src/bls12_381/pairing.rs @@ -29,7 +29,7 @@ const INPUT_LENGTH: usize = 384; /// is 0x01 if pairing result is equal to the multiplicative identity in a pairing /// target field and 0x00 otherwise. /// See also: -fn pairing(input: &Bytes, gas_limit: u64) -> PrecompileResult { +pub(super) fn pairing(input: &Bytes, gas_limit: u64) -> PrecompileResult { let input_len = input.len(); if input_len == 0 || input_len % INPUT_LENGTH != 0 { return Err(PrecompileError::Other(format!( @@ -46,12 +46,21 @@ fn pairing(input: &Bytes, gas_limit: u64) -> PrecompileResult { // accumulator for the fp12 multiplications of the miller loops. let mut acc = blst_fp12::default(); for i in 0..k { - let p1_aff = - &extract_g1_input(&input[i * INPUT_LENGTH..i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH])?; + // NB: Scalar multiplications, MSMs and pairings MUST perform a subgroup check. + // + // So we set the subgroup_check flag to `true` + let p1_aff = &extract_g1_input( + &input[i * INPUT_LENGTH..i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH], + true, + )?; + // NB: Scalar multiplications, MSMs and pairings MUST perform a subgroup check. + // + // So we set the subgroup_check flag to `true` let p2_aff = &extract_g2_input( &input[i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH ..i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + G2_INPUT_ITEM_LENGTH], + true, )?; if i > 0 { diff --git a/crates/precompile/test-vectors/add_G1_bls.json b/crates/precompile/test-vectors/add_G1_bls.json new file mode 100644 index 00000000..a7f44dda --- /dev/null +++ b/crates/precompile/test-vectors/add_G1_bls.json @@ -0,0 +1,65 @@ +[ + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21", + "Name": "bls_g1add_g1+p1", + "Expected": "000000000000000000000000000000000a40300ce2dec9888b60690e9a41d3004fda4886854573974fab73b046d3147ba5b7a5bde85279ffede1b45b3918d82d0000000000000000000000000000000006d3d887e9f53b9ec4eb6cedf5607226754b07c01ace7834f57f3e7315faefb739e59018e22c492006190fba4a870025", + "Gas": 500, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", + "Name": "bls_g1add_p1+g1", + "Expected": "000000000000000000000000000000000a40300ce2dec9888b60690e9a41d3004fda4886854573974fab73b046d3147ba5b7a5bde85279ffede1b45b3918d82d0000000000000000000000000000000006d3d887e9f53b9ec4eb6cedf5607226754b07c01ace7834f57f3e7315faefb739e59018e22c492006190fba4a870025", + "Gas": 500, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000000000000000000000000000000193fb7cedb32b2c3adc06ec11a96bc0d661869316f5e4a577a9f7c179593987beb4fb2ee424dbb2f5dd891e228b46c4a0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", + "Name": "bls_g1add_g1_wrong_order+g1", + "Expected": "000000000000000000000000000000000abe7ae4ae2b092a5cc1779b1f5605d904fa6ec59b0f084907d1f5e4d2663e117a3810e027210a72186159a21271df3e0000000000000000000000000000000001e1669f00e10205f2e2f1195d65c21022f6a9a6de21f329756309815281a4434b2864d34ebcbc1d7e7cfaaee3feeea2", + "Gas": 500, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g1add_(g1+0=g1)", + "Expected": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", + "Gas": 500, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g1add_(p1+0=p1)", + "Expected": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21", + "Gas": 500, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb00000000000000000000000000000000114d1d6855d545a8aa7d76c8cf2e21f267816aef1db507c96655b9d5caac42364e6f38ba0ecb751bad54dcd6b939c2ca", + "Name": "bls_g1add_(g1-g1=0)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 500, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a2100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca9426000000000000000000000000000000000195e911162921ba5ed055b496420f197693d36569ec34c63d7c0529a097d49e543070afba4b707e878e53c2b779208a", + "Name": "bls_g1add_(p1-p1=0)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 500, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", + "Name": "bls_g1add_(g1+g1=2*g1)", + "Expected": "000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28", + "Gas": 500, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a2100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21", + "Name": "bls_g1add_(p1+p1=2*p1)", + "Expected": "0000000000000000000000000000000015222cddbabdd764c4bee0b3720322a65ff4712c86fc4b1588d0c209210a0884fa9468e855d261c483091b2bf7de6a630000000000000000000000000000000009f9edb99bc3b75d7489735c98b16ab78b9386c5f7a1f76c7e96ac6eb5bbde30dbca31a74ec6e0f0b12229eecea33c39", + "Gas": 500, + "NoBenchmark": false + } +] diff --git a/crates/precompile/test-vectors/add_G2_bls.json b/crates/precompile/test-vectors/add_G2_bls.json new file mode 100644 index 00000000..36a7614d --- /dev/null +++ b/crates/precompile/test-vectors/add_G2_bls.json @@ -0,0 +1,65 @@ +[ + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451", + "Name": "bls_g2add_g2+p2", + "Expected": "000000000000000000000000000000000b54a8a7b08bd6827ed9a797de216b8c9057b3a9ca93e2f88e7f04f19accc42da90d883632b9ca4dc38d013f71ede4db00000000000000000000000000000000077eba4eecf0bd764dce8ed5f45040dd8f3b3427cb35230509482c14651713282946306247866dfe39a8e33016fcbe520000000000000000000000000000000014e60a76a29ef85cbd69f251b9f29147b67cfe3ed2823d3f9776b3a0efd2731941d47436dc6d2b58d9e65f8438bad073000000000000000000000000000000001586c3c910d95754fef7a732df78e279c3d37431c6a2b77e67a00c7c130a8fcd4d19f159cbeb997a178108fffffcbd20", + "Gas": 800, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d87845100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", + "Name": "bls_g2add_p2+g2", + "Expected": "000000000000000000000000000000000b54a8a7b08bd6827ed9a797de216b8c9057b3a9ca93e2f88e7f04f19accc42da90d883632b9ca4dc38d013f71ede4db00000000000000000000000000000000077eba4eecf0bd764dce8ed5f45040dd8f3b3427cb35230509482c14651713282946306247866dfe39a8e33016fcbe520000000000000000000000000000000014e60a76a29ef85cbd69f251b9f29147b67cfe3ed2823d3f9776b3a0efd2731941d47436dc6d2b58d9e65f8438bad073000000000000000000000000000000001586c3c910d95754fef7a732df78e279c3d37431c6a2b77e67a00c7c130a8fcd4d19f159cbeb997a178108fffffcbd20", + "Gas": 800, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000197bfd0342bbc8bee2beced2f173e1a87be576379b343e93232d6cef98d84b1d696e5612ff283ce2cfdccb2cfb65fa0c00000000000000000000000000000000184e811f55e6f9d84d77d2f79102fd7ea7422f4759df5bf7f6331d550245e3f1bcf6a30e3b29110d85e0ca16f9f6ae7a000000000000000000000000000000000f10e1eb3c1e53d2ad9cf2d398b2dc22c5842fab0a74b174f691a7e914975da3564d835cd7d2982815b8ac57f507348f000000000000000000000000000000000767d1c453890f1b9110fda82f5815c27281aba3f026ee868e4176a0654feea41a96575e0c4d58a14dbfbcc05b5010b100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", + "Name": "bls_g2add_g2_wrong_order+g2", + "Expected": "0000000000000000000000000000000011f00077935238fc57086414804303b20fab5880bc29f35ebda22c13dd44e586c8a889fe2ba799082c8458d861ac10cf0000000000000000000000000000000007318be09b19be000fe5df77f6e664a8286887ad8373005d7f7a203fcc458c28004042780146d3e43fa542d921c69512000000000000000000000000000000001287eab085d6f8a29f1f1aedb5ad9e8546963f0b11865e05454d86b9720c281db567682a233631f63a2794432a5596ae0000000000000000000000000000000012ec87cea1bacb75aa97728bcd64b27c7a42dd2319a2e17fe3837a05f85d089c5ebbfb73c1d08b7007e2b59ec9c8e065", + "Gas": 800, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g2add_(g2+0=g2)", + "Expected": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", + "Gas": 800, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d87845100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g2add_(p2+0=p2)", + "Expected": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451", + "Gas": 800, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", + "Name": "bls_g2add_(g2-g2=0)", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 800, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d87845100000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000a6296409115572426717c73668335a949829d739cff2cb4ab043710d28f8e772f6ef41aac4806c9cb273c490384032d000000000000000000000000000000000cde4e850c721fa94e8890d500e3655b442d5c0dc4fff1b694c6f8dd68f6d8dc1bc3251a37d27e7af96f65a96278265a", + "Name": "bls_g2add_(p2-p2=0)", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 800, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", + "Name": "bls_g2add_(g2+g2=2*g2)", + "Expected": "000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3", + "Gas": 800, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d87845100000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451", + "Name": "bls_g2add_(p2+p2=2*p2)", + "Expected": "000000000000000000000000000000000b76fcbb604082a4f2d19858a7befd6053fa181c5119a612dfec83832537f644e02454f2b70d40985ebb08042d1620d40000000000000000000000000000000019a4a02c0ae51365d964c73be7babb719db1c69e0ddbf9a8a335b5bed3b0a4b070d2d5df01d2da4a3f1e56aae2ec106d000000000000000000000000000000000d18322f821ac72d3ca92f92b000483cf5b7d9e5d06873a44071c4e7e81efd904f210208fe0b9b4824f01c65bc7e62080000000000000000000000000000000004e563d53609a2d1e216aaaee5fbc14ef460160db8d1fdc5e1bd4e8b54cd2f39abf6f925969fa405efb9e700b01c7085", + "Gas": 800, + "NoBenchmark": false + } +] diff --git a/crates/precompile/test-vectors/map_fp2_to_G2_bls.json b/crates/precompile/test-vectors/map_fp2_to_G2_bls.json new file mode 100644 index 00000000..fa96b288 --- /dev/null +++ b/crates/precompile/test-vectors/map_fp2_to_G2_bls.json @@ -0,0 +1,37 @@ +[ + { + "Input": "0000000000000000000000000000000007355d25caf6e7f2f0cb2812ca0e513bd026ed09dda65b177500fa31714e09ea0ded3a078b526bed3307f804d4b93b040000000000000000000000000000000002829ce3c021339ccb5caf3e187f6370e1e2a311dec9b75363117063ab2015603ff52c3d3b98f19c2f65575e99e8b78c", + "Name": "bls_g2map_", + "Expected": "0000000000000000000000000000000000e7f4568a82b4b7dc1f14c6aaa055edf51502319c723c4dc2688c7fe5944c213f510328082396515734b6612c4e7bb700000000000000000000000000000000126b855e9e69b1f691f816e48ac6977664d24d99f8724868a184186469ddfd4617367e94527d4b74fc86413483afb35b000000000000000000000000000000000caead0fd7b6176c01436833c79d305c78be307da5f6af6c133c47311def6ff1e0babf57a0fb5539fce7ee12407b0a42000000000000000000000000000000001498aadcf7ae2b345243e281ae076df6de84455d766ab6fcdaad71fab60abb2e8b980a440043cd305db09d283c895e3d", + "Gas": 75000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000138879a9559e24cecee8697b8b4ad32cced053138ab913b99872772dc753a2967ed50aabc907937aefb2439ba06cc50c000000000000000000000000000000000a1ae7999ea9bab1dcc9ef8887a6cb6e8f1e22566015428d220b7eec90ffa70ad1f624018a9ad11e78d588bd3617f9f2", + "Name": "bls_g2map_616263", + "Expected": "00000000000000000000000000000000108ed59fd9fae381abfd1d6bce2fd2fa220990f0f837fa30e0f27914ed6e1454db0d1ee957b219f61da6ff8be0d6441f000000000000000000000000000000000296238ea82c6d4adb3c838ee3cb2346049c90b96d602d7bb1b469b905c9228be25c627bffee872def773d5b2a2eb57d00000000000000000000000000000000033f90f6057aadacae7963b0a0b379dd46750c1c94a6357c99b65f63b79e321ff50fe3053330911c56b6ceea08fee65600000000000000000000000000000000153606c417e59fb331b7ae6bce4fbf7c5190c33ce9402b5ebe2b70e44fca614f3f1382a3625ed5493843d0b0a652fc3f", + "Gas": 75000, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000018c16fe362b7dbdfa102e42bdfd3e2f4e6191d479437a59db4eb716986bf08ee1f42634db66bde97d6c16bbfd342b3b8000000000000000000000000000000000e37812ce1b146d998d5f92bdd5ada2a31bfd63dfe18311aa91637b5f279dd045763166aa1615e46a50d8d8f475f184e", + "Name": "bls_g2map_6162636465663031", + "Expected": "00000000000000000000000000000000038af300ef34c7759a6caaa4e69363cafeed218a1f207e93b2c70d91a1263d375d6730bd6b6509dcac3ba5b567e85bf3000000000000000000000000000000000da75be60fb6aa0e9e3143e40c42796edf15685cafe0279afd2a67c3dff1c82341f17effd402e4f1af240ea90f4b659b0000000000000000000000000000000019b148cbdf163cf0894f29660d2e7bfb2b68e37d54cc83fd4e6e62c020eaa48709302ef8e746736c0e19342cc1ce3df4000000000000000000000000000000000492f4fed741b073e5a82580f7c663f9b79e036b70ab3e51162359cec4e77c78086fe879b65ca7a47d34374c8315ac5e", + "Gas": 75000, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000008d4a0997b9d52fecf99427abb721f0fa779479963315fe21c6445250de7183e3f63bfdf86570da8929489e421d4ee950000000000000000000000000000000016cb4ccad91ec95aab070f22043916cd6a59c4ca94097f7f510043d48515526dc8eaaea27e586f09151ae613688d5a89", + "Name": "bls_g2map_713132385f717171", + "Expected": "000000000000000000000000000000000c5ae723be00e6c3f0efe184fdc0702b64588fe77dda152ab13099a3bacd3876767fa7bbad6d6fd90b3642e902b208f90000000000000000000000000000000012c8c05c1d5fc7bfa847f4d7d81e294e66b9a78bc9953990c358945e1f042eedafce608b67fdd3ab0cb2e6e263b9b1ad0000000000000000000000000000000004e77ddb3ede41b5ec4396b7421dd916efc68a358a0d7425bddd253547f2fb4830522358491827265dfc5bcc1928a5690000000000000000000000000000000011c624c56dbe154d759d021eec60fab3d8b852395a89de497e48504366feedd4662d023af447d66926a28076813dd646", + "Gas": 75000, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000003f80ce4ff0ca2f576d797a3660e3f65b274285c054feccc3215c879e2c0589d376e83ede13f93c32f05da0f68fd6a1000000000000000000000000000000000006488a837c5413746d868d1efb7232724da10eca410b07d8b505b9363bdccf0a1fc0029bad07d65b15ccfe6dd25e20d", + "Name": "bls_g2map_613531325f616161", + "Expected": "000000000000000000000000000000000ea4e7c33d43e17cc516a72f76437c4bf81d8f4eac69ac355d3bf9b71b8138d55dc10fd458be115afa798b55dac34be1000000000000000000000000000000001565c2f625032d232f13121d3cfb476f45275c303a037faa255f9da62000c2c864ea881e2bcddd111edc4a3c0da3e88d00000000000000000000000000000000043b6f5fe4e52c839148dc66f2b3751e69a0f6ebb3d056d6465d50d4108543ecd956e10fa1640dfd9bc0030cc2558d28000000000000000000000000000000000f8991d2a1ad662e7b6f58ab787947f1fa607fce12dde171bc17903b012091b657e15333e11701edcf5b63ba2a561247", + "Gas": 75000, + "NoBenchmark": false + } +] diff --git a/crates/precompile/test-vectors/map_fp_to_G1_bls.json b/crates/precompile/test-vectors/map_fp_to_G1_bls.json new file mode 100644 index 00000000..80ca454d --- /dev/null +++ b/crates/precompile/test-vectors/map_fp_to_G1_bls.json @@ -0,0 +1,37 @@ +[ + { + "Input": "00000000000000000000000000000000156c8a6a2c184569d69a76be144b5cdc5141d2d2ca4fe341f011e25e3969c55ad9e9b9ce2eb833c81a908e5fa4ac5f03", + "Name": "bls_g1map_", + "Expected": "00000000000000000000000000000000184bb665c37ff561a89ec2122dd343f20e0f4cbcaec84e3c3052ea81d1834e192c426074b02ed3dca4e7676ce4ce48ba0000000000000000000000000000000004407b8d35af4dacc809927071fc0405218f1401a6d15af775810e4e460064bcc9468beeba82fdc751be70476c888bf3", + "Gas": 5500, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000147e1ed29f06e4c5079b9d14fc89d2820d32419b990c1c7bb7dbea2a36a045124b31ffbde7c99329c05c559af1c6cc82", + "Name": "bls_g1map_616263", + "Expected": "00000000000000000000000000000000009769f3ab59bfd551d53a5f846b9984c59b97d6842b20a2c565baa167945e3d026a3755b6345df8ec7e6acb6868ae6d000000000000000000000000000000001532c00cf61aa3d0ce3e5aa20c3b531a2abd2c770a790a2613818303c6b830ffc0ecf6c357af3317b9575c567f11cd2c", + "Gas": 5500, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000004090815ad598a06897dd89bcda860f25837d54e897298ce31e6947378134d3761dc59a572154963e8c954919ecfa82d", + "Name": "bls_g1map_6162636465663031", + "Expected": "000000000000000000000000000000001974dbb8e6b5d20b84df7e625e2fbfecb2cdb5f77d5eae5fb2955e5ce7313cae8364bc2fff520a6c25619739c6bdcb6a0000000000000000000000000000000015f9897e11c6441eaa676de141c8d83c37aab8667173cbe1dfd6de74d11861b961dccebcd9d289ac633455dfcc7013a3", + "Gas": 5500, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000008dccd088ca55b8bfbc96fb50bb25c592faa867a8bb78d4e94a8cc2c92306190244532e91feba2b7fed977e3c3bb5a1f", + "Name": "bls_g1map_713132385f717171", + "Expected": "000000000000000000000000000000000a7a047c4a8397b3446450642c2ac64d7239b61872c9ae7a59707a8f4f950f101e766afe58223b3bff3a19a7f754027c000000000000000000000000000000001383aebba1e4327ccff7cf9912bda0dbc77de048b71ef8c8a81111d71dc33c5e3aa6edee9cf6f5fe525d50cc50b77cc9", + "Gas": 5500, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000dd824886d2123a96447f6c56e3a3fa992fbfefdba17b6673f9f630ff19e4d326529db37e1c1be43f905bf9202e0278d", + "Name": "bls_g1map_613531325f616161", + "Expected": "000000000000000000000000000000000e7a16a975904f131682edbb03d9560d3e48214c9986bd50417a77108d13dc957500edf96462a3d01e62dc6cd468ef11000000000000000000000000000000000ae89e677711d05c30a48d6d75e76ca9fb70fe06c6dd6ff988683d89ccde29ac7d46c53bb97a59b1901abf1db66052db", + "Gas": 5500, + "NoBenchmark": false + } +] \ No newline at end of file diff --git a/crates/precompile/test-vectors/mul_G1_bls.json b/crates/precompile/test-vectors/mul_G1_bls.json new file mode 100644 index 00000000..e67f76f9 --- /dev/null +++ b/crates/precompile/test-vectors/mul_G1_bls.json @@ -0,0 +1,79 @@ +[ + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g1mul_(g1+g1=2*g1)", + "Expected": "000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g1mul_(p1+p1=2*p1)", + "Expected": "0000000000000000000000000000000015222cddbabdd764c4bee0b3720322a65ff4712c86fc4b1588d0c209210a0884fa9468e855d261c483091b2bf7de6a630000000000000000000000000000000009f9edb99bc3b75d7489735c98b16ab78b9386c5f7a1f76c7e96ac6eb5bbde30dbca31a74ec6e0f0b12229eecea33c39", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000001", + "Name": "bls_g1mul_(1*g1=g1)", + "Expected": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000001", + "Name": "bls_g1mul_(1*p1=p1)", + "Expected": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g1mul_(0*g1=inf)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g1mul_(0*p1=inf)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011", + "Name": "bls_g1mul_(x*inf=inf)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e3", + "Name": "bls_g1mul_random*g1", + "Expected": "000000000000000000000000000000000491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a0000000000000000000000000000000017cd7061575d3e8034fcea62adaa1a3bc38dca4b50e4c5c01d04dd78037c9cee914e17944ea99e7ad84278e5d49f36c4", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e3", + "Name": "bls_g1mul_random*p1", + "Expected": "0000000000000000000000000000000006ee9c9331228753bcb148d0ca8623447701bb0aa6eafb0340aa7f81543923474e00f2a225de65c62dd1d8303270220c0000000000000000000000000000000018dd7be47eb4e80985d7a0d2cc96c8b004250b36a5c3ec0217705d453d3ecc6d0d3d1588722da51b40728baba1e93804", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e19a2b64cc58f8992cb21237914262ca9ada6cb13dc7b7d3f11c278fe0462040e4", + "Name": "bls_g1mul_random*g1_unnormalized_scalar", + "Expected": "000000000000000000000000000000000491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a0000000000000000000000000000000017cd7061575d3e8034fcea62adaa1a3bc38dca4b50e4c5c01d04dd78037c9cee914e17944ea99e7ad84278e5d49f36c4", + "Gas": 12000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a219a2b64cc58f8992cb21237914262ca9ada6cb13dc7b7d3f11c278fe0462040e4", + "Name": "bls_g1mul_random*p1_unnormalized_scalar", + "Expected": "0000000000000000000000000000000006ee9c9331228753bcb148d0ca8623447701bb0aa6eafb0340aa7f81543923474e00f2a225de65c62dd1d8303270220c0000000000000000000000000000000018dd7be47eb4e80985d7a0d2cc96c8b004250b36a5c3ec0217705d453d3ecc6d0d3d1588722da51b40728baba1e93804", + "Gas": 12000, + "NoBenchmark": false + } +] diff --git a/crates/precompile/test-vectors/mul_G2_bls.json b/crates/precompile/test-vectors/mul_G2_bls.json new file mode 100644 index 00000000..1d41f3da --- /dev/null +++ b/crates/precompile/test-vectors/mul_G2_bls.json @@ -0,0 +1,79 @@ +[ + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g2mul_(g2+g2=2*g2)", + "Expected": "000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3", + "Gas": 45000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g2mul_(p2+p2=2*p2)", + "Expected": "000000000000000000000000000000000b76fcbb604082a4f2d19858a7befd6053fa181c5119a612dfec83832537f644e02454f2b70d40985ebb08042d1620d40000000000000000000000000000000019a4a02c0ae51365d964c73be7babb719db1c69e0ddbf9a8a335b5bed3b0a4b070d2d5df01d2da4a3f1e56aae2ec106d000000000000000000000000000000000d18322f821ac72d3ca92f92b000483cf5b7d9e5d06873a44071c4e7e81efd904f210208fe0b9b4824f01c65bc7e62080000000000000000000000000000000004e563d53609a2d1e216aaaee5fbc14ef460160db8d1fdc5e1bd4e8b54cd2f39abf6f925969fa405efb9e700b01c7085", + "Gas": 45000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000001", + "Name": "bls_g2mul_(1*g2=g2)", + "Expected": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", + "Gas": 45000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000001", + "Name": "bls_g2mul_(1*p2=p2)", + "Expected": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451", + "Gas": 45000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g2mul_(0*g2=inf)", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 45000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g2mul_(0*p2=inf)", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 45000, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011", + "Name": "bls_g2mul_(x*inf=inf)", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 45000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e3", + "Name": "bls_g2mul_random*g2", + "Expected": "0000000000000000000000000000000014856c22d8cdb2967c720e963eedc999e738373b14172f06fc915769d3cc5ab7ae0a1b9c38f48b5585fb09d4bd2733bb000000000000000000000000000000000c400b70f6f8cd35648f5c126cce5417f3be4d8eefbd42ceb4286a14df7e03135313fe5845e3a575faab3e8b949d248800000000000000000000000000000000149a0aacc34beba2beb2f2a19a440166e76e373194714f108e4ab1c3fd331e80f4e73e6b9ea65fe3ec96d7136de81544000000000000000000000000000000000e4622fef26bdb9b1e8ef6591a7cc99f5b73164500c1ee224b6a761e676b8799b09a3fd4fa7e242645cc1a34708285e4", + "Gas": 45000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e3", + "Name": "bls_g2mul_random*p2", + "Expected": "00000000000000000000000000000000036074dcbbd0e987531bfe0e45ddfbe09fd015665990ee0c352e8e403fe6af971d8f42141970d9ab14b4dd04874409e600000000000000000000000000000000019705637f24ba2f398f32c3a3e20d6a1cd0fd63e6f8f071cf603a8334f255744927e7bfdfdb18519e019c49ff6e914500000000000000000000000000000000008e74fcff4c4278c9accfb60809ed69bbcbe3d6213ef2304e078d15ec7d6decb4f462b24b8e7cc38cc11b6f2c9e0486000000000000000000000000000000001331d40100f38c1070afd832445881b47cf4d63894666d9907c85ac66604aab5ad329980938cc3c167ccc5b6bc1b8f30", + "Gas": 45000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be9a2b64cc58f8992cb21237914262ca9ada6cb13dc7b7d3f11c278fe0462040e4", + "Name": "bls_g2mul_random*g2_unnormalized_scalar", + "Expected": "0000000000000000000000000000000014856c22d8cdb2967c720e963eedc999e738373b14172f06fc915769d3cc5ab7ae0a1b9c38f48b5585fb09d4bd2733bb000000000000000000000000000000000c400b70f6f8cd35648f5c126cce5417f3be4d8eefbd42ceb4286a14df7e03135313fe5845e3a575faab3e8b949d248800000000000000000000000000000000149a0aacc34beba2beb2f2a19a440166e76e373194714f108e4ab1c3fd331e80f4e73e6b9ea65fe3ec96d7136de81544000000000000000000000000000000000e4622fef26bdb9b1e8ef6591a7cc99f5b73164500c1ee224b6a761e676b8799b09a3fd4fa7e242645cc1a34708285e4", + "Gas": 45000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784519a2b64cc58f8992cb21237914262ca9ada6cb13dc7b7d3f11c278fe0462040e4", + "Name": "bls_g2mul_random*p2_unnormalized_scalar", + "Expected": "00000000000000000000000000000000036074dcbbd0e987531bfe0e45ddfbe09fd015665990ee0c352e8e403fe6af971d8f42141970d9ab14b4dd04874409e600000000000000000000000000000000019705637f24ba2f398f32c3a3e20d6a1cd0fd63e6f8f071cf603a8334f255744927e7bfdfdb18519e019c49ff6e914500000000000000000000000000000000008e74fcff4c4278c9accfb60809ed69bbcbe3d6213ef2304e078d15ec7d6decb4f462b24b8e7cc38cc11b6f2c9e0486000000000000000000000000000000001331d40100f38c1070afd832445881b47cf4d63894666d9907c85ac66604aab5ad329980938cc3c167ccc5b6bc1b8f30", + "Gas": 45000, + "NoBenchmark": false + } +] diff --git a/crates/precompile/test-vectors/multiexp_G1_bls.json b/crates/precompile/test-vectors/multiexp_G1_bls.json new file mode 100644 index 00000000..0a137378 --- /dev/null +++ b/crates/precompile/test-vectors/multiexp_G1_bls.json @@ -0,0 +1,79 @@ +[ + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g1multiexp_(g1+g1=2*g1)", + "Expected": "000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28", + "Gas": 14400, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g1multiexp_(p1+p1=2*p1)", + "Expected": "0000000000000000000000000000000015222cddbabdd764c4bee0b3720322a65ff4712c86fc4b1588d0c209210a0884fa9468e855d261c483091b2bf7de6a630000000000000000000000000000000009f9edb99bc3b75d7489735c98b16ab78b9386c5f7a1f76c7e96ac6eb5bbde30dbca31a74ec6e0f0b12229eecea33c39", + "Gas": 14400, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000001", + "Name": "bls_g1multiexp_(1*g1=g1)", + "Expected": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", + "Gas": 14400, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000001", + "Name": "bls_g1multiexp_(1*p1=p1)", + "Expected": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21", + "Gas": 14400, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g1multiexp_(0*g1=inf)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 14400, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g1multiexp_(0*p1=inf)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 14400, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011", + "Name": "bls_g1multiexp_(x*inf=inf)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 14400, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g1multiexp_(2g1+inf)", + "Expected": "000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28", + "Gas": 21312, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g1multiexp_(inf+inf)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 21312, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g1multiexp_(2g1+2p1)", + "Expected": "00000000000000000000000000000000148f92dced907361b4782ab542a75281d4b6f71f65c8abf94a5a9082388c64662d30fd6a01ced724feef3e284752038c0000000000000000000000000000000015c3634c3b67bc18e19150e12bfd8a1769306ed010f59be645a0823acb5b38f39e8e0d86e59b6353fdafc59ca971b769", + "Gas": 21312, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e300000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a2147b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff66513800000000000000000000000000000000184bb665c37ff561a89ec2122dd343f20e0f4cbcaec84e3c3052ea81d1834e192c426074b02ed3dca4e7676ce4ce48ba0000000000000000000000000000000004407b8d35af4dacc809927071fc0405218f1401a6d15af775810e4e460064bcc9468beeba82fdc751be70476c888bf3328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d21600000000000000000000000000000000009769f3ab59bfd551d53a5f846b9984c59b97d6842b20a2c565baa167945e3d026a3755b6345df8ec7e6acb6868ae6d000000000000000000000000000000001532c00cf61aa3d0ce3e5aa20c3b531a2abd2c770a790a2613818303c6b830ffc0ecf6c357af3317b9575c567f11cd2c263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e2000000000000000000000000000000001974dbb8e6b5d20b84df7e625e2fbfecb2cdb5f77d5eae5fb2955e5ce7313cae8364bc2fff520a6c25619739c6bdcb6a0000000000000000000000000000000015f9897e11c6441eaa676de141c8d83c37aab8667173cbe1dfd6de74d11861b961dccebcd9d289ac633455dfcc7013a347b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff665131000000000000000000000000000000000a7a047c4a8397b3446450642c2ac64d7239b61872c9ae7a59707a8f4f950f101e766afe58223b3bff3a19a7f754027c000000000000000000000000000000001383aebba1e4327ccff7cf9912bda0dbc77de048b71ef8c8a81111d71dc33c5e3aa6edee9cf6f5fe525d50cc50b77cc9328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d211000000000000000000000000000000000e7a16a975904f131682edbb03d9560d3e48214c9986bd50417a77108d13dc957500edf96462a3d01e62dc6cd468ef11000000000000000000000000000000000ae89e677711d05c30a48d6d75e76ca9fb70fe06c6dd6ff988683d89ccde29ac7d46c53bb97a59b1901abf1db66052db55b53c4669f19f0fc7431929bc0363d7d8fb432435fcde2635fdba334424e9f5", + "Name": "bls_g1multiexp_multiple", + "Expected": "00000000000000000000000000000000053fbdb09b6b5faa08bfe7b7069454247ad4d8bd57e90e2d2ebaa04003dcf110aa83072c07f480ab2107cca2ccff6091000000000000000000000000000000001654537b7c96fe64d13906066679c3d45808cb666452b55d1b909c230cc4b423c3f932c58754b9b762dc49fcc825522c", + "Gas": 42000, + "NoBenchmark": false + } +] \ No newline at end of file diff --git a/crates/precompile/test-vectors/multiexp_G2_bls.json b/crates/precompile/test-vectors/multiexp_G2_bls.json new file mode 100644 index 00000000..fdf50e0f --- /dev/null +++ b/crates/precompile/test-vectors/multiexp_G2_bls.json @@ -0,0 +1,86 @@ +[ + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g2multiexp_(g2+g2=2*g2)", + "Expected": "000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3", + "Gas": 54000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g2multiexp_(p2+p2=2*p2)", + "Expected": "000000000000000000000000000000000b76fcbb604082a4f2d19858a7befd6053fa181c5119a612dfec83832537f644e02454f2b70d40985ebb08042d1620d40000000000000000000000000000000019a4a02c0ae51365d964c73be7babb719db1c69e0ddbf9a8a335b5bed3b0a4b070d2d5df01d2da4a3f1e56aae2ec106d000000000000000000000000000000000d18322f821ac72d3ca92f92b000483cf5b7d9e5d06873a44071c4e7e81efd904f210208fe0b9b4824f01c65bc7e62080000000000000000000000000000000004e563d53609a2d1e216aaaee5fbc14ef460160db8d1fdc5e1bd4e8b54cd2f39abf6f925969fa405efb9e700b01c7085", + "Gas": 54000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000001", + "Name": "bls_g2multiexp_(1*g2=g2)", + "Expected": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", + "Gas": 54000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000001", + "Name": "bls_g2multiexp_(1*p2=p2)", + "Expected": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451", + "Gas": 54000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g2multiexp_(0*g2=inf)", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 54000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g2multiexp_(0*p2=inf)", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 54000, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011", + "Name": "bls_g2multiexp_(x*inf=inf)", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 54000, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g2multiexp_(2g2+inf)", + "Expected": "000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3", + "Gas": 79920, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g2multiexp_(2p2+inf)", + "Expected": "000000000000000000000000000000000b76fcbb604082a4f2d19858a7befd6053fa181c5119a612dfec83832537f644e02454f2b70d40985ebb08042d1620d40000000000000000000000000000000019a4a02c0ae51365d964c73be7babb719db1c69e0ddbf9a8a335b5bed3b0a4b070d2d5df01d2da4a3f1e56aae2ec106d000000000000000000000000000000000d18322f821ac72d3ca92f92b000483cf5b7d9e5d06873a44071c4e7e81efd904f210208fe0b9b4824f01c65bc7e62080000000000000000000000000000000004e563d53609a2d1e216aaaee5fbc14ef460160db8d1fdc5e1bd4e8b54cd2f39abf6f925969fa405efb9e700b01c7085", + "Gas": 79920, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000000", + "Name": "bls_g1multiexp_(inf+inf)", + "Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gas": 79920, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002", + "Name": "bls_g2multiexp_(2g2+2p2)", + "Expected": "00000000000000000000000000000000009cc9ed6635623ba19b340cbc1b0eb05c3a58770623986bb7e041645175b0a38d663d929afb9a949f7524656043bccc000000000000000000000000000000000c0fb19d3f083fd5641d22a861a11979da258003f888c59c33005cb4a2df4df9e5a2868832063ac289dfa3e997f21f8a00000000000000000000000000000000168bf7d87cef37cf1707849e0a6708cb856846f5392d205ae7418dd94d94ef6c8aa5b424af2e99d957567654b9dae1d90000000000000000000000000000000017e0fa3c3b2665d52c26c7d4cea9f35443f4f9007840384163d3aa3c7d4d18b21b65ff4380cf3f3b48e94b5eecb221dd", + "Gas": 79920, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e300000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d87845147b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff66513800000000000000000000000000000000108ed59fd9fae381abfd1d6bce2fd2fa220990f0f837fa30e0f27914ed6e1454db0d1ee957b219f61da6ff8be0d6441f000000000000000000000000000000000296238ea82c6d4adb3c838ee3cb2346049c90b96d602d7bb1b469b905c9228be25c627bffee872def773d5b2a2eb57d00000000000000000000000000000000033f90f6057aadacae7963b0a0b379dd46750c1c94a6357c99b65f63b79e321ff50fe3053330911c56b6ceea08fee65600000000000000000000000000000000153606c417e59fb331b7ae6bce4fbf7c5190c33ce9402b5ebe2b70e44fca614f3f1382a3625ed5493843d0b0a652fc3f328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d21600000000000000000000000000000000038af300ef34c7759a6caaa4e69363cafeed218a1f207e93b2c70d91a1263d375d6730bd6b6509dcac3ba5b567e85bf3000000000000000000000000000000000da75be60fb6aa0e9e3143e40c42796edf15685cafe0279afd2a67c3dff1c82341f17effd402e4f1af240ea90f4b659b0000000000000000000000000000000019b148cbdf163cf0894f29660d2e7bfb2b68e37d54cc83fd4e6e62c020eaa48709302ef8e746736c0e19342cc1ce3df4000000000000000000000000000000000492f4fed741b073e5a82580f7c663f9b79e036b70ab3e51162359cec4e77c78086fe879b65ca7a47d34374c8315ac5e263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e2000000000000000000000000000000000c5ae723be00e6c3f0efe184fdc0702b64588fe77dda152ab13099a3bacd3876767fa7bbad6d6fd90b3642e902b208f90000000000000000000000000000000012c8c05c1d5fc7bfa847f4d7d81e294e66b9a78bc9953990c358945e1f042eedafce608b67fdd3ab0cb2e6e263b9b1ad0000000000000000000000000000000004e77ddb3ede41b5ec4396b7421dd916efc68a358a0d7425bddd253547f2fb4830522358491827265dfc5bcc1928a5690000000000000000000000000000000011c624c56dbe154d759d021eec60fab3d8b852395a89de497e48504366feedd4662d023af447d66926a28076813dd64647b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff665131000000000000000000000000000000000ea4e7c33d43e17cc516a72f76437c4bf81d8f4eac69ac355d3bf9b71b8138d55dc10fd458be115afa798b55dac34be1000000000000000000000000000000001565c2f625032d232f13121d3cfb476f45275c303a037faa255f9da62000c2c864ea881e2bcddd111edc4a3c0da3e88d00000000000000000000000000000000043b6f5fe4e52c839148dc66f2b3751e69a0f6ebb3d056d6465d50d4108543ecd956e10fa1640dfd9bc0030cc2558d28000000000000000000000000000000000f8991d2a1ad662e7b6f58ab787947f1fa607fce12dde171bc17903b012091b657e15333e11701edcf5b63ba2a561247328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d211", + "Name": "bls_g2multiexp_multiple", + "Expected": "0000000000000000000000000000000016cf5fd2c2f1b2e01cc48a6d03e8e6d7f3ad754d6c7d4000f806c18c28d8d559cf529dd159c74946a7713d1906894718000000000000000000000000000000000628d42142df8d620d1f3709ac01f382ba950eaf14c12863885af5838067deec4bb363ffda427fcbdd2b8ec6cc5784ae0000000000000000000000000000000018168dec2441ef462e9a769c782f81acdc7fa49dffebb996764ba9fa96b9200ceb5edd9e96b33c383bd042b4e6af191a000000000000000000000000000000001065aaea2c4aa1d2bee7f1e82a2138ae7016dbbade8383ad912d81eca5fb260086238f95f8cef8f2f491969d4cefa2c3", + "Gas": 147690, + "NoBenchmark": false + } +] diff --git a/crates/precompile/test-vectors/pairing_check_bls.json b/crates/precompile/test-vectors/pairing_check_bls.json new file mode 100644 index 00000000..a74d8489 --- /dev/null +++ b/crates/precompile/test-vectors/pairing_check_bls.json @@ -0,0 +1,44 @@ +[ + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", + "Name": "bls_pairing_e(G1,0)=e(0,G2)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 151000, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", + "Name": "bls_pairing_non-degeneracy", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000", + "Gas": 108000, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a2100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be000000000000000000000000000000000a40300ce2dec9888b60690e9a41d3004fda4886854573974fab73b046d3147ba5b7a5bde85279ffede1b45b3918d82d0000000000000000000000000000000006d3d887e9f53b9ec4eb6cedf5607226754b07c01ace7834f57f3e7315faefb739e59018e22c492006190fba4a87002500000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", + "Name": "bls_pairing_bilinearity", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 194000, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", + "Name": "bls_pairing_e(G1,-G2)=e(-G1,G2)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 151000, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a0000000000000000000000000000000017cd7061575d3e8034fcea62adaa1a3bc38dca4b50e4c5c01d04dd78037c9cee914e17944ea99e7ad84278e5d49f36c4000000000000000000000000000000000bc2357c6782bbb6a078d9e171fc7a81f7bd8ca73eb485e76317359908bb09bd372fd362a637512a9d48019b383e54890000000000000000000000000000000004b8f49c3bac0247a09487049492b0ed99cf90c56263141daa35f011330d3ced3f3ad78d252c51a3bb42fc7d8f182594000000000000000000000000000000000982d17b17404ac198a0ff5f2dffa56a328d95ec4732d9cca9da420ec7cf716dc63d56d0f5179a8b1ec71fe0328fe88200000000000000000000000000000000147c92cb19e43943bb20c5360a6c4347411eb8ffb3d6f19cc428a8dc0cb3fd1eb3ad02b1c21e21c78f65a7691ee63de90000000000000000000000000000000016cae74dc6523e5273dbd2d9d25c53f1e2c453e6d9ba3f605021cfb514fa0bdf721b05f2200f32591d733e739fabf438000000000000000000000000000000001405df65fb71b738510b3a2fc31c33ef3d884ccc84efb1017341a368bf40727b7ad8cdc8e3fd6b0eb94102488c5cb77000000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", + "Name": "bls_pairing_e(aG1,bG2)=e(abG1,G2)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 151000, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a0000000000000000000000000000000017cd7061575d3e8034fcea62adaa1a3bc38dca4b50e4c5c01d04dd78037c9cee914e17944ea99e7ad84278e5d49f36c4000000000000000000000000000000000bc2357c6782bbb6a078d9e171fc7a81f7bd8ca73eb485e76317359908bb09bd372fd362a637512a9d48019b383e54890000000000000000000000000000000004b8f49c3bac0247a09487049492b0ed99cf90c56263141daa35f011330d3ced3f3ad78d252c51a3bb42fc7d8f182594000000000000000000000000000000000982d17b17404ac198a0ff5f2dffa56a328d95ec4732d9cca9da420ec7cf716dc63d56d0f5179a8b1ec71fe0328fe88200000000000000000000000000000000147c92cb19e43943bb20c5360a6c4347411eb8ffb3d6f19cc428a8dc0cb3fd1eb3ad02b1c21e21c78f65a7691ee63de90000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb00000000000000000000000000000000114d1d6855d545a8aa7d76c8cf2e21f267816aef1db507c96655b9d5caac42364e6f38ba0ecb751bad54dcd6b939c2ca00000000000000000000000000000000166335679f3b3e2617b70c22c48e820e2c6a35149c4f96293035c1494a1ce4591f7a44bce94e9d76def50a71c9e7fa41000000000000000000000000000000000ef11c636091748476331159c8259c064da712ffec033c89299384b4c11b801893026726d992aacdc8e0a28db1a3ab82000000000000000000000000000000000fd8d4944030f480f44ce0d2d4fb67ff6264d30a0f3193cc218b062e5114cf9e4ce847489f7be94b0d4a9fc0c550fdc60000000000000000000000000000000000edba2c166be3d673ea77016163ae5cdf7b3c9bd480e733eb5c08a5f1c798793d339cb503005f5a9e586ea5aabf9695", + "Name": "bls_pairing_e(aG1,bG2)=e(G1,abG2)", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 151000, + "NoBenchmark": false + } +] From 30c6362bd4676911fa8f3306b4d8311cee340931 Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Fri, 17 May 2024 16:51:40 +0300 Subject: [PATCH 090/105] fix(precompile): ignore infinity points in G1 MSM (#1432) --- crates/precompile/src/bls12_381/g1_msm.rs | 20 ++++++++++++++++---- crates/precompile/src/bls12_381/g2_msm.rs | 6 +++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/crates/precompile/src/bls12_381/g1_msm.rs b/crates/precompile/src/bls12_381/g1_msm.rs index 503a7b74..c8d086ab 100644 --- a/crates/precompile/src/bls12_381/g1_msm.rs +++ b/crates/precompile/src/bls12_381/g1_msm.rs @@ -41,13 +41,20 @@ pub(super) fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { let mut g1_points: Vec = Vec::with_capacity(k); let mut scalars: Vec = Vec::with_capacity(k * SCALAR_LENGTH); for i in 0..k { + let slice = + &input[i * g1_mul::INPUT_LENGTH..i * g1_mul::INPUT_LENGTH + G1_INPUT_ITEM_LENGTH]; + + // BLST batch API for p1_affines blows up when you pass it a point at infinity and returns + // point at infinity so we just skip the element, and return 128 bytes in the response + if slice.iter().all(|i| *i == 0) { + continue; + } + // NB: Scalar multiplications, MSMs and pairings MUST perform a subgroup check. // // So we set the subgroup_check flag to `true` - let p0_aff = &extract_g1_input( - &input[i * g1_mul::INPUT_LENGTH..i * g1_mul::INPUT_LENGTH + G1_INPUT_ITEM_LENGTH], - true, - )?; + let p0_aff = &extract_g1_input(slice, true)?; + let mut p0 = blst_p1::default(); // SAFETY: p0 and p0_aff are blst values. unsafe { blst_p1_from_affine(&mut p0, p0_aff) }; @@ -62,6 +69,11 @@ pub(super) fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { ); } + // return infinity point if all points are infinity + if g1_points.is_empty() { + return Ok((required_gas, [0; 128].into())); + } + let points = p1_affines::from(&g1_points); let multiexp = points.mult(&scalars, NBITS); diff --git a/crates/precompile/src/bls12_381/g2_msm.rs b/crates/precompile/src/bls12_381/g2_msm.rs index 0becd2b5..85f8208f 100644 --- a/crates/precompile/src/bls12_381/g2_msm.rs +++ b/crates/precompile/src/bls12_381/g2_msm.rs @@ -43,8 +43,8 @@ pub(super) fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { for i in 0..k { let slice = &input[i * g2_mul::INPUT_LENGTH..i * g2_mul::INPUT_LENGTH + G2_INPUT_ITEM_LENGTH]; - // BLST batch API for p2_affines blows up when you pass it a point at infinity and returns point at infinity - // so we just skip the element, and return 256 bytes in the response + // BLST batch API for p2_affines blows up when you pass it a point at infinity and returns + // point at infinity so we just skip the element, and return 256 bytes in the response if slice.iter().all(|i| *i == 0) { continue; } @@ -71,7 +71,7 @@ pub(super) fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { // return infinity point if all points are infinity if g2_points.is_empty() { - return Ok((required_gas, vec![0; 256].into())); + return Ok((required_gas, [0; 256].into())); } let points = p2_affines::from(&g2_points); From ff2dcf56c6c293cbeef5d822b0d27eff4450340e Mon Sep 17 00:00:00 2001 From: jpgonzalezra Date: Fri, 24 May 2024 05:31:54 -0300 Subject: [PATCH 091/105] chore(interpreter): optimisation for BYTE, SHL, SHR and SAR (#1418) * chore(interpreter): optimisation for BYTE, SHL, SHR and SAR * added previus comment in byte function * updated pr comments --- .../interpreter/src/instructions/bitwise.rs | 89 ++++++++++++++----- 1 file changed, 66 insertions(+), 23 deletions(-) diff --git a/crates/interpreter/src/instructions/bitwise.rs b/crates/interpreter/src/instructions/bitwise.rs index 586af76c..62edf11c 100644 --- a/crates/interpreter/src/instructions/bitwise.rs +++ b/crates/interpreter/src/instructions/bitwise.rs @@ -1,11 +1,10 @@ -use super::i256::{i256_cmp, i256_sign_compl, two_compl, Sign}; +use super::i256::i256_cmp; use crate::{ gas, primitives::{Spec, U256}, Host, Interpreter, }; use core::cmp::Ordering; -use revm_primitives::uint; pub fn lt(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); @@ -85,7 +84,12 @@ pub fn shl(interpreter: &mut Interpreter, _host: & check!(interpreter, CONSTANTINOPLE); gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); - *op2 <<= as_usize_saturated!(op1); + let shift = as_usize_saturated!(op1); + *op2 = if shift < 256 { + *op2 << shift + } else { + U256::ZERO + } } /// EIP-145: Bitwise shifting instructions in EVM @@ -93,7 +97,12 @@ pub fn shr(interpreter: &mut Interpreter, _host: & check!(interpreter, CONSTANTINOPLE); gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); - *op2 >>= as_usize_saturated!(op1); + let shift = as_usize_saturated!(op1); + *op2 = if shift < 256 { + *op2 >> shift + } else { + U256::ZERO + } } /// EIP-145: Bitwise shifting instructions in EVM @@ -102,33 +111,32 @@ pub fn sar(interpreter: &mut Interpreter, _host: & gas!(interpreter, gas::VERYLOW); pop_top!(interpreter, op1, op2); - let value_sign = i256_sign_compl(op2); - - // If the shift count is 255+, we can short-circuit. This is because shifting by 255 bits is the - // maximum shift that still leaves 1 bit in the original 256-bit number. Shifting by 256 bits or - // more would mean that no original bits remain. The result depends on what the highest bit of - // the value is. - *op2 = if value_sign == Sign::Zero || op1 >= U256::from(255) { - match value_sign { - // value is 0 or >=1, pushing 0 - Sign::Plus | Sign::Zero => U256::ZERO, - // value is <0, pushing -1 - Sign::Minus => U256::MAX, + let shift = as_usize_saturated!(op1); + *op2 = if shift >= 256 { + // If the shift is 256 or more, the result depends on the sign of the last bit. + if op2.bit(255) { + U256::MAX // Negative number, all bits set to one. + } else { + U256::ZERO // Non-negative number, all bits set to zero. } } else { - const ONE: U256 = uint!(1_U256); - // SAFETY: shift count is checked above; it's less than 255. - let shift = usize::try_from(op1).unwrap(); - match value_sign { - Sign::Plus | Sign::Zero => op2.wrapping_shr(shift), - Sign::Minus => two_compl(op2.wrapping_sub(ONE).wrapping_shr(shift).wrapping_add(ONE)), + // Normal shift + if op2.bit(255) { + // Check the most significant bit. + // Arithmetic right shift for negative numbers. + let shifted_value = *op2 >> shift; + let mask = U256::MAX << (256 - shift); // Mask for the sign bits. + shifted_value | mask // Apply the mask to simulate the filling of sign bits. + } else { + // Logical right shift for non-negative numbers. + *op2 >> shift } }; } #[cfg(test)] mod tests { - use crate::instructions::bitwise::{sar, shl, shr}; + use crate::instructions::bitwise::{byte, sar, shl, shr}; use crate::{Contract, DummyHost, Interpreter}; use revm_primitives::{uint, Env, LatestSpec, U256}; @@ -399,4 +407,39 @@ mod tests { assert_eq!(res, test.expected); } } + + #[test] + fn test_byte() { + struct TestCase { + input: U256, + index: usize, + expected: U256, + } + + let mut host = DummyHost::new(Env::default()); + let mut interpreter = Interpreter::new(Contract::default(), u64::MAX, false); + + let input_value = U256::from(0x1234567890abcdef1234567890abcdef_u128); + let test_cases = (0..32) + .map(|i| { + let byte_pos = 31 - i; + + let shift_amount = U256::from(byte_pos * 8); + let byte_value = (input_value >> shift_amount) & U256::from(0xFF); + TestCase { + input: input_value, + index: i, + expected: byte_value, + } + }) + .collect::>(); + + for test in test_cases.iter() { + push!(interpreter, test.input); + push!(interpreter, U256::from(test.index)); + byte(&mut interpreter, &mut host); + pop!(interpreter, res); + assert_eq!(res, test.expected, "Failed at index: {}", test.index); + } + } } From 45e3571beae5baf7324b0e9d4af7e95253384708 Mon Sep 17 00:00:00 2001 From: Pana Date: Fri, 24 May 2024 16:33:25 +0800 Subject: [PATCH 092/105] update doc about interpreter action (#1419) --- documentation/src/SUMMARY.md | 2 +- documentation/src/crates/interpreter.md | 2 +- .../src/crates/interpreter/inner_models.md | 29 -------------- .../crates/interpreter/interpreter_action.md | 39 +++++++++++++++++++ 4 files changed, 41 insertions(+), 31 deletions(-) delete mode 100644 documentation/src/crates/interpreter/inner_models.md create mode 100644 documentation/src/crates/interpreter/interpreter_action.md diff --git a/documentation/src/SUMMARY.md b/documentation/src/SUMMARY.md index d40b1b2b..1d2900f3 100644 --- a/documentation/src/SUMMARY.md +++ b/documentation/src/SUMMARY.md @@ -12,7 +12,7 @@ - [gas](./crates/interpreter/gas.md) - [memory](./crates/interpreter/memory.md) - [host](./crates/interpreter/host.md) - - [inner_models](./crates/interpreter/inner_models.md) + - [interpreter_action](./crates/interpreter/interpreter_action.md) - [instruction_result](./crates/interpreter/instruction_result.md) - [instructions](./crates/interpreter/instructions.md) - [Primitives](./crates/primitives.md) diff --git a/documentation/src/crates/interpreter.md b/documentation/src/crates/interpreter.md index 629be56a..0ad39b0b 100644 --- a/documentation/src/crates/interpreter.md +++ b/documentation/src/crates/interpreter.md @@ -8,7 +8,7 @@ It is structured as follows: - [gas](./interpreter/gas.md): Handles gas mechanics in the EVM, such as calculating gas costs for operations. - [host](./interpreter/host.md): Defines the EVM context `Host` trait. -- [inner_models](./interpreter/inner_models.md): Contains inner data structures used in the EVM implementation. +- [interpreter_action](./interpreter/interpreter_action.md): Contains data structures used in the EVM implementation. - [instruction_result](./interpreter/instruction_result.md): Defines results of instruction execution. - [instructions](./interpreter/instructions.md): Defines the EVM opcodes (i.e. instructions). diff --git a/documentation/src/crates/interpreter/inner_models.md b/documentation/src/crates/interpreter/inner_models.md deleted file mode 100644 index 7524d942..00000000 --- a/documentation/src/crates/interpreter/inner_models.md +++ /dev/null @@ -1,29 +0,0 @@ -# The `inner_models.rs` Module in the Rust Ethereum Virtual Machine (EVM) - -The `inner_models.rs` module within this Rust EVM implementation encompasses a collection of datastructures used as internal models within the EVM. These models represent various aspects of EVM operations such as call and create inputs, call context, value transfers, and the result of self-destruction operations. - -## Data Structures - -- `CallInputs` Struct - - The `CallInputs` struct is used to encapsulate the inputs to a smart contract call in the EVM. This struct includes the target contract address, the value to be transferred (if any), the input data, the gas limit for the call, the call context, and a boolean indicating if the call is a static call (a read-only operation). - -- `CreateInputs` Struct - - The `CreateInputs` struct encapsulates the inputs for creating a new smart contract. This includes the address of the creator, the creation scheme, the value to be transferred, the initialization code for the new contract, and the gas limit for the creation operation. - -- `CallScheme` Enum - - The `CallScheme` enum represents the type of call being made to a smart contract. The different types of calls (`CALL`, `CALLCODE`, `DELEGATECALL`, `STATICCALL`) represent different modes of interaction with a smart contract, each with its own semantics concerning the treatment of the message sender, value transfer, and the context in which the called code executes. - -- `CallContext` Struct - - The `CallContext` struct encapsulates the context of a smart contract call. This includes the executing contract's address, the caller's address, the address from which the contract code was loaded, the apparent value of the call (for `DELEGATECALL` and `CALLCODE`), and the call scheme. - -- `Transfer` Struct - -The `Transfer` struct represents a value transfer between two accounts. - -- `SelfDestructResult` Struct - -Finally, the `SelfDestructResult` struct captures the result of a self-destruction operation on a contract. In summary, the `inner_models.rs` module provides several crucial data structures that facilitate the representation and handling of various EVM operations and their associated data within this Rust EVM implementation. diff --git a/documentation/src/crates/interpreter/interpreter_action.md b/documentation/src/crates/interpreter/interpreter_action.md new file mode 100644 index 00000000..9654b43e --- /dev/null +++ b/documentation/src/crates/interpreter/interpreter_action.md @@ -0,0 +1,39 @@ +# The `interpreter_action.rs` Module in the Rust Ethereum Virtual Machine (EVM) + +The `interpreter_action.rs` module within this Rust EVM implementation encompasses a collection of datastructures used as internal models within the EVM. These models represent various aspects of EVM operations such as call and create inputs, call context, value transfers, and the result of self-destruction operations. + +## Data Structures + +- `CallInputs` Struct + + The `CallInputs` struct is used to encapsulate the inputs to a smart contract call in the EVM. This struct includes the target contract address, the value to be transferred (if any), the input data, the gas limit for the call, the call context, and a boolean indicating if the call is a static call (a read-only operation). + +- `CallScheme` Enum + + The `CallScheme` enum represents the type of call being made to a smart contract. The different types of calls (`CALL`, `CALLCODE`, `DELEGATECALL`, `STATICCALL`) represent different modes of interaction with a smart contract, each with its own semantics concerning the treatment of the message sender, value transfer, and the context in which the called code executes. + +- `CallValue` Enum + + The `CallValue` Enum represents a value transfer between two accounts. + +- `CallOutcome` + + Represents the outcome of a call operation in a virtual machine. This struct encapsulates the result of executing an instruction by an interpreter, including the result itself, gas usage information, and the memory offset where output data is stored. + +- `CreateInputs` Struct + + The `CreateInputs` struct encapsulates the inputs for creating a new smart contract. This includes the address of the creator, the creation scheme, the value to be transferred, the initialization code for the new contract, and the gas limit for the creation operation. + +- `CreateOutcome` Struct + + Represents the outcome of a create operation in an interpreter. This struct holds the result of the operation along with an optional address. It provides methods to determine the next action based on the result of the operation. + +- `EOFCreateInput` Struct + + Inputs for EOF create call. + +- `EOFCreateOutcome` Struct + + Represents the outcome of a create operation in an interpreter. + +In summary, the `interpreter_action.rs` module provides several crucial data structures that facilitate the representation and handling of various EVM operations and their associated data within this Rust EVM implementation. From c75597723ceeb38ccf4d67bf0e7cc828ad435721 Mon Sep 17 00:00:00 2001 From: yjh Date: Fri, 24 May 2024 17:40:31 +0800 Subject: [PATCH 093/105] feat: load account should return db error (#1447) * feat: load account should return db error * simplify --- crates/revm/src/optimism/handler_register.rs | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/crates/revm/src/optimism/handler_register.rs b/crates/revm/src/optimism/handler_register.rs index 0d3bcf40..f517f941 100644 --- a/crates/revm/src/optimism/handler_register.rs +++ b/crates/revm/src/optimism/handler_register.rs @@ -240,30 +240,20 @@ pub fn reward_beneficiary( let l1_cost = l1_block_info.calculate_tx_l1_cost(enveloped_tx, SPEC::SPEC_ID); // Send the L1 cost of the transaction to the L1 Fee Vault. - let Ok((l1_fee_vault_account, _)) = context + let (l1_fee_vault_account, _) = context .evm .inner .journaled_state - .load_account(optimism::L1_FEE_RECIPIENT, &mut context.evm.inner.db) - else { - return Err(EVMError::Custom( - "[OPTIMISM] Failed to load L1 Fee Vault account.".to_string(), - )); - }; + .load_account(optimism::L1_FEE_RECIPIENT, &mut context.evm.inner.db)?; l1_fee_vault_account.mark_touch(); l1_fee_vault_account.info.balance += l1_cost; // Send the base fee of the transaction to the Base Fee Vault. - let Ok((base_fee_vault_account, _)) = context + let (base_fee_vault_account, _) = context .evm .inner .journaled_state - .load_account(optimism::BASE_FEE_RECIPIENT, &mut context.evm.inner.db) - else { - return Err(EVMError::Custom( - "[OPTIMISM] Failed to load Base Fee Vault account.".to_string(), - )); - }; + .load_account(optimism::BASE_FEE_RECIPIENT, &mut context.evm.inner.db)?; base_fee_vault_account.mark_touch(); base_fee_vault_account.info.balance += context .evm From 44bafedd346af3f02ba342906989d3fceab19eae Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Fri, 24 May 2024 08:20:01 -0400 Subject: [PATCH 094/105] chore: add docs for BLS scalar input decoding (#1446) --- crates/precompile/src/bls12_381/utils.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/crates/precompile/src/bls12_381/utils.rs b/crates/precompile/src/bls12_381/utils.rs index 3617a752..de370a07 100644 --- a/crates/precompile/src/bls12_381/utils.rs +++ b/crates/precompile/src/bls12_381/utils.rs @@ -42,7 +42,16 @@ pub(super) fn remove_padding(input: &[u8]) -> Result<&[u8; FP_LENGTH], Precompil Ok(unpadded.try_into().unwrap()) } -/// Extracts an Scalar from a 32 byte slice representation. +/// Extracts a scalar from a 32 byte slice representation, decoding the input as a big endian +/// unsigned integer. If the input is not exactly 32 bytes long, an error is returned. +/// +/// From [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537): +/// * A scalar for the multiplication operation is encoded as 32 bytes by performing BigEndian +/// encoding of the corresponding (unsigned) integer. +/// +/// We do not check that the scalar is a canonical Fr element, because the EIP specifies: +/// * The corresponding integer is not required to be less than or equal than main subgroup order +/// `q`. pub(super) fn extract_scalar_input(input: &[u8]) -> Result { if input.len() != SCALAR_LENGTH { return Err(PrecompileError::Other(format!( @@ -53,7 +62,13 @@ pub(super) fn extract_scalar_input(input: &[u8]) -> Result Date: Fri, 24 May 2024 15:02:23 +0200 Subject: [PATCH 095/105] chore: cargo update (#1451) --- Cargo.lock | 537 ++++++++++++++++++++---------------------- crates/revm/src/db.rs | 8 +- 2 files changed, 264 insertions(+), 281 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e6914d00..fa834e7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,9 +40,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "alloy-consensus" @@ -113,9 +113,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525448f6afc1b70dd0f9d0a8145631bf2f5e434678ab23ab18409ca264cae6b3" +checksum = "db8aa973e647ec336810a9356af8aea787249c9d00b1525359f3db29a68d231b" dependencies = [ "alloy-rlp", "arbitrary", @@ -168,9 +168,9 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d58d9f5da7b40e9bfff0b7e7816700be4019db97d4b6359fe7f94a9e22e42ac" +checksum = "b155716bab55763c95ba212806cf43d05bcc70e5f35b02bad20cf5ec7fe11fed" dependencies = [ "alloy-rlp-derive", "arrayvec", @@ -179,13 +179,13 @@ dependencies = [ [[package]] name = "alloy-rlp-derive" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a047897373be4bbb0224c1afdabca92648dc57a9c9ef6e7b0be3aff7a859c83" +checksum = "8037e03c7f462a063f28daec9fda285a9a89da003c552f8637a80b9c8fd96241" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] @@ -263,9 +263,23 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.7.2" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dbd17d67f3e89478c8a634416358e539e577899666c927bc3d2b1328ee9b6ca" +dependencies = [ + "alloy-sol-macro-expander", + "alloy-sol-macro-input", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "alloy-sol-macro-expander" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89c80a2cb97e7aa48611cbb63950336f9824a174cdf670527cc6465078a26ea1" +checksum = "2c6da95adcf4760bb4b108fefa51d50096c5e5fdd29ee72fed3e86ee414f2e34" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -274,31 +288,31 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", "syn-solidity", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58894b58ac50979eeac6249661991ac40b9d541830d9a725f7714cc9ef08c23" +checksum = "32c8da04c1343871fb6ce5a489218f9c85323c8340a36e9106b5fc98d4dd59d5" dependencies = [ "const-hex", "dunce", "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", "syn-solidity", ] [[package]] name = "alloy-sol-types" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "399287f68d1081ed8b1f4903c49687658b95b142207d7cb4ae2f4813915343ef" +checksum = "40a64d2d2395c1ac636b62419a7b17ec39031d6b2367e66e9acbf566e6055e9c" dependencies = [ "alloy-primitives", "alloy-sol-macro", @@ -312,7 +326,7 @@ version = "0.1.0" source = "git+https://github.com/alloy-rs/alloy.git?rev=44b8a6d#44b8a6da656602fd9fd2c52f28ecffa4acaed96c" dependencies = [ "alloy-json-rpc", - "base64 0.22.0", + "base64 0.22.1", "futures-util", "futures-utils-wasm", "serde", @@ -354,15 +368,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anyhow" -version = "1.0.83" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "arbitrary" @@ -519,18 +533,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] name = "async-trait" -version = "0.1.79" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] @@ -544,6 +558,12 @@ dependencies = [ "rustc_version 0.4.0", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "atty" version = "0.2.14" @@ -573,14 +593,14 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" @@ -617,9 +637,9 @@ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" @@ -703,9 +723,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byte-slice-cast" @@ -750,9 +770,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.90" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" [[package]] name = "cfg-if" @@ -762,9 +782,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.35" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "num-traits", ] @@ -813,9 +833,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.3" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", ] @@ -851,9 +871,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.11.3" +version = "1.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ba00838774b4ab0233e355d26710fbfc8327a05c017f6dc4873f876d1f79f78" +checksum = "70ff96486ccc291d36a958107caf2c0af8c78c0af7d31ae2f35ce055130de1a6" dependencies = [ "cfg-if", "cpufeatures", @@ -908,7 +928,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.5.3", + "clap 4.5.4", "criterion-plot", "is-terminal", "itertools 0.10.5", @@ -956,9 +976,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -1003,15 +1023,15 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "zeroize", @@ -1045,7 +1065,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] @@ -1110,9 +1130,9 @@ dependencies = [ [[package]] name = "either" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "elliptic-curve" @@ -1141,9 +1161,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -1174,7 +1194,7 @@ checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] @@ -1185,9 +1205,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1345,9 +1365,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fastrlp" @@ -1475,7 +1495,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] @@ -1546,9 +1566,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -1592,9 +1612,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", @@ -1611,15 +1631,15 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" dependencies = [ + "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "futures-util", "http 1.1.0", "indexmap", "slab", @@ -1630,9 +1650,9 @@ dependencies = [ [[package]] name = "half" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5eceaaeec696539ddaf7b333340f1af35a5aa87ae3e4f3ead0532f72affab2e" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" dependencies = [ "cfg-if", "crunchy", @@ -1802,7 +1822,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.25", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "httparse", @@ -1818,14 +1838,14 @@ dependencies = [ [[package]] name = "hyper" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.4", + "h2 0.4.5", "http 1.1.0", "http-body 1.0.0", "httparse", @@ -1858,7 +1878,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.2.0", + "hyper 1.3.1", "hyper-util", "native-tls", "tokio", @@ -1877,7 +1897,7 @@ dependencies = [ "futures-util", "http 1.1.0", "http-body 1.0.0", - "hyper 1.2.0", + "hyper 1.3.1", "pin-project-lite", "socket2", "tokio", @@ -1965,9 +1985,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -2009,9 +2029,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" @@ -2061,9 +2081,9 @@ dependencies = [ [[package]] name = "keccak-asm" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb8515fff80ed850aea4a1595f2e519c003e2a00a82fe168ebf5269196caf444" +checksum = "47a3633291834c4fbebf8673acbc1b04ec9d151418ff9b8e26dcd79129928758" dependencies = [ "digest 0.10.7", "sha3-asm", @@ -2080,9 +2100,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libm" @@ -2092,15 +2112,15 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -2123,9 +2143,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "microbench" @@ -2141,9 +2161,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" dependencies = [ "adler", ] @@ -2179,9 +2199,9 @@ dependencies = [ [[package]] name = "num" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ "num-bigint", "num-complex", @@ -2193,20 +2213,19 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" dependencies = [ - "autocfg", "num-integer", "num-traits", ] [[package]] name = "num-complex" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] @@ -2228,9 +2247,9 @@ dependencies = [ [[package]] name = "num-iter" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -2239,11 +2258,10 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", "num-bigint", "num-integer", "num-traits", @@ -2251,9 +2269,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -2284,10 +2302,10 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] @@ -2365,7 +2383,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] @@ -2388,9 +2406,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec", "bitvec", @@ -2402,11 +2420,11 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 2.0.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -2414,15 +2432,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] @@ -2448,9 +2466,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.8" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" dependencies = [ "memchr", "thiserror", @@ -2497,7 +2515,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] @@ -2526,14 +2544,14 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -2568,9 +2586,9 @@ dependencies = [ [[package]] name = "plotters" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" dependencies = [ "num-traits", "plotters-backend", @@ -2581,15 +2599,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" +checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" [[package]] name = "plotters-svg" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" dependencies = [ "plotters-backend", ] @@ -2626,32 +2644,13 @@ dependencies = [ "uint", ] -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - -[[package]] -name = "proc-macro-crate" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" -dependencies = [ - "toml_edit 0.20.7", -] - [[package]] name = "proc-macro-crate" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_edit 0.21.1", + "toml_edit", ] [[package]] @@ -2680,9 +2679,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" dependencies = [ "unicode-ident", ] @@ -2726,9 +2725,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -2800,11 +2799,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", ] [[package]] @@ -2832,9 +2831,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "relative-path" @@ -2853,7 +2852,7 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2 0.3.25", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", @@ -2889,16 +2888,16 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" dependencies = [ - "base64 0.22.0", + "base64 0.22.1", "bytes", "encoding_rs", "futures-core", "futures-util", - "h2 0.4.4", + "h2 0.4.5", "http 1.1.0", "http-body 1.0.0", "http-body-util", - "hyper 1.2.0", + "hyper 1.3.1", "hyper-tls", "hyper-util", "ipnet", @@ -3135,7 +3134,7 @@ dependencies = [ "regex", "relative-path", "rustc_version 0.4.0", - "syn 2.0.55", + "syn 2.0.66", "unicode-ident", ] @@ -3172,9 +3171,9 @@ checksum = "f86854cf50259291520509879a5c294c3c9a4c334e9ff65071c51e42ef1e2343" [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hex" @@ -3197,14 +3196,14 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.22", + "semver 1.0.23", ] [[package]] name = "rustix" -version = "0.38.32" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.5.0", "errno", @@ -3215,9 +3214,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring 0.17.8", @@ -3240,15 +3239,15 @@ version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" dependencies = [ - "base64 0.22.0", + "base64 0.22.1", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.5.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beb461507cee2c2ff151784c52762cf4d9ff6a61f3e80968600ed24fa837fa54" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" @@ -3262,9 +3261,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "rusty-fork" @@ -3280,9 +3279,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -3295,9 +3294,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.11.1" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "788745a868b0e751750388f4e6546eb921ef714a4317fa6954f7cde114eb2eb7" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" dependencies = [ "cfg-if", "derive_more", @@ -3307,11 +3306,11 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.11.1" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dc2f4e8bc344b9fc3d5f74f72c2e55bfc38d28dc2ebc69c194a3df424e4d9ac" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -3377,11 +3376,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "core-foundation", "core-foundation-sys", "libc", @@ -3390,9 +3389,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" dependencies = [ "core-foundation-sys", "libc", @@ -3409,9 +3408,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "semver-parser" @@ -3436,22 +3435,22 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.201" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.201" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] @@ -3512,9 +3511,9 @@ dependencies = [ [[package]] name = "sha3-asm" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac61da6b35ad76b195eb4771210f947734321a8d81d7738e1580d953bc7a15e" +checksum = "a9b57fd861253bff08bb1919e995f90ba8f4889de2726091c8876f3a4e823b40" dependencies = [ "cc", "cfg-if", @@ -3565,9 +3564,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", @@ -3650,7 +3649,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] @@ -3685,9 +3684,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.55" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -3696,14 +3695,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa0cefd02f532035d83cfec82647c6eb53140b0485220760e669f4bad489e36" +checksum = "b8db114c44cf843a8bacd37a146e37987a0b823a0e8bc4fdc610c9c72ab397a5" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] @@ -3762,22 +3761,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.60" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.60" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] @@ -3791,9 +3790,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.34" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", @@ -3812,9 +3811,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", @@ -3879,7 +3878,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] @@ -3931,45 +3930,22 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml_datetime" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" - -[[package]] -name = "toml_edit" -version = "0.19.15" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow", -] - -[[package]] -name = "toml_edit" -version = "0.20.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow", -] +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" [[package]] name = "toml_edit" @@ -4030,7 +4006,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] @@ -4148,9 +4124,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" [[package]] name = "unicode-xid" @@ -4266,7 +4242,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", "wasm-bindgen-shared", ] @@ -4300,7 +4276,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4345,11 +4321,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -4373,7 +4349,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -4393,17 +4369,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -4414,9 +4391,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -4426,9 +4403,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -4438,9 +4415,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -4450,9 +4433,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -4462,9 +4445,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -4474,9 +4457,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -4486,9 +4469,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" @@ -4549,22 +4532,22 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] [[package]] @@ -4584,5 +4567,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.66", ] diff --git a/crates/revm/src/db.rs b/crates/revm/src/db.rs index bcb3aa46..03dd5ac0 100644 --- a/crates/revm/src/db.rs +++ b/crates/revm/src/db.rs @@ -1,7 +1,7 @@ //! [Database] implementations. -#[cfg(feature = "alloydb")] -pub mod alloydb; +//#[cfg(feature = "alloydb")] +//pub mod alloydb; pub mod emptydb; #[cfg(feature = "ethersdb")] pub mod ethersdb; @@ -9,8 +9,8 @@ pub mod in_memory_db; pub mod states; pub use crate::primitives::db::*; -#[cfg(feature = "alloydb")] -pub use alloydb::AlloyDB; +//#[cfg(feature = "alloydb")] +//pub use alloydb::AlloyDB; pub use emptydb::{EmptyDB, EmptyDBTyped}; #[cfg(feature = "ethersdb")] pub use ethersdb::EthersDB; From 0e1cd99ae974a41082c7768ede19b6c7aefc5d07 Mon Sep 17 00:00:00 2001 From: rakita Date: Fri, 24 May 2024 18:29:58 +0200 Subject: [PATCH 096/105] chore: skip tests with storage check and return status (#1452) * chore: cargo update * chore: skip tests with storage check and return error * return println and clippy * revert to previous println --- bins/revme/src/cmd/statetest/runner.rs | 12 ++++++++++++ bins/revme/src/main.rs | 8 +++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/bins/revme/src/cmd/statetest/runner.rs b/bins/revme/src/cmd/statetest/runner.rs index 16cf2379..85764f6a 100644 --- a/bins/revme/src/cmd/statetest/runner.rs +++ b/bins/revme/src/cmd/statetest/runner.rs @@ -105,6 +105,18 @@ fn skip_test(path: &Path) -> bool { | "eip1559.json" | "mergeTest.json" + // Test with some storage check. + | "RevertInCreateInInit_Paris.json" + | "RevertInCreateInInit.json" + | "dynamicAccountOverwriteEmpty.json" + | "dynamicAccountOverwriteEmpty_Paris.json" + | "RevertInCreateInInitCreate2Paris.json" + | "create2collisionStorage.json" + | "RevertInCreateInInitCreate2.json" + | "create2collisionStorageParis.json" + | "InitCollision.json" + | "InitCollisionParis.json" + // These tests are passing, but they take a lot of time to execute so we are going to skip them. | "loopExp.json" | "Call50000_sha256.json" diff --git a/bins/revme/src/main.rs b/bins/revme/src/main.rs index 5e21714f..46620574 100644 --- a/bins/revme/src/main.rs +++ b/bins/revme/src/main.rs @@ -1,9 +1,11 @@ -use revme::cmd::MainCmd; +use revme::cmd::{Error, MainCmd}; use structopt::StructOpt; -pub fn main() { +pub fn main() -> Result<(), Error> { let cmd = MainCmd::from_args(); if let Err(e) = cmd.run() { - println!("{}", e) + println!("{:?}", e); + return Err(e); } + Ok(()) } From 8b6ab3118a47df8574ed463f37d38ea5c94c6ad7 Mon Sep 17 00:00:00 2001 From: Alexey Shekhirin Date: Fri, 24 May 2024 17:30:17 +0100 Subject: [PATCH 097/105] feat(revm): revert EIP-2935 BLOCKHASH opcode changes (#1450) * feat(revm): revert EIP-2935 BLOCKHASH opcode changes * fix lint * bump time * return previous impl mod prague branch * remove unused imports --- crates/revm/src/context.rs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/crates/revm/src/context.rs b/crates/revm/src/context.rs index aa2ae4be..6cdbdfe6 100644 --- a/crates/revm/src/context.rs +++ b/crates/revm/src/context.rs @@ -13,10 +13,7 @@ use revm_interpreter::as_usize_saturated; use crate::{ db::{Database, EmptyDB}, interpreter::{Host, LoadAccountResult, SStoreResult, SelfDestructResult}, - primitives::{ - Address, Bytecode, EVMError, Env, HandlerCfg, Log, B256, BLOCKHASH_SERVE_WINDOW, - BLOCKHASH_STORAGE_ADDRESS, BLOCK_HASH_HISTORY, PRAGUE, U256, - }, + primitives::{Address, Bytecode, Env, HandlerCfg, Log, B256, BLOCK_HASH_HISTORY, U256}, }; use std::boxed::Box; @@ -130,17 +127,6 @@ impl Host for Context { .ok(); } - if self.evm.journaled_state.spec.is_enabled_in(PRAGUE) && diff <= BLOCKHASH_SERVE_WINDOW { - let index = number.wrapping_rem(U256::from(BLOCKHASH_SERVE_WINDOW)); - return self - .evm - .db - .storage(BLOCKHASH_STORAGE_ADDRESS, index) - .map_err(|e| self.evm.error = Err(EVMError::Database(e))) - .ok() - .map(|v| v.into()); - } - Some(B256::ZERO) } From 2ce53cde4a2991d1c3f0b2f5ac3299e571b60f13 Mon Sep 17 00:00:00 2001 From: Brian Bland Date: Sat, 25 May 2024 09:59:51 -0700 Subject: [PATCH 098/105] chore: Update fork_ref_transact to use alloy instead of ethers (#1454) --- examples/fork_ref_transact.rs | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/examples/fork_ref_transact.rs b/examples/fork_ref_transact.rs index 90864677..6953fda2 100644 --- a/examples/fork_ref_transact.rs +++ b/examples/fork_ref_transact.rs @@ -1,5 +1,5 @@ -use ethers_contract::BaseContract; -use ethers_core::abi::parse_abi; +use alloy_sol_types::sol; +use alloy_sol_types::SolCall; use ethers_providers::{Http, Provider}; use revm::{ db::{CacheDB, EmptyDB, EthersDB}, @@ -35,14 +35,12 @@ async fn main() -> anyhow::Result<()> { let pool_address = address!("0d4a11d5EEaaC28EC3F61d100daF4d40471f1852"); // generate abi for the calldata from the human readable interface - let abi = BaseContract::from( - parse_abi(&[ - "function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast)", - ])? - ); + sol! { + function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); + } // encode abi into Bytes - let encoded = abi.encode("getReserves", ())?; + let encoded = getReservesCall::new(()).abi_encode(); // initialize new EthersDB let mut ethersdb = EthersDB::new(Arc::clone(&client), None).unwrap(); @@ -74,7 +72,7 @@ async fn main() -> anyhow::Result<()> { // account you want to transact with tx.transact_to = TransactTo::Call(pool_address); // calldata formed via abigen - tx.data = encoded.0.into(); + tx.data = encoded.into(); // transaction value in wei tx.value = U256::from(0); }) @@ -94,13 +92,13 @@ async fn main() -> anyhow::Result<()> { result => panic!("Execution failed: {result:?}"), }; - // decode bytes to reserves + ts via ethers-rs's abi decode - let (reserve0, reserve1, ts): (u128, u128, u32) = abi.decode_output("getReserves", value)?; + // decode bytes to reserves + ts via alloy's abi decode + let return_vals = getReservesCall::abi_decode_returns(&value, true)?; // Print emulated getReserves() call output - println!("Reserve0: {:#?}", reserve0); - println!("Reserve1: {:#?}", reserve1); - println!("Timestamp: {:#?}", ts); + println!("Reserve0: {:#?}", return_vals.reserve0); + println!("Reserve1: {:#?}", return_vals.reserve1); + println!("Timestamp: {:#?}", return_vals.blockTimestampLast); Ok(()) } From 928883c26c21feaed45fefc78a4d1a810bbbd3b5 Mon Sep 17 00:00:00 2001 From: Brian Bland Date: Sun, 26 May 2024 09:02:34 -0700 Subject: [PATCH 099/105] feat(optimism): Add secp256r1 precompile for Fjord (#1436) * feat(optimism): Add secp256r1 precompile for Fjord * Fix docs * Fix nostd build * Load fjord precompiles via optimism handler register * Remove outdated fjord() precompile spec constructor * Document the secp256r1 feature * Address feedback * Handle invalid signatures * Update crates/precompile/src/secp256r1.rs * Update crates/precompile/src/secp256r1.rs * Blank return on failed signature verification * Add test case for invalid (zero) pubkey --------- Co-authored-by: rakita --- Cargo.lock | 22 ++++ crates/precompile/Cargo.toml | 8 +- crates/precompile/src/lib.rs | 4 +- crates/precompile/src/secp256r1.rs | 128 +++++++++++++++++++ crates/primitives/src/specification.rs | 43 ++++++- crates/revm/src/db/in_memory_db.rs | 2 +- crates/revm/src/optimism.rs | 4 +- crates/revm/src/optimism/handler_register.rs | 20 ++- 8 files changed, 224 insertions(+), 7 deletions(-) create mode 100644 crates/precompile/src/secp256r1.rs diff --git a/Cargo.lock b/Cargo.lock index fa834e7c..46150b3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2404,6 +2404,18 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + [[package]] name = "parity-scale-codec" version = "3.6.12" @@ -2630,6 +2642,15 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "primitive-types" version = "0.12.2" @@ -2972,6 +2993,7 @@ dependencies = [ "eyre", "k256", "once_cell", + "p256", "rand", "revm-primitives", "ripemd", diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index f761e726..08abf55b 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -44,6 +44,9 @@ secp256k1 = { version = "0.29.0", default-features = false, features = [ # BLS12-381 precompiles blst = { version = "0.3.11", optional = true } +# p256verify precompile +p256 = { version = "0.13.2", optional = true, default-features = false, features = ["ecdsa"] } + [dev-dependencies] criterion = { version = "0.5" } rand = { version = "0.8", features = ["std"] } @@ -67,7 +70,7 @@ std = [ hashbrown = ["revm-primitives/hashbrown"] asm-keccak = ["revm-primitives/asm-keccak"] -optimism = ["revm-primitives/optimism"] +optimism = ["revm-primitives/optimism", "secp256r1"] # Optimism default handler enabled Optimism handler register by default in EvmBuilder. optimism-default-handler = [ "optimism", @@ -77,6 +80,9 @@ negate-optimism-default-handler = [ "revm-primitives/negate-optimism-default-handler", ] +# Enables the p256verify precompile. +secp256r1 = ["dep:p256"] + # These libraries may not work on all no_std platforms as they depend on C. # Enables the KZG point evaluation precompile. diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index fe2486d3..ca797c81 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -18,6 +18,8 @@ pub mod identity; pub mod kzg_point_evaluation; pub mod modexp; pub mod secp256k1; +#[cfg(feature = "secp256r1")] +pub mod secp256r1; pub mod utilities; use core::hash::Hash; @@ -271,7 +273,7 @@ impl PrecompileSpecId { #[cfg(feature = "optimism")] BEDROCK | REGOLITH | CANYON => Self::BERLIN, #[cfg(feature = "optimism")] - ECOTONE => Self::CANCUN, + ECOTONE | FJORD => Self::CANCUN, } } } diff --git a/crates/precompile/src/secp256r1.rs b/crates/precompile/src/secp256r1.rs new file mode 100644 index 00000000..e2c9951a --- /dev/null +++ b/crates/precompile/src/secp256r1.rs @@ -0,0 +1,128 @@ +//! # EIP-7212 secp256r1 Precompile +//! +//! This module implements the [EIP-7212](https://eips.ethereum.org/EIPS/eip-7212) precompile for +//! secp256r1 curve support. +//! +//! The main purpose of this precompile is to verify ECDSA signatures that use the secp256r1, or +//! P256 elliptic curve. The [`P256VERIFY`] const represents the implementation of this precompile, +//! with the address that it is currently deployed at. +use crate::{u64_to_address, Precompile, PrecompileWithAddress}; +use p256::ecdsa::{signature::hazmat::PrehashVerifier, Signature, VerifyingKey}; +use revm_primitives::{Bytes, PrecompileError, PrecompileResult, B256}; + +/// Base gas fee for secp256r1 p256verify operation. +const P256VERIFY_BASE: u64 = 3450; + +/// Returns the secp256r1 precompile with its address. +pub fn precompiles() -> impl Iterator { + [P256VERIFY].into_iter() +} + +/// [EIP-7212](https://eips.ethereum.org/EIPS/eip-7212#specification) secp256r1 precompile. +pub const P256VERIFY: PrecompileWithAddress = + PrecompileWithAddress(u64_to_address(0x100), Precompile::Standard(p256_verify)); + +/// secp256r1 precompile logic. It takes the input bytes sent to the precompile +/// and the gas limit. The output represents the result of verifying the +/// secp256r1 signature of the input. +/// +/// The input is encoded as follows: +/// +/// | signed message hash | r | s | public key x | public key y | +/// | :-----------------: | :-: | :-: | :----------: | :----------: | +/// | 32 | 32 | 32 | 32 | 32 | +pub fn p256_verify(input: &Bytes, gas_limit: u64) -> PrecompileResult { + if P256VERIFY_BASE > gas_limit { + return Err(PrecompileError::OutOfGas); + } + let result = if verify_impl(input).is_some() { + B256::with_last_byte(1).into() + } else { + Bytes::new() + }; + Ok((P256VERIFY_BASE, result)) +} + +/// Returns `Some(())` if the signature included in the input byte slice is +/// valid, `None` otherwise. +pub fn verify_impl(input: &[u8]) -> Option<()> { + if input.len() != 160 { + return None; + } + + // msg signed (msg is already the hash of the original message) + let msg = &input[..32]; + // r, s: signature + let sig = &input[32..96]; + // x, y: public key + let pk = &input[96..160]; + + // prepend 0x04 to the public key: uncompressed form + let mut uncompressed_pk = [0u8; 65]; + uncompressed_pk[0] = 0x04; + uncompressed_pk[1..].copy_from_slice(pk); + + // Can fail only if the input is not exact length. + let signature = Signature::from_slice(sig).ok()?; + // Can fail if the input is not valid, so we have to propagate the error. + let public_key = VerifyingKey::from_sec1_bytes(&uncompressed_pk).ok()?; + + public_key.verify_prehash(msg, &signature).ok() +} + +#[cfg(test)] +mod test { + use super::*; + use revm_primitives::hex::FromHex; + use rstest::rstest; + + #[rstest] + // test vectors from https://github.com/daimo-eth/p256-verifier/tree/master/test-vectors + #[case::ok_1("4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4da73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d604aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff37618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e", true)] + #[case::ok_2("3fec5769b5cf4e310a7d150508e82fb8e3eda1c2c94c61492d3bd8aea99e06c9e22466e928fdccef0de49e3503d2657d00494a00e764fd437bdafa05f5922b1fbbb77c6817ccf50748419477e843d5bac67e6a70e97dde5a57e0c983b777e1ad31a80482dadf89de6302b1988c82c29544c9c07bb910596158f6062517eb089a2f54c9a0f348752950094d3228d3b940258c75fe2a413cb70baa21dc2e352fc5", true)] + #[case::ok_3("e775723953ead4a90411a02908fd1a629db584bc600664c609061f221ef6bf7c440066c8626b49daaa7bf2bcc0b74be4f7a1e3dcf0e869f1542fe821498cbf2de73ad398194129f635de4424a07ca715838aefe8fe69d1a391cfa70470795a80dd056866e6e1125aff94413921880c437c9e2570a28ced7267c8beef7e9b2d8d1547d76dfcf4bee592f5fefe10ddfb6aeb0991c5b9dbbee6ec80d11b17c0eb1a", true)] + #[case::ok_4("b5a77e7a90aa14e0bf5f337f06f597148676424fae26e175c6e5621c34351955289f319789da424845c9eac935245fcddd805950e2f02506d09be7e411199556d262144475b1fa46ad85250728c600c53dfd10f8b3f4adf140e27241aec3c2da3a81046703fccf468b48b145f939efdbb96c3786db712b3113bb2488ef286cdcef8afe82d200a5bb36b5462166e8ce77f2d831a52ef2135b2af188110beaefb1", true)] + #[case::ok_5("858b991cfd78f16537fe6d1f4afd10273384db08bdfc843562a22b0626766686f6aec8247599f40bfe01bec0e0ecf17b4319559022d4d9bf007fe929943004eb4866760dedf31b7c691f5ce665f8aae0bda895c23595c834fecc2390a5bcc203b04afcacbb4280713287a2d0c37e23f7513fab898f2c1fefa00ec09a924c335d9b629f1d4fb71901c3e59611afbfea354d101324e894c788d1c01f00b3c251b2", true)] + #[case::fail_wrong_msg_1("3cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4da73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d604aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff37618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e", false)] + #[case::fail_wrong_msg_2("afec5769b5cf4e310a7d150508e82fb8e3eda1c2c94c61492d3bd8aea99e06c9e22466e928fdccef0de49e3503d2657d00494a00e764fd437bdafa05f5922b1fbbb77c6817ccf50748419477e843d5bac67e6a70e97dde5a57e0c983b777e1ad31a80482dadf89de6302b1988c82c29544c9c07bb910596158f6062517eb089a2f54c9a0f348752950094d3228d3b940258c75fe2a413cb70baa21dc2e352fc5", false)] + #[case::fail_wrong_msg_3("f775723953ead4a90411a02908fd1a629db584bc600664c609061f221ef6bf7c440066c8626b49daaa7bf2bcc0b74be4f7a1e3dcf0e869f1542fe821498cbf2de73ad398194129f635de4424a07ca715838aefe8fe69d1a391cfa70470795a80dd056866e6e1125aff94413921880c437c9e2570a28ced7267c8beef7e9b2d8d1547d76dfcf4bee592f5fefe10ddfb6aeb0991c5b9dbbee6ec80d11b17c0eb1a", false)] + #[case::fail_wrong_msg_4("c5a77e7a90aa14e0bf5f337f06f597148676424fae26e175c6e5621c34351955289f319789da424845c9eac935245fcddd805950e2f02506d09be7e411199556d262144475b1fa46ad85250728c600c53dfd10f8b3f4adf140e27241aec3c2da3a81046703fccf468b48b145f939efdbb96c3786db712b3113bb2488ef286cdcef8afe82d200a5bb36b5462166e8ce77f2d831a52ef2135b2af188110beaefb1", false)] + #[case::fail_wrong_msg_5("958b991cfd78f16537fe6d1f4afd10273384db08bdfc843562a22b0626766686f6aec8247599f40bfe01bec0e0ecf17b4319559022d4d9bf007fe929943004eb4866760dedf31b7c691f5ce665f8aae0bda895c23595c834fecc2390a5bcc203b04afcacbb4280713287a2d0c37e23f7513fab898f2c1fefa00ec09a924c335d9b629f1d4fb71901c3e59611afbfea354d101324e894c788d1c01f00b3c251b2", false)] + #[case::fail_short_input_1("4cee90eb86eaa050036147a12d49004b6a", false)] + #[case::fail_short_input_2("4cee90eb86eaa050036147a12d49004b6a958b991cfd78f16537fe6d1f4afd10273384db08bdfc843562a22b0626766686f6aec8247599f40bfe01bec0e0ecf17b4319559022d4d9bf007fe929943004eb4866760dedf319", false)] + #[case::fail_long_input("4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4da73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d604aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff37618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e00", false)] + #[case::fail_invalid_sig("4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff37618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e", false)] + #[case::fail_invalid_pubkey("4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4da73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", false)] + fn test_sig_verify(#[case] input: &str, #[case] expect_success: bool) { + let input = Bytes::from_hex(input).unwrap(); + let target_gas = 3_500u64; + let (gas_used, res) = p256_verify(&input, target_gas).unwrap(); + assert_eq!(gas_used, 3_450u64); + let expected_result = if expect_success { + B256::with_last_byte(1).into() + } else { + Bytes::new() + }; + assert_eq!(res, expected_result); + } + + #[rstest] + fn test_not_enough_gas_errors() { + let input = Bytes::from_hex("4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4da73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d604aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff37618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e").unwrap(); + let target_gas = 2_500u64; + let result = p256_verify(&input, target_gas); + + assert!(result.is_err()); + assert_eq!(result.err(), Some(PrecompileError::OutOfGas)); + } + + #[rstest] + #[case::ok_1("b5a77e7a90aa14e0bf5f337f06f597148676424fae26e175c6e5621c34351955289f319789da424845c9eac935245fcddd805950e2f02506d09be7e411199556d262144475b1fa46ad85250728c600c53dfd10f8b3f4adf140e27241aec3c2da3a81046703fccf468b48b145f939efdbb96c3786db712b3113bb2488ef286cdcef8afe82d200a5bb36b5462166e8ce77f2d831a52ef2135b2af188110beaefb1", true)] + #[case::fail_1("b5a77e7a90aa14e0bf5f337f06f597148676424fae26e175c6e5621c34351955289f319789da424845c9eac935245fcddd805950e2f02506d09be7e411199556d262144475b1fa46ad85250728c600c53dfd10f8b3f4adf140e27241aec3c2daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaef8afe82d200a5bb36b5462166e8ce77f2d831a52ef2135b2af188110beaefb1", false)] + fn test_verify_impl(#[case] input: &str, #[case] expect_success: bool) { + let input = Bytes::from_hex(input).unwrap(); + let result = verify_impl(&input); + + assert_eq!(result.is_some(), expect_success); + } +} diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index 52abf9ec..d7c1d3e6 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -63,7 +63,8 @@ pub enum SpecId { CANYON = 19, CANCUN = 20, ECOTONE = 21, - PRAGUE = 22, + FJORD = 22, + PRAGUE = 23, #[default] LATEST = u8::MAX, } @@ -114,6 +115,8 @@ impl From<&str> for SpecId { "Canyon" => SpecId::CANYON, #[cfg(feature = "optimism")] "Ecotone" => SpecId::ECOTONE, + #[cfg(feature = "optimism")] + "Fjord" => SpecId::FJORD, _ => Self::LATEST, } } @@ -149,6 +152,8 @@ impl From for &'static str { SpecId::CANYON => "Canyon", #[cfg(feature = "optimism")] SpecId::ECOTONE => "Ecotone", + #[cfg(feature = "optimism")] + SpecId::FJORD => "Fjord", SpecId::LATEST => "Latest", } } @@ -207,6 +212,8 @@ spec!(REGOLITH, RegolithSpec); spec!(CANYON, CanyonSpec); #[cfg(feature = "optimism")] spec!(ECOTONE, EcotoneSpec); +#[cfg(feature = "optimism")] +spec!(FJORD, FjordSpec); #[cfg(not(feature = "optimism"))] #[macro_export] @@ -354,6 +361,10 @@ macro_rules! spec_to_generic { use $crate::EcotoneSpec as SPEC; $e } + $crate::SpecId::FJORD => { + use $crate::FjordSpec as SPEC; + $e + } } }}; } @@ -390,6 +401,10 @@ mod tests { #[cfg(feature = "optimism")] spec_to_generic!(CANYON, assert_eq!(SPEC::SPEC_ID, CANYON)); spec_to_generic!(CANCUN, assert_eq!(SPEC::SPEC_ID, CANCUN)); + #[cfg(feature = "optimism")] + spec_to_generic!(ECOTONE, assert_eq!(SPEC::SPEC_ID, ECOTONE)); + #[cfg(feature = "optimism")] + spec_to_generic!(FJORD, assert_eq!(SPEC::SPEC_ID, FJORD)); spec_to_generic!(PRAGUE, assert_eq!(SPEC::SPEC_ID, PRAGUE)); spec_to_generic!(LATEST, assert_eq!(SPEC::SPEC_ID, LATEST)); } @@ -485,4 +500,30 @@ mod optimism_tests { assert!(SpecId::enabled(SpecId::ECOTONE, SpecId::CANYON)); assert!(SpecId::enabled(SpecId::ECOTONE, SpecId::ECOTONE)); } + + #[test] + fn test_fjord_post_merge_hardforks() { + assert!(FjordSpec::enabled(SpecId::MERGE)); + assert!(FjordSpec::enabled(SpecId::SHANGHAI)); + assert!(FjordSpec::enabled(SpecId::CANCUN)); + assert!(!FjordSpec::enabled(SpecId::LATEST)); + assert!(FjordSpec::enabled(SpecId::BEDROCK)); + assert!(FjordSpec::enabled(SpecId::REGOLITH)); + assert!(FjordSpec::enabled(SpecId::CANYON)); + assert!(FjordSpec::enabled(SpecId::ECOTONE)); + assert!(FjordSpec::enabled(SpecId::FJORD)); + } + + #[test] + fn test_fjord_post_merge_hardforks_spec_id() { + assert!(SpecId::enabled(SpecId::FJORD, SpecId::MERGE)); + assert!(SpecId::enabled(SpecId::FJORD, SpecId::SHANGHAI)); + assert!(SpecId::enabled(SpecId::FJORD, SpecId::CANCUN)); + assert!(!SpecId::enabled(SpecId::FJORD, SpecId::LATEST)); + assert!(SpecId::enabled(SpecId::FJORD, SpecId::BEDROCK)); + assert!(SpecId::enabled(SpecId::FJORD, SpecId::REGOLITH)); + assert!(SpecId::enabled(SpecId::FJORD, SpecId::CANYON)); + assert!(SpecId::enabled(SpecId::FJORD, SpecId::ECOTONE)); + assert!(SpecId::enabled(SpecId::FJORD, SpecId::FJORD)); + } } diff --git a/crates/revm/src/db/in_memory_db.rs b/crates/revm/src/db/in_memory_db.rs index 00602d78..a46e6be9 100644 --- a/crates/revm/src/db/in_memory_db.rs +++ b/crates/revm/src/db/in_memory_db.rs @@ -482,7 +482,7 @@ mod tests { let serialized = serde_json::to_string(&init_state).unwrap(); let deserialized: CacheDB = serde_json::from_str(&serialized).unwrap(); - assert!(deserialized.accounts.get(&account).is_some()); + assert!(deserialized.accounts.contains_key(&account)); assert_eq!( deserialized.accounts.get(&account).unwrap().info.nonce, nonce diff --git a/crates/revm/src/optimism.rs b/crates/revm/src/optimism.rs index 3923b0c6..c72272b8 100644 --- a/crates/revm/src/optimism.rs +++ b/crates/revm/src/optimism.rs @@ -4,7 +4,7 @@ mod handler_register; mod l1block; pub use handler_register::{ - deduct_caller, end, last_frame_return, load_accounts, optimism_handle_register, output, - reward_beneficiary, validate_env, validate_tx_against_state, + deduct_caller, end, last_frame_return, load_accounts, load_precompiles, + optimism_handle_register, output, reward_beneficiary, validate_env, validate_tx_against_state, }; pub use l1block::{L1BlockInfo, BASE_FEE_RECIPIENT, L1_BLOCK_CONTRACT, L1_FEE_RECIPIENT}; diff --git a/crates/revm/src/optimism/handler_register.rs b/crates/revm/src/optimism/handler_register.rs index f517f941..d4996cca 100644 --- a/crates/revm/src/optimism/handler_register.rs +++ b/crates/revm/src/optimism/handler_register.rs @@ -11,9 +11,10 @@ use crate::{ db::Database, spec_to_generic, Account, EVMError, Env, ExecutionResult, HaltReason, HashMap, InvalidTransaction, ResultAndState, Spec, SpecId, SpecId::REGOLITH, U256, }, - Context, FrameResult, + Context, ContextPrecompiles, FrameResult, }; use core::ops::Mul; +use revm_precompile::{secp256r1, PrecompileSpecId, Precompiles}; use std::string::ToString; use std::sync::Arc; @@ -23,6 +24,8 @@ pub fn optimism_handle_register(handler: &mut EvmHandler<'_, handler.validation.env = Arc::new(validate_env::); // Validate transaction against state. handler.validation.tx_against_state = Arc::new(validate_tx_against_state::); + // Load additional precompiles for the given chain spec. + handler.pre_execution.load_precompiles = Arc::new(load_precompiles::); // load l1 data handler.pre_execution.load_accounts = Arc::new(load_accounts::); // An estimated batch cost is charged from the caller and added to L1 Fee Vault. @@ -137,6 +140,21 @@ pub fn last_frame_return( Ok(()) } +/// Load precompiles for Optimism chain. +#[inline] +pub fn load_precompiles() -> ContextPrecompiles { + let mut precompiles = Precompiles::new(PrecompileSpecId::from_spec_id(SPEC::SPEC_ID)).clone(); + + if SPEC::enabled(SpecId::FJORD) { + precompiles.extend([ + // EIP-7212: secp256r1 P256verify + secp256r1::P256VERIFY, + ]) + } + + precompiles.into() +} + /// Load account (make them warm) and l1 data from database. #[inline] pub fn load_accounts( From 3a8b5d0430c57bd07b3e85828bd573dcad3d7d17 Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Sun, 26 May 2024 12:53:08 -0400 Subject: [PATCH 100/105] fix: check canonical Fp elements (#1434) * fix: check canonical field elements * chore: more cleanups * remove hex, update comments * fix more docs * small refactor and check if fp is canonical * doc fix --- crates/precompile/src/bls12_381.rs | 32 +++++++++---- crates/precompile/src/bls12_381/g1.rs | 35 +++++++++----- crates/precompile/src/bls12_381/g1_msm.rs | 1 + crates/precompile/src/bls12_381/g1_mul.rs | 5 +- crates/precompile/src/bls12_381/g2.rs | 45 +++++++++++++----- crates/precompile/src/bls12_381/g2_msm.rs | 1 + .../precompile/src/bls12_381/map_fp2_to_g2.rs | 19 ++------ .../precompile/src/bls12_381/map_fp_to_g1.rs | 14 ++---- crates/precompile/src/bls12_381/utils.rs | 43 ++++++++++++++++- .../test-vectors/fail-add_G1_bls.json | 32 +++++++++++++ .../test-vectors/fail-add_G2_bls.json | 32 +++++++++++++ .../test-vectors/fail-map_fp2_to_G2_bls.json | 27 +++++++++++ .../test-vectors/fail-map_fp_to_G1_bls.json | 27 +++++++++++ .../test-vectors/fail-mul_G1_bls.json | 37 +++++++++++++++ .../test-vectors/fail-mul_G2_bls.json | 37 +++++++++++++++ .../test-vectors/fail-multiexp_G1_bls.json | 37 +++++++++++++++ .../test-vectors/fail-multiexp_G2_bls.json | 37 +++++++++++++++ .../test-vectors/fail-pairing_check_bls.json | 47 +++++++++++++++++++ 18 files changed, 451 insertions(+), 57 deletions(-) create mode 100644 crates/precompile/test-vectors/fail-add_G1_bls.json create mode 100644 crates/precompile/test-vectors/fail-add_G2_bls.json create mode 100644 crates/precompile/test-vectors/fail-map_fp2_to_G2_bls.json create mode 100644 crates/precompile/test-vectors/fail-map_fp_to_G1_bls.json create mode 100644 crates/precompile/test-vectors/fail-mul_G1_bls.json create mode 100644 crates/precompile/test-vectors/fail-mul_G2_bls.json create mode 100644 crates/precompile/test-vectors/fail-multiexp_G1_bls.json create mode 100644 crates/precompile/test-vectors/fail-multiexp_G2_bls.json create mode 100644 crates/precompile/test-vectors/fail-pairing_check_bls.json diff --git a/crates/precompile/src/bls12_381.rs b/crates/precompile/src/bls12_381.rs index fd5daae0..a020e8b1 100644 --- a/crates/precompile/src/bls12_381.rs +++ b/crates/precompile/src/bls12_381.rs @@ -48,14 +48,15 @@ mod test { use serde_derive::{Deserialize, Serialize}; use std::{fs, path::Path}; + /// Test vector structure for BLS12-381 precompile tests. #[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "PascalCase")] struct TestVector { input: String, - expected: String, + expected: Option, name: String, - gas: u64, - error: Option, + gas: Option, + expected_error: Option, } #[derive(Serialize, Deserialize, Debug)] @@ -67,6 +68,15 @@ mod test { } #[rstest] + #[case::fail_g1_add(g1_add::g1_add, "fail-add_G1_bls.json")] + #[case::fail_g1_mul(g1_mul::g1_mul, "fail-mul_G1_bls.json")] + #[case::fail_g1_msm(g1_msm::g1_msm, "fail-multiexp_G1_bls.json")] + #[case::fail_g2_add(g2_add::g2_add, "fail-add_G2_bls.json")] + #[case::fail_g2_mul(g2_mul::g2_mul, "fail-mul_G2_bls.json")] + #[case::fail_g2_msm(g2_msm::g2_msm, "fail-multiexp_G2_bls.json")] + #[case::fail_pairing(pairing::pairing, "fail-pairing_check_bls.json")] + #[case::fail_map_fp_to_g1(map_fp_to_g1::map_fp_to_g1, "fail-map_fp_to_G1_bls.json")] + #[case::fail_map_fp2_to_g2(map_fp2_to_g2::map_fp2_to_g2, "fail-map_fp2_to_G2_bls.json")] #[case::g1_add(g1_add::g1_add, "add_G1_bls.json")] #[case::g1_mul(g1_mul::g1_mul, "mul_G1_bls.json")] #[case::g1_msm(g1_msm::g1_msm, "multiexp_G1_bls.json")] @@ -93,17 +103,23 @@ mod test { }); let target_gas: u64 = 30_000_000; let res = precompile(&input, target_gas); - if vector.error.unwrap_or_default() { - assert!(res.is_err(), "expected error didn't happen in {test_name}"); + if let Some(expected_error) = vector.expected_error { + assert!(res.is_err(), "expected error {expected_error} didn't happen in {test_name}, got result {res:?}"); } else { + let Some(gas) = vector.gas else { + panic!("gas is missing in {test_name}"); + }; let (actual_gas, actual_output) = res.unwrap_or_else(|e| panic!("precompile call failed for {test_name}: {e}")); assert_eq!( - vector.gas, actual_gas, + gas, actual_gas, "expected gas: {}, actual gas: {} in {test_name}", - vector.gas, actual_gas + gas, actual_gas ); - let expected_output = Bytes::from_hex(vector.expected).unwrap(); + let Some(expected) = vector.expected else { + panic!("expected output is missing in {test_name}"); + }; + let expected_output = Bytes::from_hex(expected).unwrap(); assert_eq!( expected_output, actual_output, "expected output: {expected_output}, actual output: {actual_output} in {test_name}"); diff --git a/crates/precompile/src/bls12_381/g1.rs b/crates/precompile/src/bls12_381/g1.rs index 9d4f630d..6e4b73fa 100644 --- a/crates/precompile/src/bls12_381/g1.rs +++ b/crates/precompile/src/bls12_381/g1.rs @@ -1,13 +1,14 @@ -use super::utils::{fp_to_bytes, remove_padding, PADDED_FP_LENGTH}; -use blst::{blst_fp_from_bendian, blst_p1_affine, blst_p1_affine_in_g1, blst_p1_affine_on_curve}; -use revm_primitives::{Bytes, PrecompileError}; +use super::utils::{fp_from_bendian, fp_to_bytes, remove_padding, PADDED_FP_LENGTH}; +use crate::primitives::{Bytes, PrecompileError}; +use blst::{blst_p1_affine, blst_p1_affine_in_g1, blst_p1_affine_on_curve}; /// Length of each of the elements in a g1 operation input. pub(super) const G1_INPUT_ITEM_LENGTH: usize = 128; + /// Output length of a g1 operation. const G1_OUTPUT_LENGTH: usize = 128; -/// Encodes a G1 point in affine format into a byte slice with padded elements. +/// Encodes a G1 point in affine format into byte slice with padded elements. pub(super) fn encode_g1_point(input: *const blst_p1_affine) -> Bytes { let mut out = vec![0u8; G1_OUTPUT_LENGTH]; // SAFETY: out comes from fixed length array, input is a blst value. @@ -18,6 +19,24 @@ pub(super) fn encode_g1_point(input: *const blst_p1_affine) -> Bytes { out.into() } +/// Returns a `blst_p1_affine` from the provided byte slices, which represent the x and y +/// affine coordinates of the point. +/// +/// If the x or y coordinate do not represent a canonical field element, an error is returned. +/// +/// See [fp_from_bendian] for more information. +pub(super) fn decode_and_check_g1( + p0_x: &[u8; 48], + p0_y: &[u8; 48], +) -> Result { + let out = blst_p1_affine { + x: fp_from_bendian(p0_x)?, + y: fp_from_bendian(p0_y)?, + }; + + Ok(out) +} + /// Extracts a G1 point in Affine format from a 128 byte slice representation. /// /// NOTE: This function will perform a G1 subgroup check if `subgroup_check` is set to `true`. @@ -34,13 +53,7 @@ pub(super) fn extract_g1_input( let input_p0_x = remove_padding(&input[..PADDED_FP_LENGTH])?; let input_p0_y = remove_padding(&input[PADDED_FP_LENGTH..G1_INPUT_ITEM_LENGTH])?; - - let mut out = blst_p1_affine::default(); - // SAFETY: input_p0_x and input_p0_y have fixed length, out is a blst value. - unsafe { - blst_fp_from_bendian(&mut out.x, input_p0_x.as_ptr()); - blst_fp_from_bendian(&mut out.y, input_p0_y.as_ptr()); - } + let out = decode_and_check_g1(input_p0_x, input_p0_y)?; if subgroup_check { // NB: Subgroup checks diff --git a/crates/precompile/src/bls12_381/g1_msm.rs b/crates/precompile/src/bls12_381/g1_msm.rs index c8d086ab..f0003a32 100644 --- a/crates/precompile/src/bls12_381/g1_msm.rs +++ b/crates/precompile/src/bls12_381/g1_msm.rs @@ -11,6 +11,7 @@ use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; /// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G1MSM precompile. pub const PRECOMPILE: PrecompileWithAddress = PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(g1_msm)); + /// BLS12_G1MSM precompile address. pub const ADDRESS: u64 = 0x0d; diff --git a/crates/precompile/src/bls12_381/g1_mul.rs b/crates/precompile/src/bls12_381/g1_mul.rs index 305458e2..2b62a39c 100644 --- a/crates/precompile/src/bls12_381/g1_mul.rs +++ b/crates/precompile/src/bls12_381/g1_mul.rs @@ -37,8 +37,11 @@ pub(super) fn g1_mul(input: &Bytes, gas_limit: u64) -> PrecompileResult { // NB: Scalar multiplications, MSMs and pairings MUST perform a subgroup check. // // So we set the subgroup_check flag to `true` - let p0_aff = &extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH], true)?; + let slice = &input[..G1_INPUT_ITEM_LENGTH]; + let p0_aff = &extract_g1_input(slice, true)?; + let mut p0 = blst_p1::default(); + // SAFETY: p0 and p0_aff are blst values. unsafe { blst_p1_from_affine(&mut p0, p0_aff) }; diff --git a/crates/precompile/src/bls12_381/g2.rs b/crates/precompile/src/bls12_381/g2.rs index 321fc5f6..58536895 100644 --- a/crates/precompile/src/bls12_381/g2.rs +++ b/crates/precompile/src/bls12_381/g2.rs @@ -1,13 +1,14 @@ -use super::utils::{fp_to_bytes, remove_padding, FP_LENGTH, PADDED_FP_LENGTH}; -use blst::{blst_fp_from_bendian, blst_p2_affine, blst_p2_affine_in_g2, blst_p2_affine_on_curve}; -use revm_primitives::{Bytes, PrecompileError}; +use super::utils::{fp_from_bendian, fp_to_bytes, remove_padding, FP_LENGTH, PADDED_FP_LENGTH}; +use crate::primitives::{Bytes, PrecompileError}; +use blst::{blst_fp2, blst_p2_affine, blst_p2_affine_in_g2, blst_p2_affine_on_curve}; /// Length of each of the elements in a g2 operation input. pub(super) const G2_INPUT_ITEM_LENGTH: usize = 256; + /// Output length of a g2 operation. const G2_OUTPUT_LENGTH: usize = 256; -/// Encodes a G2 point in affine format into a byte slice with padded elements. +/// Encodes a G2 point in affine format into byte slice with padded elements. pub(super) fn encode_g2_point(input: &blst_p2_affine) -> Bytes { let mut out = vec![0u8; G2_OUTPUT_LENGTH]; fp_to_bytes(&mut out[..PADDED_FP_LENGTH], &input.x.fp[0]); @@ -26,6 +27,33 @@ pub(super) fn encode_g2_point(input: &blst_p2_affine) -> Bytes { out.into() } +/// Convert the following field elements from byte slices into a `blst_p2_affine` point. +pub(super) fn decode_and_check_g2( + x1: &[u8; 48], + x2: &[u8; 48], + y1: &[u8; 48], + y2: &[u8; 48], +) -> Result { + Ok(blst_p2_affine { + x: check_canonical_fp2(x1, x2)?, + y: check_canonical_fp2(y1, y2)?, + }) +} + +/// Checks whether or not the input represents a canonical fp2 field element, returning the field +/// element if successful. +pub(super) fn check_canonical_fp2( + input_1: &[u8; 48], + input_2: &[u8; 48], +) -> Result { + let fp_1 = fp_from_bendian(input_1)?; + let fp_2 = fp_from_bendian(input_2)?; + + let fp2 = blst_fp2 { fp: [fp_1, fp_2] }; + + Ok(fp2) +} + /// Extracts a G2 point in Affine format from a 256 byte slice representation. /// /// NOTE: This function will perform a G2 subgroup check if `subgroup_check` is set to `true`. @@ -45,14 +73,7 @@ pub(super) fn extract_g2_input( input_fps[i] = remove_padding(&input[i * PADDED_FP_LENGTH..(i + 1) * PADDED_FP_LENGTH])?; } - let mut out = blst_p2_affine::default(); - // SAFETY: items in fps have fixed length, out is a blst value. - unsafe { - blst_fp_from_bendian(&mut out.x.fp[0], input_fps[0].as_ptr()); - blst_fp_from_bendian(&mut out.x.fp[1], input_fps[1].as_ptr()); - blst_fp_from_bendian(&mut out.y.fp[0], input_fps[2].as_ptr()); - blst_fp_from_bendian(&mut out.y.fp[1], input_fps[3].as_ptr()); - } + let out = decode_and_check_g2(input_fps[0], input_fps[1], input_fps[2], input_fps[3])?; if subgroup_check { // NB: Subgroup checks diff --git a/crates/precompile/src/bls12_381/g2_msm.rs b/crates/precompile/src/bls12_381/g2_msm.rs index 85f8208f..cedc73a1 100644 --- a/crates/precompile/src/bls12_381/g2_msm.rs +++ b/crates/precompile/src/bls12_381/g2_msm.rs @@ -11,6 +11,7 @@ use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; /// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G2MSM precompile. pub const PRECOMPILE: PrecompileWithAddress = PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(g2_msm)); + /// BLS12_G2MSM precompile address. pub const ADDRESS: u64 = 0x10; diff --git a/crates/precompile/src/bls12_381/map_fp2_to_g2.rs b/crates/precompile/src/bls12_381/map_fp2_to_g2.rs index 51a90ac3..30c3ab5b 100644 --- a/crates/precompile/src/bls12_381/map_fp2_to_g2.rs +++ b/crates/precompile/src/bls12_381/map_fp2_to_g2.rs @@ -1,19 +1,19 @@ use super::{ + g2::check_canonical_fp2, g2::encode_g2_point, utils::{remove_padding, PADDED_FP2_LENGTH, PADDED_FP_LENGTH}, }; use crate::{u64_to_address, PrecompileWithAddress}; -use blst::{ - blst_fp, blst_fp2, blst_fp_from_bendian, blst_map_to_g2, blst_p2, blst_p2_affine, - blst_p2_to_affine, -}; +use blst::{blst_map_to_g2, blst_p2, blst_p2_affine, blst_p2_to_affine}; use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; /// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_MAP_FP2_TO_G2 precompile. pub const PRECOMPILE: PrecompileWithAddress = PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(map_fp2_to_g2)); + /// BLS12_MAP_FP2_TO_G2 precompile address. pub const ADDRESS: u64 = 0x13; + /// Base gas fee for BLS12-381 map_fp2_to_g2 operation. const BASE_GAS_FEE: u64 = 75000; @@ -35,16 +35,7 @@ pub(super) fn map_fp2_to_g2(input: &Bytes, gas_limit: u64) -> PrecompileResult { let input_p0_x = remove_padding(&input[..PADDED_FP_LENGTH])?; let input_p0_y = remove_padding(&input[PADDED_FP_LENGTH..PADDED_FP2_LENGTH])?; - - let mut fp2 = blst_fp2::default(); - let mut fp_x = blst_fp::default(); - let mut fp_y = blst_fp::default(); - // SAFETY: input_p0_x has fixed length, fp_x is a blst value. - unsafe { blst_fp_from_bendian(&mut fp_x, input_p0_x.as_ptr()) }; - // SAFETY: input_p0_y has fixed length, fp_y is a blst value. - unsafe { blst_fp_from_bendian(&mut fp_y, input_p0_y.as_ptr()) }; - fp2.fp[0] = fp_x; - fp2.fp[1] = fp_y; + let fp2 = check_canonical_fp2(input_p0_x, input_p0_y)?; let mut p = blst_p2::default(); // SAFETY: p and fp2 are blst values. diff --git a/crates/precompile/src/bls12_381/map_fp_to_g1.rs b/crates/precompile/src/bls12_381/map_fp_to_g1.rs index a6d9f48e..ddbebb37 100644 --- a/crates/precompile/src/bls12_381/map_fp_to_g1.rs +++ b/crates/precompile/src/bls12_381/map_fp_to_g1.rs @@ -1,18 +1,18 @@ use super::{ g1::encode_g1_point, - utils::{remove_padding, PADDED_FP_LENGTH}, + utils::{fp_from_bendian, remove_padding, PADDED_FP_LENGTH}, }; use crate::{u64_to_address, PrecompileWithAddress}; -use blst::{ - blst_fp, blst_fp_from_bendian, blst_map_to_g1, blst_p1, blst_p1_affine, blst_p1_to_affine, -}; +use blst::{blst_map_to_g1, blst_p1, blst_p1_affine, blst_p1_to_affine}; use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileResult}; /// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_MAP_FP_TO_G1 precompile. pub const PRECOMPILE: PrecompileWithAddress = PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(map_fp_to_g1)); + /// BLS12_MAP_FP_TO_G1 precompile address. pub const ADDRESS: u64 = 0x12; + /// Base gas fee for BLS12-381 map_fp_to_g1 operation. const MAP_FP_TO_G1_BASE: u64 = 5500; @@ -32,11 +32,7 @@ pub(super) fn map_fp_to_g1(input: &Bytes, gas_limit: u64) -> PrecompileResult { } let input_p0 = remove_padding(input)?; - - let mut fp = blst_fp::default(); - - // SAFETY: input_p0 has fixed length, fp is a blst value. - unsafe { blst_fp_from_bendian(&mut fp, input_p0.as_ptr()) }; + let fp = fp_from_bendian(input_p0)?; let mut p = blst_p1::default(); // SAFETY: p and fp are blst values. diff --git a/crates/precompile/src/bls12_381/utils.rs b/crates/precompile/src/bls12_381/utils.rs index de370a07..ba18475c 100644 --- a/crates/precompile/src/bls12_381/utils.rs +++ b/crates/precompile/src/bls12_381/utils.rs @@ -1,4 +1,8 @@ -use blst::{blst_bendian_from_fp, blst_fp, blst_scalar, blst_scalar_from_bendian}; +use core::cmp::Ordering; + +use blst::{ + blst_bendian_from_fp, blst_fp, blst_fp_from_bendian, blst_scalar, blst_scalar_from_bendian, +}; use revm_primitives::PrecompileError; /// Number of bits used in the BLS12-381 curve finite field elements. @@ -13,8 +17,14 @@ pub(super) const PADDED_FP2_LENGTH: usize = 128; pub(super) const PADDING_LENGTH: usize = 16; /// Scalar length. pub(super) const SCALAR_LENGTH: usize = 32; +// Big-endian non-Montgomery form. +pub(super) const MODULUS_REPR: [u8; 48] = [ + 0x1a, 0x01, 0x11, 0xea, 0x39, 0x7f, 0xe6, 0x9a, 0x4b, 0x1b, 0xa7, 0xb6, 0x43, 0x4b, 0xac, 0xd7, + 0x64, 0x77, 0x4b, 0x84, 0xf3, 0x85, 0x12, 0xbf, 0x67, 0x30, 0xd2, 0xa0, 0xf6, 0xb0, 0xf6, 0x24, + 0x1e, 0xab, 0xff, 0xfe, 0xb1, 0x53, 0xff, 0xff, 0xb9, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xab, +]; -/// Encodes a single finite field element into a byte slice with padding. +/// Encodes a single finite field element into byte slice with padding. pub(super) fn fp_to_bytes(out: &mut [u8], input: *const blst_fp) { if out.len() != PADDED_FP_LENGTH { return; @@ -72,3 +82,32 @@ pub(super) fn extract_scalar_input(input: &[u8]) -> Result bool { + for (i, modul) in input.iter().zip(MODULUS_REPR.iter()) { + match i.cmp(modul) { + Ordering::Greater => return false, + Ordering::Less => return true, + Ordering::Equal => continue, + } + } + // false if matching the modulus + false +} + +/// Checks whether or not the input represents a canonical field element, returning the field +/// element if successful. +pub(super) fn fp_from_bendian(input: &[u8; 48]) -> Result { + if !is_valid_be(input) { + return Err(PrecompileError::Other("non-canonical fp value".to_string())); + } + let mut fp = blst_fp::default(); + // SAFETY: input has fixed length, and fp is a blst value. + unsafe { + // This performs the check for canonical field elements + blst_fp_from_bendian(&mut fp, input.as_ptr()); + } + + Ok(fp) +} diff --git a/crates/precompile/test-vectors/fail-add_G1_bls.json b/crates/precompile/test-vectors/fail-add_G1_bls.json new file mode 100644 index 00000000..e61e269d --- /dev/null +++ b/crates/precompile/test-vectors/fail-add_G1_bls.json @@ -0,0 +1,32 @@ +[ + { + "Input": "", + "ExpectedError": "invalid input length", + "Name": "bls_g1add_empty_input" + }, + { + "Input": "00000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21", + "ExpectedError": "invalid input length", + "Name": "bls_g1add_short_input" + }, + { + "Input": "000000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21", + "ExpectedError": "invalid input length", + "Name": "bls_g1add_large_input" + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb00000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a2100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21", + "ExpectedError": "invalid point: not on curve", + "Name": "bls_g1add_point_not_on_curve" + }, + { + "Input": "0000000000000000000000000000000031f2e5916b17be2e71b10b4292f558e727dfd7d48af9cbc5087f0ce00dcca27c8b01e83eaace1aefb539f00adb2271660000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21", + "ExpectedError": "invalid fp.Element encoding", + "Name": "bls_g2add_invalid_field_element" + }, + { + "Input": "1000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21", + "ExpectedError": "invalid field element top bytes", + "Name": "bls_g1add_violate_top_bytes" + } +] \ No newline at end of file diff --git a/crates/precompile/test-vectors/fail-add_G2_bls.json b/crates/precompile/test-vectors/fail-add_G2_bls.json new file mode 100644 index 00000000..9d3ab9c1 --- /dev/null +++ b/crates/precompile/test-vectors/fail-add_G2_bls.json @@ -0,0 +1,32 @@ +[ + { + "Input": "", + "ExpectedError": "invalid input length", + "Name": "bls_g2add_empty_input" + }, + { + "Input": "000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451", + "ExpectedError": "invalid input length", + "Name": "bls_g2add_short_input" + }, + { + "Input": "0000000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451", + "ExpectedError": "invalid input length", + "Name": "bls_g2add_long_input" + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb800000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451", + "ExpectedError": "invalid point: not on curve", + "Name": "bls_g2add_point_not_on_curve" + }, + { + "Input": "000000000000000000000000000000001c4bb49d2a0ef12b7123acdd7110bd292b5bc659edc54dc21b81de057194c79b2a5803255959bbef8e7f56c8c12168630000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451", + "ExpectedError": "invalid fp.Element encoding", + "Name": "bls_g2add_invalid_field_element" + }, + { + "Input": "10000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451", + "ExpectedError": "invalid field element top bytes", + "Name": "bls_g2add_violate_top_bytes" + } +] \ No newline at end of file diff --git a/crates/precompile/test-vectors/fail-map_fp2_to_G2_bls.json b/crates/precompile/test-vectors/fail-map_fp2_to_G2_bls.json new file mode 100644 index 00000000..4411fdcc --- /dev/null +++ b/crates/precompile/test-vectors/fail-map_fp2_to_G2_bls.json @@ -0,0 +1,27 @@ +[ + { + "Input": "", + "ExpectedError": "invalid input length", + "Name": "bls_mapg2_empty_input" + }, + { + "Input": "0000000000000000000000000000000007355d25caf6e7f2f0cb2812ca0e513bd026ed09dda65b177500fa31714e09ea0ded3a078b526bed3307f804d4b93b040000000000000000000000000000000002829ce3c021339ccb5caf3e187f6370e1e2a311dec9b75363117063ab2015603ff52c3d3b98f19c2f65575e99e8b7", + "ExpectedError": "invalid input length", + "Name": "bls_mapg2_short_input" + }, + { + "Input": "000000000000000000000000000000000007355d25caf6e7f2f0cb2812ca0e513bd026ed09dda65b177500fa31714e09ea0ded3a078b526bed3307f804d4b93b040000000000000000000000000000000002829ce3c021339ccb5caf3e187f6370e1e2a311dec9b75363117063ab2015603ff52c3d3b98f19c2f65575e99e8b78c", + "ExpectedError": "invalid input length", + "Name": "bls_mapg2_long_input" + }, + { + "Input": "000000000000000000000000000000000007355d25caf6e7f2f0cb2812ca0e513bd026ed09dda65b177500fa31714e09ea0ded3a078b526bed3307f804d4b93b040000000000000000000000000000000002829ce3c021339ccb5caf3e187f6370e1e2a311dec9b75363117063ab2015603ff52c3d3b98f19c2f65575e99e8b7", + "ExpectedError": "invalid field element top bytes", + "Name": "bls_mapg2_top_bytes" + }, + { + "Input": "0000000000000000000000000000000021366f100476ce8d3be6cfc90d59fe13349e388ed12b6dd6dc31ccd267ff000e2c993a063ca66beced06f804d4b8e5af0000000000000000000000000000000002829ce3c021339ccb5caf3e187f6370e1e2a311dec9b75363117063ab2015603ff52c3d3b98f19c2f65575e99e8b78c", + "ExpectedError": "invalid fp.Element encoding", + "Name": "bls_mapg2_invalid_fq_element" + } +] \ No newline at end of file diff --git a/crates/precompile/test-vectors/fail-map_fp_to_G1_bls.json b/crates/precompile/test-vectors/fail-map_fp_to_G1_bls.json new file mode 100644 index 00000000..2f668569 --- /dev/null +++ b/crates/precompile/test-vectors/fail-map_fp_to_G1_bls.json @@ -0,0 +1,27 @@ +[ + { + "Input": "", + "ExpectedError": "invalid input length", + "Name": "bls_mapg1_empty_input" + }, + { + "Input": "00000000000000000000000000000000156c8a6a2c184569d69a76be144b5cdc5141d2d2ca4fe341f011e25e3969c55ad9e9b9ce2eb833c81a908e5fa4ac5f", + "ExpectedError": "invalid input length", + "Name": "bls_mapg1_short_input" + }, + { + "Input": "0000000000000000000000000000000000156c8a6a2c184569d69a76be144b5cdc5141d2d2ca4fe341f011e25e3969c55ad9e9b9ce2eb833c81a908e5fa4ac5f03", + "ExpectedError": "invalid input length", + "Name": "bls_mapg1_large_input" + }, + { + "Input": "1000000000000000000000000000000000156c8a6a2c184569d69a76be144b5cdc5141d2d2ca4fe341f011e25e3969c55ad9e9b9ce2eb833c81a908e5fa4ac5f", + "ExpectedError": "invalid field element top bytes", + "Name": "bls_mapg1_top_bytes" + }, + { + "Input": "000000000000000000000000000000002f6d9c5465982c0421b61e74579709b3b5b91e57bdd4f6015742b4ff301abb7ef895b9cce00c33c7d48f8e5fa4ac09ae", + "ExpectedError": "invalid fp.Element encoding", + "Name": "bls_invalid_fq_element" + } +] \ No newline at end of file diff --git a/crates/precompile/test-vectors/fail-mul_G1_bls.json b/crates/precompile/test-vectors/fail-mul_G1_bls.json new file mode 100644 index 00000000..5ae8e3b5 --- /dev/null +++ b/crates/precompile/test-vectors/fail-mul_G1_bls.json @@ -0,0 +1,37 @@ +[ + { + "Input": "", + "ExpectedError": "invalid input length", + "Name": "bls_g1mul_empty_input" + }, + { + "Input": "00000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid input length", + "Name": "bls_g1mul_short_input" + }, + { + "Input": "000000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid input length", + "Name": "bls_g1mul_large_input" + }, + { + "Input": "0000000000000000000000000000000031f2e5916b17be2e71b10b4292f558e727dfd7d48af9cbc5087f0ce00dcca27c8b01e83eaace1aefb539f00adb2271660000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid fp.Element encoding", + "Name": "bls_g1mul_invalid_field_element" + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb00000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid point: not on curve", + "Name": "bls_g1mul_point_not_on_curve" + }, + { + "Input": "1000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid field element top bytes", + "Name": "bls_g1mul_violate_top_bytes" + }, + { + "Input": "000000000000000000000000000000000123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000000000000000000000000000000193fb7cedb32b2c3adc06ec11a96bc0d661869316f5e4a577a9f7c179593987beb4fb2ee424dbb2f5dd891e228b46c4a0000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "g1 point is not on correct subgroup", + "Name": "bls_g1mul_g1_not_in_correct_subgroup" + } +] \ No newline at end of file diff --git a/crates/precompile/test-vectors/fail-mul_G2_bls.json b/crates/precompile/test-vectors/fail-mul_G2_bls.json new file mode 100644 index 00000000..5b4fa8a1 --- /dev/null +++ b/crates/precompile/test-vectors/fail-mul_G2_bls.json @@ -0,0 +1,37 @@ +[ + { + "Input": "", + "ExpectedError": "invalid input length", + "Name": "bls_g2mul_empty_input" + }, + { + "Input": "000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid input length", + "Name": "bls_g2mul_short_input" + }, + { + "Input": "0000000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid input length", + "Name": "bls_g2mul_large_input" + }, + { + "Input": "000000000000000000000000000000001c4bb49d2a0ef12b7123acdd7110bd292b5bc659edc54dc21b81de057194c79b2a5803255959bbef8e7f56c8c12168630000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid fp.Element encoding", + "Name": "bls_g2mul_invalid_field_element" + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb800000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid point: not on curve", + "Name": "bls_g2mul_point_not_on_curve" + }, + { + "Input": "10000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid field element top bytes", + "Name": "bls_g2mul_violate_top_bytes" + }, + { + "Input": "00000000000000000000000000000000197bfd0342bbc8bee2beced2f173e1a87be576379b343e93232d6cef98d84b1d696e5612ff283ce2cfdccb2cfb65fa0c00000000000000000000000000000000184e811f55e6f9d84d77d2f79102fd7ea7422f4759df5bf7f6331d550245e3f1bcf6a30e3b29110d85e0ca16f9f6ae7a000000000000000000000000000000000f10e1eb3c1e53d2ad9cf2d398b2dc22c5842fab0a74b174f691a7e914975da3564d835cd7d2982815b8ac57f507348f000000000000000000000000000000000767d1c453890f1b9110fda82f5815c27281aba3f026ee868e4176a0654feea41a96575e0c4d58a14dbfbcc05b5010b10000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "g2 point is not on correct subgroup", + "Name": "bls_g2mul_g2_not_in_correct_subgroup" + } +] \ No newline at end of file diff --git a/crates/precompile/test-vectors/fail-multiexp_G1_bls.json b/crates/precompile/test-vectors/fail-multiexp_G1_bls.json new file mode 100644 index 00000000..976f28c4 --- /dev/null +++ b/crates/precompile/test-vectors/fail-multiexp_G1_bls.json @@ -0,0 +1,37 @@ +[ + { + "Input": "", + "ExpectedError": "invalid input length", + "Name": "bls_g1multiexp_empty_input" + }, + { + "Input": "00000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid input length", + "Name": "bls_g1multiexp_short_input" + }, + { + "Input": "000000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid input length", + "Name": "bls_g1multiexp_long_input" + }, + { + "Input": "0000000000000000000000000000000031f2e5916b17be2e71b10b4292f558e727dfd7d48af9cbc5087f0ce00dcca27c8b01e83eaace1aefb539f00adb2271660000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid fp.Element encoding", + "Name": "bls_g1multiexp_invalid_field_element" + }, + { + "Input": "1000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid field element top bytes", + "Name": "bls_g1multiexp_violate_top_bytes" + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb00000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid point: not on curve", + "Name": "bls_g1multiexp_point_not_on_curve" + }, + { + "Input": "000000000000000000000000000000000123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000000000000000000000000000000193fb7cedb32b2c3adc06ec11a96bc0d661869316f5e4a577a9f7c179593987beb4fb2ee424dbb2f5dd891e228b46c4a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "g1 point is not on correct subgroup", + "Name": "bls_g1multiexp_g1_not_in_correct_subgroup" + } +] \ No newline at end of file diff --git a/crates/precompile/test-vectors/fail-multiexp_G2_bls.json b/crates/precompile/test-vectors/fail-multiexp_G2_bls.json new file mode 100644 index 00000000..48613898 --- /dev/null +++ b/crates/precompile/test-vectors/fail-multiexp_G2_bls.json @@ -0,0 +1,37 @@ +[ + { + "Input": "", + "ExpectedError": "invalid input length", + "Name": "bls_g2multiexp_empty_input" + }, + { + "Input": "000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid input length", + "Name": "bls_g2multiexp_short_input" + }, + { + "Input": "0000000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid input length", + "Name": "bls_g2multiexp_long_input" + }, + { + "Input": "10000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid field element top bytes", + "Name": "bls_g2multiexp_violate_top_bytes" + }, + { + "Input": "000000000000000000000000000000001c4bb49d2a0ef12b7123acdd7110bd292b5bc659edc54dc21b81de057194c79b2a5803255959bbef8e7f56c8c12168630000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid fp.Element encoding", + "Name": "bls_g2multiexp_invalid_field_element" + }, + { + "Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb800000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "invalid point: not on curve", + "Name": "bls_g2multiexp_point_not_on_curve" + }, + { + "Input": "00000000000000000000000000000000197bfd0342bbc8bee2beced2f173e1a87be576379b343e93232d6cef98d84b1d696e5612ff283ce2cfdccb2cfb65fa0c00000000000000000000000000000000184e811f55e6f9d84d77d2f79102fd7ea7422f4759df5bf7f6331d550245e3f1bcf6a30e3b29110d85e0ca16f9f6ae7a000000000000000000000000000000000f10e1eb3c1e53d2ad9cf2d398b2dc22c5842fab0a74b174f691a7e914975da3564d835cd7d2982815b8ac57f507348f000000000000000000000000000000000767d1c453890f1b9110fda82f5815c27281aba3f026ee868e4176a0654feea41a96575e0c4d58a14dbfbcc05b5010b1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d8784510000000000000000000000000000000000000000000000000000000000000002", + "ExpectedError": "g2 point is not on correct subgroup", + "Name": "bls_pairing_g2_not_in_correct_subgroup" + } +] \ No newline at end of file diff --git a/crates/precompile/test-vectors/fail-pairing_check_bls.json b/crates/precompile/test-vectors/fail-pairing_check_bls.json new file mode 100644 index 00000000..e14cb8e6 --- /dev/null +++ b/crates/precompile/test-vectors/fail-pairing_check_bls.json @@ -0,0 +1,47 @@ +[ + { + "Input": "", + "ExpectedError": "invalid input length", + "Name": "bls_pairing_empty_input" + }, + { + "Input": "00000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", + "ExpectedError": "invalid input length", + "Name": "bls_pairing_missing_data" + }, + { + "Input": "000000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", + "ExpectedError": "invalid input length", + "Name": "bls_pairing_extra_data" + }, + { + "Input": "1000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", + "ExpectedError": "invalid field element top bytes", + "Name": "bls_pairing_top_bytes" + }, + { + "Input": "0000000000000000000000000000000031f2e5916b17be2e71b10b4292f558e727dfd7d48af9cbc5087f0ce00dcca27c8b01e83eaace1aefb539f00adb2271660000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", + "ExpectedError": "invalid fp.Element encoding", + "Name": "bls_pairing_invalid_field_element" + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb00000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a2100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", + "ExpectedError": "invalid point: not on curve", + "Name": "bls_pairing_g1_not_on_curve" + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb800000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", + "ExpectedError": "invalid point: not on curve", + "Name": "bls_pairing_g2_not_on_curve" + }, + { + "Input": "000000000000000000000000000000000123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000000000000000000000000000000193fb7cedb32b2c3adc06ec11a96bc0d661869316f5e4a577a9f7c179593987beb4fb2ee424dbb2f5dd891e228b46c4a00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", + "ExpectedError": "g1 point is not on correct subgroup", + "Name": "bls_pairing_g1_not_in_correct_subgroup" + }, + { + "Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000197bfd0342bbc8bee2beced2f173e1a87be576379b343e93232d6cef98d84b1d696e5612ff283ce2cfdccb2cfb65fa0c00000000000000000000000000000000184e811f55e6f9d84d77d2f79102fd7ea7422f4759df5bf7f6331d550245e3f1bcf6a30e3b29110d85e0ca16f9f6ae7a000000000000000000000000000000000f10e1eb3c1e53d2ad9cf2d398b2dc22c5842fab0a74b174f691a7e914975da3564d835cd7d2982815b8ac57f507348f000000000000000000000000000000000767d1c453890f1b9110fda82f5815c27281aba3f026ee868e4176a0654feea41a96575e0c4d58a14dbfbcc05b5010b10000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed", + "ExpectedError": "g2 point is not on correct subgroup", + "Name": "bls_pairing_g2_not_in_correct_subgroup" + } +] \ No newline at end of file From 1b471bd138a1e263e677f566848591071b33d42a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 09:06:41 +0200 Subject: [PATCH 101/105] chore(deps): bump serde from 1.0.202 to 1.0.203 (#1457) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.202 to 1.0.203. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.202...v1.0.203) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 46150b3b..35c433fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3457,18 +3457,18 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", From af88ee9968167a6eb286fc9f7ac9b022c5a6e13c Mon Sep 17 00:00:00 2001 From: rakita Date: Mon, 27 May 2024 11:38:08 +0200 Subject: [PATCH 102/105] fix(Interpreter): wrong block number used (#1458) --- crates/interpreter/src/instructions/host.rs | 3 +-- crates/revm/src/db/states/state.rs | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/interpreter/src/instructions/host.rs b/crates/interpreter/src/instructions/host.rs index 20a2bcfe..0bc777c3 100644 --- a/crates/interpreter/src/instructions/host.rs +++ b/crates/interpreter/src/instructions/host.rs @@ -106,8 +106,7 @@ pub fn blockhash(interpreter: &mut Interpreter, ho gas!(interpreter, gas::BLOCKHASH); pop_top!(interpreter, number); - let block_number = host.env().block.number; - let Some(hash) = host.block_hash(block_number) else { + let Some(hash) = host.block_hash(*number) else { interpreter.instruction_result = InstructionResult::FatalExternalError; return; }; diff --git a/crates/revm/src/db/states/state.rs b/crates/revm/src/db/states/state.rs index 22a937c5..4ca380d8 100644 --- a/crates/revm/src/db/states/state.rs +++ b/crates/revm/src/db/states/state.rs @@ -277,8 +277,9 @@ impl Database for State { let ret = *entry.insert(self.database.block_hash(number)?); // prune all hashes that are older then BLOCK_HASH_HISTORY + let last_block = u64num.saturating_sub(BLOCK_HASH_HISTORY as u64); while let Some(entry) = self.block_hashes.first_entry() { - if *entry.key() < u64num.saturating_sub(BLOCK_HASH_HISTORY as u64) { + if *entry.key() < last_block { entry.remove(); } else { break; From ba0220273c145a925bc2339af46abb917ec49406 Mon Sep 17 00:00:00 2001 From: vandenbogart <73037091+vandenbogart@users.noreply.github.com> Date: Tue, 28 May 2024 03:11:31 -0700 Subject: [PATCH 103/105] remove 'checked' bytecode bench causing benchmarks to crash due to name (#1461) conflict Co-authored-by: Eric Bogard --- crates/revm/benches/bench.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/crates/revm/benches/bench.rs b/crates/revm/benches/bench.rs index d98d3519..b45beefd 100644 --- a/crates/revm/benches/bench.rs +++ b/crates/revm/benches/bench.rs @@ -35,13 +35,6 @@ fn analysis(c: &mut Criterion) { .build(); bench_transact(&mut g, &mut evm); - let checked = Bytecode::new_raw(contract_data.clone()); - let mut evm = evm - .modify() - .reset_handler_with_db(BenchmarkDB::new_bytecode(checked)) - .build(); - bench_transact(&mut g, &mut evm); - let analysed = to_analysed(Bytecode::new_raw(contract_data)); let mut evm = evm .modify() From d9033998b5af9cbb42ef64bba2c7d3457a925e72 Mon Sep 17 00:00:00 2001 From: Brian Bland Date: Tue, 28 May 2024 04:06:20 -0700 Subject: [PATCH 104/105] feat(optimism): Implement new L1 cost function for Fjord (#1420) * Implement new L1 cost function for Fjord * Add fastlz test * Adds a second, more faithful adaptation of solady fastlz for fuzzing * Fix bounds check * Remove some unnecessary constants * Fix some linting issues * Add tests for parity with evm bytecode implementation of fastlz * Replace ethers abi encode/decode with alloy * Use rstest for parameterized testcases * Revert change to examples * Remove duplicate solady flz implementation * Remove direct alloy-sol-macro dependency * Remove unnecessary flag check * Undo dependency reordering --- Cargo.lock | 1 + crates/revm/Cargo.toml | 1 + crates/revm/src/optimism.rs | 1 + crates/revm/src/optimism/fast_lz.rs | 183 ++++++++++++++++++++++++++++ crates/revm/src/optimism/l1block.rs | 116 ++++++++++++++++-- 5 files changed, 294 insertions(+), 8 deletions(-) create mode 100644 crates/revm/src/optimism/fast_lz.rs diff --git a/Cargo.lock b/Cargo.lock index 35c433fb..8250353b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2964,6 +2964,7 @@ dependencies = [ "reqwest 0.12.4", "revm-interpreter", "revm-precompile", + "rstest", "serde", "serde_json", "tokio", diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 9c1830e4..1a93a83d 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -62,6 +62,7 @@ anyhow = "1.0.83" criterion = "0.5" indicatif = "0.17" reqwest = { version = "0.12" } +rstest = "0.19.0" alloy-provider = { git = "https://github.com/alloy-rs/alloy.git", rev = "44b8a6d", default-features = false, features = [ "reqwest", diff --git a/crates/revm/src/optimism.rs b/crates/revm/src/optimism.rs index c72272b8..12f3db99 100644 --- a/crates/revm/src/optimism.rs +++ b/crates/revm/src/optimism.rs @@ -1,5 +1,6 @@ //! Optimism-specific constants, types, and helpers. +mod fast_lz; mod handler_register; mod l1block; diff --git a/crates/revm/src/optimism/fast_lz.rs b/crates/revm/src/optimism/fast_lz.rs new file mode 100644 index 00000000..51ea82d4 --- /dev/null +++ b/crates/revm/src/optimism/fast_lz.rs @@ -0,0 +1,183 @@ +/// Returns the length of the data after compression through FastLZ, based on +// https://github.com/Vectorized/solady/blob/5315d937d79b335c668896d7533ac603adac5315/js/solady.js +pub(crate) fn flz_compress_len(input: &[u8]) -> u32 { + let mut idx: u32 = 2; + + let idx_limit: u32 = if input.len() < 13 { + 0 + } else { + input.len() as u32 - 13 + }; + + let mut anchor = 0; + + let mut size = 0; + + let mut htab = [0; 8192]; + + while idx < idx_limit { + let mut r: u32; + let mut distance: u32; + + loop { + let seq = u24(input, idx); + let hash = hash(seq); + r = htab[hash as usize]; + htab[hash as usize] = idx; + distance = idx - r; + if idx >= idx_limit { + break; + } + idx += 1; + if distance < 8192 && seq == u24(input, r) { + break; + } + } + + if idx >= idx_limit { + break; + } + + idx -= 1; + + if idx > anchor { + size = literals(idx - anchor, size); + } + + let len = cmp(input, r + 3, idx + 3, idx_limit + 9); + size = flz_match(len, size); + + idx = set_next_hash(&mut htab, input, idx + len); + idx = set_next_hash(&mut htab, input, idx); + anchor = idx; + } + + literals(input.len() as u32 - anchor, size) +} + +fn literals(r: u32, size: u32) -> u32 { + let size = size + 0x21 * (r / 0x20); + let r = r % 0x20; + if r != 0 { + size + r + 1 + } else { + size + } +} + +fn cmp(input: &[u8], p: u32, q: u32, r: u32) -> u32 { + let mut l = 0; + let mut r = r - q; + while l < r { + if input[(p + l) as usize] != input[(q + l) as usize] { + r = 0; + } + l += 1; + } + l +} + +fn flz_match(l: u32, size: u32) -> u32 { + let l = l - 1; + let size = size + (3 * (l / 262)); + if l % 262 >= 6 { + size + 3 + } else { + size + 2 + } +} + +fn set_next_hash(htab: &mut [u32; 8192], input: &[u8], idx: u32) -> u32 { + htab[hash(u24(input, idx)) as usize] = idx; + idx + 1 +} + +fn hash(v: u32) -> u16 { + let hash = (v as u64 * 2654435769) >> 19; + hash as u16 & 0x1fff +} + +fn u24(input: &[u8], idx: u32) -> u32 { + u32::from(input[idx as usize]) + + (u32::from(input[(idx + 1) as usize]) << 8) + + (u32::from(input[(idx + 2) as usize]) << 16) +} + +#[cfg(test)] +mod tests { + use alloy_sol_types::sol; + use alloy_sol_types::SolCall; + + use super::*; + use crate::db::BenchmarkDB; + use crate::{ + primitives::address, primitives::bytes, primitives::Bytecode, primitives::Bytes, + primitives::TransactTo, primitives::U256, Evm, + }; + + use rstest::rstest; + + #[rstest] + #[case::empty(&[], 0)] + #[case::thousand_zeros(&[0; 1000], 21)] + #[case::thousand_fourty_twos(&[42; 1000], 21)] + #[case::short_hex(&bytes!("FACADE"), 4)] + #[case::sample_contract_call(&bytes!("02f901550a758302df1483be21b88304743f94f80e51afb613d764fa61751affd3313c190a86bb870151bd62fd12adb8e41ef24f3f000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831000000000000000000000000000000000000000000000000000000000003c1e5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000148c89ed219d02f1a5be012c689b4f5b731827bebe000000000000000000000000c001a033fd89cb37c31b2cba46b6466e040c61fc9b2a3675a7f5f493ebd5ad77c497f8a07cdf65680e238392693019b4092f610222e71b7cec06449cb922b93b6a12744e"), 202)] + #[case::base_0x5dadeb52979f29fc7a7494c43fdabc5be1d8ff404f3aafe93d729fa8e5d00769(&bytes!("b9047c02f904788221050883036ee48409c6c87383037f6f941195cf65f83b3a5768f3c496d3a05ad6412c64b78644364c5bb000b90404d123b4d80000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000f6476f90447748c19248ccaa31e6b8bfda4eb9d830f5f47df7f0998f7c2123d9e6137761b75d3184efb0f788e3b14516000000000000000000000000000000000000000000000000000044364c5bb000000000000000000000000000f38e53bd45c8225a7c94b513beadaa7afe5d222d0000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084d6574614d61736b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035697066733a2f2f516d656852577a743347745961776343347564745657557233454c587261436746434259416b66507331696f48610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cd0d83d9e840f8e27d5c2e365fd365ff1c05b2480000000000000000000000000000000000000000000000000000000000000ce40000000000000000000000000000000000000000000000000000000000000041e4480d358dbae20880960a0a464d63b06565a0c9f9b1b37aa94b522247b23ce149c81359bf4239d1a879eeb41047ec710c15f5c0f67453da59a383e6abd742971c00000000000000000000000000000000000000000000000000000000000000c001a0b57f0ff8516ea29cb26a44ac5055a5420847d1e16a8e7b03b70f0c02291ff2d5a00ad3771e5f39ccacfff0faa8c5d25ef7a1c179f79e66e828ffddcb994c8b512e"), 471)] + fn test_flz_compress_len(#[case] input: &[u8], #[case] expected: u32) { + assert_eq!(flz_compress_len(input), expected); + } + + #[test] + fn test_flz_compress_len_no_repeats() { + let mut input = Vec::new(); + let mut len = 0; + + for i in 0..256 { + input.push(i as u8); + let prev_len = len; + len = flz_compress_len(&input); + assert!(len > prev_len); + } + } + + #[rstest] + #[case::short_hex(bytes!("FACADE"))] + #[case::sample_contract_call(bytes!("02f901550a758302df1483be21b88304743f94f80e51afb613d764fa61751affd3313c190a86bb870151bd62fd12adb8e41ef24f3f000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831000000000000000000000000000000000000000000000000000000000003c1e5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000148c89ed219d02f1a5be012c689b4f5b731827bebe000000000000000000000000c001a033fd89cb37c31b2cba46b6466e040c61fc9b2a3675a7f5f493ebd5ad77c497f8a07cdf65680e238392693019b4092f610222e71b7cec06449cb922b93b6a12744e"))] + #[case::base_0x5dadeb52979f29fc7a7494c43fdabc5be1d8ff404f3aafe93d729fa8e5d00769(bytes!("b9047c02f904788221050883036ee48409c6c87383037f6f941195cf65f83b3a5768f3c496d3a05ad6412c64b78644364c5bb000b90404d123b4d80000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000f6476f90447748c19248ccaa31e6b8bfda4eb9d830f5f47df7f0998f7c2123d9e6137761b75d3184efb0f788e3b14516000000000000000000000000000000000000000000000000000044364c5bb000000000000000000000000000f38e53bd45c8225a7c94b513beadaa7afe5d222d0000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084d6574614d61736b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035697066733a2f2f516d656852577a743347745961776343347564745657557233454c587261436746434259416b66507331696f48610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cd0d83d9e840f8e27d5c2e365fd365ff1c05b2480000000000000000000000000000000000000000000000000000000000000ce40000000000000000000000000000000000000000000000000000000000000041e4480d358dbae20880960a0a464d63b06565a0c9f9b1b37aa94b522247b23ce149c81359bf4239d1a879eeb41047ec710c15f5c0f67453da59a383e6abd742971c00000000000000000000000000000000000000000000000000000000000000c001a0b57f0ff8516ea29cb26a44ac5055a5420847d1e16a8e7b03b70f0c02291ff2d5a00ad3771e5f39ccacfff0faa8c5d25ef7a1c179f79e66e828ffddcb994c8b512e"))] + #[case::base_0xfaada76a2dac09fc17f5a28d066aaabefc6d82ef6589b211ed8c9f766b070721(bytes!("b87602f873822105528304320f8409cfe5c98252089480c67432656d59144ceff962e8faf8926599bcf888011dfe52d06b633f80c001a08632f069f837aea7a28bab0affee14dda116956bd5a850a355c045d25afedd17a0084b8f273efffe17ece527116053e5781a4915ff89ab9c379f1e62c25b697687"))] + #[case::base_0x112864e9b971af6a1dac840018833c5a5a659acc187cfdaba919ad1da013678d(bytes!("b8b302f8b0822105308304320f8409cfe5c9827496944ed4e862860bed51a9570b96d89af5e1b0efefed80b844095ea7b3000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba300000000000000000000000000000000000000000000015e10fb0973595fffffc001a02020e39f07917c1a852feb131c857e12478c7e88a20772b91a8bf5cee38c5aeea06055981727f9aaa3471c1af800555b35a77916c154be3f9d02ad1a63029455ab"))] + #[case::base_0x6905051352691641888d0c427fb137c5b95afb5870d5169ff014eff1d0952195(bytes!("b87202f86f8221058303dc6c8310db1f84068fa8d7838954409436af2ff952a7355c8045fcd5e88bc9f6c8257f7b8080c001a0b89e7ff3d7694109e73e7f4244e032581670313c36e48e485c9c94b853bd81d2a038ffaf8f10859ce21d1f7f7046c3d08027fb8aa15b69038f6102be97aaa1179a"))] + #[case::base_0x6a38e9a26d7202a2268de69d2d47531c1a9829867579a483fb48d78e9e0b080d(bytes!("b9049b02f904978221058201618506fc23ac008506fc23ac008306ddd0943fc91a3afd70395cd496c647d5a6cc9d4b2b7fad80b904243593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000006641d67b00000000000000000000000000000000000000000000000000000000000000030a000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000088487bd8c3222d64d1d0b3fa7098dcf9d94d79e000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000006669635d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad000000000000000000000000000000000000000000000000000000006641d78900000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000418661369ca026f92ff88347bd0e3625a7b5ed65071b366368c68ad7c55aed136c18659b34f9246e30a784227a53dd374fbd3d2124696808c678cd987c4e954a681b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000549e5c020c764dbfffff00000000000000000000000000000000000000000000000002e5a629c093a2b600000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002b088487bd8c3222d64d1d0b3fa7098dcf9d94d79e0027104200000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000c001a014a3acef764ff6d3bb9bd81e420bfa94171a5734ab997dfbc9b41b653ce018a4a01ff5fccb01ef5c60ba3aef67d4e74f3f47312dd78bfbbff9e5090fbf2d3d62bb"))] + fn test_flz_native_evm_parity(#[case] input: Bytes) { + // This bytecode and ABI is for a contract, which wraps the LibZip library for easier fuzz testing. + // The source of this contract is here: https://github.com/danyalprout/fastlz/blob/main/src/FastLz.sol#L6-L10 + sol! { + interface FastLz { + function fastLz(bytes input) external view returns (uint256); + } + } + + let contract_bytecode = Bytecode::new_raw(bytes!("608060405234801561001057600080fd5b506004361061002b5760003560e01c8063920a769114610030575b600080fd5b61004361003e366004610374565b610055565b60405190815260200160405180910390f35b600061006082610067565b5192915050565b60606101e0565b818153600101919050565b600082840393505b838110156100a25782810151828201511860001a1590930292600101610081565b9392505050565b825b602082106100d75782516100c0601f8361006e565b5260209290920191601f19909101906021016100ab565b81156100a25782516100ec600184038361006e565b520160010192915050565b60006001830392505b61010782106101385761012a8360ff1661012560fd6101258760081c60e0018961006e565b61006e565b935061010682039150610100565b600782106101655761015e8360ff16610125600785036101258760081c60e0018961006e565b90506100a2565b61017e8360ff166101258560081c8560051b018761006e565b949350505050565b80516101d890838303906101bc90600081901a600182901a60081b1760029190911a60101b17639e3779b90260131c611fff1690565b8060021b6040510182815160e01c1860e01b8151188152505050565b600101919050565b5060405161800038823961800081016020830180600d8551820103826002015b81811015610313576000805b50508051604051600082901a600183901a60081b1760029290921a60101b91909117639e3779b9810260111c617ffc16909101805160e081811c878603811890911b9091189091528401908183039084841061026857506102a3565b600184019350611fff821161029d578251600081901a600182901a60081b1760029190911a60101b17810361029d57506102a3565b5061020c565b8383106102b1575050610313565b600183039250858311156102cf576102cc87878886036100a9565b96505b6102e3600985016003850160038501610079565b91506102f08782846100f7565b9650506103088461030386848601610186565b610186565b915050809350610200565b5050617fe061032884848589518601036100a9565b03925050506020820180820383525b81811161034e57617fe08101518152602001610337565b5060008152602001604052919050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561038657600080fd5b813567ffffffffffffffff8082111561039e57600080fd5b818401915084601f8301126103b257600080fd5b8135818111156103c4576103c461035e565b604051601f8201601f19908116603f011681019083821181831017156103ec576103ec61035e565b8160405282815287602084870101111561040557600080fd5b82602086016020830137600092810160200192909252509594505050505056fea264697066735822122000646b2953fc4a6f501bd0456ac52203089443937719e16b3190b7979c39511264736f6c63430008190033")); + + let native_val = flz_compress_len(&input); + + let mut evm = Evm::builder() + .with_db(BenchmarkDB::new_bytecode(contract_bytecode.clone())) + .modify_tx_env(|tx| { + tx.caller = address!("1000000000000000000000000000000000000000"); + tx.transact_to = + TransactTo::Call(address!("0000000000000000000000000000000000000000")); + tx.data = FastLz::fastLzCall::new((input,)).abi_encode().into(); + }) + .build(); + + let result_and_state = evm.transact().unwrap(); + let output = result_and_state.result.output().unwrap(); + let evm_val = FastLz::fastLzCall::abi_decode_returns(output, true) + .unwrap() + ._0; + + assert_eq!(U256::from(native_val), evm_val); + } +} diff --git a/crates/revm/src/optimism/l1block.rs b/crates/revm/src/optimism/l1block.rs index b598bd82..2dab41a4 100644 --- a/crates/revm/src/optimism/l1block.rs +++ b/crates/revm/src/optimism/l1block.rs @@ -1,3 +1,4 @@ +use crate::optimism::fast_lz::flz_compress_len; use crate::primitives::{address, db::Database, Address, SpecId, U256}; use core::ops::Mul; @@ -116,12 +117,22 @@ impl L1BlockInfo { } } - /// Calculate the data gas for posting the transaction on L1. Calldata costs 16 gas per non-zero - /// byte and 4 gas per zero byte. + /// Calculate the data gas for posting the transaction on L1. Calldata costs 16 gas per byte + /// after compression. + /// + /// Prior to fjord, calldata costs 16 gas per non-zero byte and 4 gas per zero byte. /// /// Prior to regolith, an extra 68 non-zero bytes were included in the rollup data costs to /// account for the empty signature. pub fn data_gas(&self, input: &[u8], spec_id: SpecId) -> U256 { + if spec_id.is_enabled_in(SpecId::FJORD) { + let estimated_size = self.tx_estimated_size_fjord(input); + + return estimated_size + .saturating_mul(U256::from(NON_ZERO_BYTE_COST)) + .wrapping_div(U256::from(1_000_000)); + }; + let mut rollup_data_gas_cost = U256::from(input.iter().fold(0, |acc, byte| { acc + if *byte == 0x00 { ZERO_BYTE_COST @@ -138,6 +149,18 @@ impl L1BlockInfo { rollup_data_gas_cost } + // Calculate the estimated compressed transaction size in bytes, scaled by 1e6. + // This value is computed based on the following formula: + // max(minTransactionSize, intercept + fastlzCoef*fastlzSize) + fn tx_estimated_size_fjord(&self, input: &[u8]) -> U256 { + let fastlz_size = U256::from(flz_compress_len(input)); + + fastlz_size + .saturating_mul(U256::from(836_500)) + .saturating_sub(U256::from(42_585_600)) + .max(U256::from(100_000_000)) + } + /// Calculate the gas cost of a transaction based on L1 block data posted on L2, depending on the [SpecId] passed. pub fn calculate_tx_l1_cost(&self, input: &[u8], spec_id: SpecId) -> U256 { // If the input is a deposit transaction or empty, the default value is zero. @@ -145,7 +168,9 @@ impl L1BlockInfo { return U256::ZERO; } - if spec_id.is_enabled_in(SpecId::ECOTONE) { + if spec_id.is_enabled_in(SpecId::FJORD) { + self.calculate_tx_l1_cost_fjord(input) + } else if spec_id.is_enabled_in(SpecId::ECOTONE) { self.calculate_tx_l1_cost_ecotone(input, spec_id) } else { self.calculate_tx_l1_cost_bedrock(input, spec_id) @@ -181,19 +206,38 @@ impl L1BlockInfo { } let rollup_data_gas_cost = self.data_gas(input, spec_id); + let l1_fee_scaled = self.calculate_l1_fee_scaled_ecotone(); + + l1_fee_scaled + .saturating_mul(rollup_data_gas_cost) + .wrapping_div(U256::from(1_000_000 * NON_ZERO_BYTE_COST)) + } + + /// Calculate the gas cost of a transaction based on L1 block data posted on L2, post-Fjord. + /// + /// [SpecId::FJORD] L1 cost function: + /// `estimatedSize*(baseFeeScalar*l1BaseFee*16 + blobFeeScalar*l1BlobBaseFee)/1e12` + fn calculate_tx_l1_cost_fjord(&self, input: &[u8]) -> U256 { + let l1_fee_scaled = self.calculate_l1_fee_scaled_ecotone(); + let estimated_size = self.tx_estimated_size_fjord(input); + + estimated_size + .saturating_mul(l1_fee_scaled) + .wrapping_div(U256::from(1e12)) + } + + // l1BaseFee*16*l1BaseFeeScalar + l1BlobBaseFee*l1BlobBaseFeeScalar + fn calculate_l1_fee_scaled_ecotone(&self) -> U256 { let calldata_cost_per_byte = self .l1_base_fee - .saturating_mul(U256::from(16)) + .saturating_mul(U256::from(NON_ZERO_BYTE_COST)) .saturating_mul(self.l1_base_fee_scalar); let blob_cost_per_byte = self .l1_blob_base_fee .unwrap_or_default() .saturating_mul(self.l1_blob_base_fee_scalar.unwrap_or_default()); - calldata_cost_per_byte - .saturating_add(blob_cost_per_byte) - .saturating_mul(rollup_data_gas_cost) - .wrapping_div(U256::from(1_000_000 * 16)) + calldata_cost_per_byte.saturating_add(blob_cost_per_byte) } } @@ -225,6 +269,11 @@ mod tests { // gas cost = 3 * 16 = 48 let regolith_data_gas = l1_block_info.data_gas(&input, SpecId::REGOLITH); assert_eq!(regolith_data_gas, U256::from(48)); + + // Fjord has a minimum compressed size of 100 bytes + // gas cost = 100 * 16 = 1600 + let fjord_data_gas = l1_block_info.data_gas(&input, SpecId::FJORD); + assert_eq!(fjord_data_gas, U256::from(1600)); } #[test] @@ -250,6 +299,11 @@ mod tests { // gas cost = 3 * 16 + 2 * 4 = 56 let regolith_data_gas = l1_block_info.data_gas(&input, SpecId::REGOLITH); assert_eq!(regolith_data_gas, U256::from(56)); + + // Fjord has a minimum compressed size of 100 bytes + // gas cost = 100 * 16 = 1600 + let fjord_data_gas = l1_block_info.data_gas(&input, SpecId::FJORD); + assert_eq!(fjord_data_gas, U256::from(1600)); } #[test] @@ -310,4 +364,50 @@ mod tests { let gas_cost = l1_block_info.calculate_tx_l1_cost(&input, SpecId::ECOTONE); assert_eq!(gas_cost, U256::from(1048)); } + + #[test] + fn test_calculate_tx_l1_cost_fjord() { + // l1FeeScaled = baseFeeScalar*l1BaseFee*16 + blobFeeScalar*l1BlobBaseFee + // = 1000 * 1000 * 16 + 1000 * 1000 + // = 17e6 + let l1_block_info = L1BlockInfo { + l1_base_fee: U256::from(1_000), + l1_base_fee_scalar: U256::from(1_000), + l1_blob_base_fee: Some(U256::from(1_000)), + l1_blob_base_fee_scalar: Some(U256::from(1_000)), + ..Default::default() + }; + + // fastLzSize = 4 + // estimatedSize = max(minTransactionSize, intercept + fastlzCoef*fastlzSize) + // = max(100e6, 836500*4 - 42585600) + // = 100e6 + let input = bytes!("FACADE"); + // l1Cost = estimatedSize * l1FeeScaled / 1e12 + // = 100e6 * 17 / 1e6 + // = 1700 + let gas_cost = l1_block_info.calculate_tx_l1_cost(&input, SpecId::FJORD); + assert_eq!(gas_cost, U256::from(1700)); + + // fastLzSize = 202 + // estimatedSize = max(minTransactionSize, intercept + fastlzCoef*fastlzSize) + // = max(100e6, 836500*202 - 42585600) + // = 126387400 + let input = bytes!("02f901550a758302df1483be21b88304743f94f80e51afb613d764fa61751affd3313c190a86bb870151bd62fd12adb8e41ef24f3f000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831000000000000000000000000000000000000000000000000000000000003c1e5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000148c89ed219d02f1a5be012c689b4f5b731827bebe000000000000000000000000c001a033fd89cb37c31b2cba46b6466e040c61fc9b2a3675a7f5f493ebd5ad77c497f8a07cdf65680e238392693019b4092f610222e71b7cec06449cb922b93b6a12744e"); + // l1Cost = estimatedSize * l1FeeScaled / 1e12 + // = 126387400 * 17 / 1e6 + // = 2148 + let gas_cost = l1_block_info.calculate_tx_l1_cost(&input, SpecId::FJORD); + assert_eq!(gas_cost, U256::from(2148)); + + // Zero rollup data gas cost should result in zero + let input = bytes!(""); + let gas_cost = l1_block_info.calculate_tx_l1_cost(&input, SpecId::FJORD); + assert_eq!(gas_cost, U256::ZERO); + + // Deposit transactions with the EIP-2718 type of 0x7F should result in zero + let input = bytes!("7FFACADE"); + let gas_cost = l1_block_info.calculate_tx_l1_cost(&input, SpecId::FJORD); + assert_eq!(gas_cost, U256::ZERO); + } } From a28a5439b9cfb7494cbd670da10cbedcfe6c5854 Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 28 May 2024 13:08:12 +0200 Subject: [PATCH 105/105] chore(primitives): rename State/Storage to EvmState/EvmStorage (#1459) * fix(Interpreter): wrong block number used * chore(primitives): rename State to PlainState * Restructure StorageSlot and rename PlainState to EvmState * doc --- crates/primitives/src/result.rs | 4 +- crates/primitives/src/state.rs | 41 +++++++-------- crates/revm/src/db/states.rs | 2 +- crates/revm/src/db/states/bundle_account.rs | 4 +- crates/revm/src/db/states/bundle_state.rs | 5 +- crates/revm/src/db/states/cache.rs | 25 ++++++--- crates/revm/src/db/states/plain_account.rs | 57 ++++++++++++++++++++- crates/revm/src/db/states/state.rs | 6 +-- crates/revm/src/journaled_state.rs | 22 ++++---- 9 files changed, 113 insertions(+), 53 deletions(-) diff --git a/crates/primitives/src/result.rs b/crates/primitives/src/result.rs index d5a0f90f..438451e2 100644 --- a/crates/primitives/src/result.rs +++ b/crates/primitives/src/result.rs @@ -1,4 +1,4 @@ -use crate::{Address, Bytes, Log, State, U256}; +use crate::{Address, Bytes, EvmState, Log, U256}; use core::fmt; use std::{boxed::Box, string::String, vec::Vec}; @@ -14,7 +14,7 @@ pub struct ResultAndState { /// Status of execution pub result: ExecutionResult, /// State that got updated - pub state: State, + pub state: EvmState, } /// Result of a transaction execution. diff --git a/crates/primitives/src/state.rs b/crates/primitives/src/state.rs index d0038f8d..37315d3b 100644 --- a/crates/primitives/src/state.rs +++ b/crates/primitives/src/state.rs @@ -3,13 +3,13 @@ use bitflags::bitflags; use core::hash::{Hash, Hasher}; /// EVM State is a mapping from addresses to accounts. -pub type State = HashMap; +pub type EvmState = HashMap; /// Structure used for EIP-1153 transient storage. pub type TransientStorage = HashMap<(Address, U256), U256>; -/// An account's Storage is a mapping from 256-bit integer keys to [StorageSlot]s. -pub type Storage = HashMap; +/// An account's Storage is a mapping from 256-bit integer keys to [EvmStorageSlot]s. +pub type EvmStorage = HashMap; #[derive(Debug, Clone, PartialEq, Eq, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -17,7 +17,7 @@ pub struct Account { /// Balance, nonce, and code. pub info: AccountInfo, /// Storage cache - pub storage: Storage, + pub storage: EvmStorage, /// Account status flags. pub status: AccountStatus, } @@ -119,8 +119,8 @@ impl Account { /// Returns an iterator over the storage slots that have been changed. /// - /// See also [StorageSlot::is_changed] - pub fn changed_storage_slots(&self) -> impl Iterator { + /// See also [EvmStorageSlot::is_changed] + pub fn changed_storage_slots(&self) -> impl Iterator { self.storage.iter().filter(|(_, slot)| slot.is_changed()) } } @@ -138,42 +138,37 @@ impl From for Account { /// This type keeps track of the current value of a storage slot. #[derive(Debug, Clone, Default, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct StorageSlot { - /// The value of the storage slot before it was changed. - /// - /// When the slot is first loaded, this is the original value. - /// - /// If the slot was not changed, this is equal to the present value. - pub previous_or_original_value: U256, - /// When loaded with sload present value is set to original value +pub struct EvmStorageSlot { + /// Original value of the storage slot. + pub original_value: U256, + /// Present value of the storage slot. pub present_value: U256, } -impl StorageSlot { - /// Creates a new _unchanged_ `StorageSlot` for the given value. +impl EvmStorageSlot { + /// Creates a new _unchanged_ `EvmStorageSlot` for the given value. pub fn new(original: U256) -> Self { Self { - previous_or_original_value: original, + original_value: original, present_value: original, } } - /// Creates a new _changed_ `StorageSlot`. - pub fn new_changed(previous_or_original_value: U256, present_value: U256) -> Self { + /// Creates a new _changed_ `EvmStorageSlot`. + pub fn new_changed(original_value: U256, present_value: U256) -> Self { Self { - previous_or_original_value, + original_value, present_value, } } - /// Returns true if the present value differs from the original value pub fn is_changed(&self) -> bool { - self.previous_or_original_value != self.present_value + self.original_value != self.present_value } /// Returns the original value of the storage slot. pub fn original_value(&self) -> U256 { - self.previous_or_original_value + self.original_value } /// Returns the current value of the storage slot. diff --git a/crates/revm/src/db/states.rs b/crates/revm/src/db/states.rs index 2c58f2d6..2fa08b2a 100644 --- a/crates/revm/src/db/states.rs +++ b/crates/revm/src/db/states.rs @@ -18,7 +18,7 @@ pub use bundle_state::{BundleBuilder, BundleState, OriginalValuesKnown}; pub use cache::CacheState; pub use cache_account::CacheAccount; pub use changes::{PlainStateReverts, PlainStorageChangeset, PlainStorageRevert, StateChangeset}; -pub use plain_account::{PlainAccount, StorageWithOriginalValues}; +pub use plain_account::{PlainAccount, StorageSlot, StorageWithOriginalValues}; pub use reverts::{AccountRevert, RevertToSlot}; pub use state::{DBBox, State, StateDBBox}; pub use state_builder::StateBuilder; diff --git a/crates/revm/src/db/states/bundle_account.rs b/crates/revm/src/db/states/bundle_account.rs index c582dfdd..9916139d 100644 --- a/crates/revm/src/db/states/bundle_account.rs +++ b/crates/revm/src/db/states/bundle_account.rs @@ -1,8 +1,8 @@ use super::{ - reverts::AccountInfoRevert, AccountRevert, AccountStatus, RevertToSlot, + reverts::AccountInfoRevert, AccountRevert, AccountStatus, RevertToSlot, StorageSlot, StorageWithOriginalValues, TransitionAccount, }; -use revm_interpreter::primitives::{AccountInfo, StorageSlot, U256}; +use revm_interpreter::primitives::{AccountInfo, U256}; use revm_precompile::HashMap; /// Account information focused on creating of database changesets diff --git a/crates/revm/src/db/states/bundle_state.rs b/crates/revm/src/db/states/bundle_state.rs index 5f189041..8dd4edfe 100644 --- a/crates/revm/src/db/states/bundle_state.rs +++ b/crates/revm/src/db/states/bundle_state.rs @@ -1,12 +1,13 @@ use super::{ changes::{PlainStorageChangeset, StateChangeset}, reverts::{AccountInfoRevert, Reverts}, - AccountRevert, AccountStatus, BundleAccount, PlainStateReverts, RevertToSlot, TransitionState, + AccountRevert, AccountStatus, BundleAccount, PlainStateReverts, RevertToSlot, StorageSlot, + TransitionState, }; use core::{mem, ops::RangeInclusive}; use revm_interpreter::primitives::{ hash_map::{self, Entry}, - AccountInfo, Address, Bytecode, HashMap, HashSet, StorageSlot, B256, KECCAK_EMPTY, U256, + AccountInfo, Address, Bytecode, HashMap, HashSet, B256, KECCAK_EMPTY, U256, }; use std::{ collections::{BTreeMap, BTreeSet}, diff --git a/crates/revm/src/db/states/cache.rs b/crates/revm/src/db/states/cache.rs index eb1c4577..63c0160b 100644 --- a/crates/revm/src/db/states/cache.rs +++ b/crates/revm/src/db/states/cache.rs @@ -2,7 +2,7 @@ use super::{ plain_account::PlainStorage, transition_account::TransitionAccount, CacheAccount, PlainAccount, }; use revm_interpreter::primitives::{ - Account, AccountInfo, Address, Bytecode, HashMap, State as EVMState, B256, + Account, AccountInfo, Address, Bytecode, EvmState, HashMap, B256, }; use std::vec::Vec; @@ -88,7 +88,7 @@ impl CacheState { } /// Apply output of revm execution and create account transitions that are used to build BundleState. - pub fn apply_evm_state(&mut self, evm_state: EVMState) -> Vec<(Address, TransitionAccount)> { + pub fn apply_evm_state(&mut self, evm_state: EvmState) -> Vec<(Address, TransitionAccount)> { let mut transitions = Vec::with_capacity(evm_state.len()); for (address, account) in evm_state { if let Some(transition) = self.apply_account_state(address, account) { @@ -121,6 +121,17 @@ impl CacheState { return this_account.selfdestruct(); } + let is_created = account.is_created(); + let is_empty = account.is_empty(); + + // transform evm storage to storage with previous value. + let changed_storage = account + .storage + .into_iter() + .filter(|(_, slot)| slot.is_changed()) + .map(|(key, slot)| (key, slot.into())) + .collect(); + // Note: it can happen that created contract get selfdestructed in same block // that is why is_created is checked after selfdestructed // @@ -129,25 +140,25 @@ impl CacheState { // Note: It is possibility to create KECCAK_EMPTY contract with some storage // by just setting storage inside CRATE constructor. Overlap of those contracts // is not possible because CREATE2 is introduced later. - if account.is_created() { - return Some(this_account.newly_created(account.info, account.storage)); + if is_created { + return Some(this_account.newly_created(account.info, changed_storage)); } // Account is touched, but not selfdestructed or newly created. // Account can be touched and not changed. // And when empty account is touched it needs to be removed from database. // EIP-161 state clear - if account.is_empty() { + if is_empty { if self.has_state_clear { // touch empty account. this_account.touch_empty_eip161() } else { // if account is empty and state clear is not enabled we should save // empty account. - this_account.touch_create_pre_eip161(account.storage) + this_account.touch_create_pre_eip161(changed_storage) } } else { - Some(this_account.change(account.info, account.storage)) + Some(this_account.change(account.info, changed_storage)) } } } diff --git a/crates/revm/src/db/states/plain_account.rs b/crates/revm/src/db/states/plain_account.rs index f6cb7661..5aadfcc0 100644 --- a/crates/revm/src/db/states/plain_account.rs +++ b/crates/revm/src/db/states/plain_account.rs @@ -1,4 +1,4 @@ -use revm_interpreter::primitives::{AccountInfo, HashMap, StorageSlot, U256}; +use crate::primitives::{AccountInfo, EvmStorageSlot, HashMap, U256}; // TODO rename this to BundleAccount. As for the block level we have original state. #[derive(Clone, Debug, Default, PartialEq, Eq)] @@ -20,9 +20,62 @@ impl PlainAccount { } } +/// This type keeps track of the current value of a storage slot. +#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct StorageSlot { + /// The value of the storage slot before it was changed. + /// + /// When the slot is first loaded, this is the original value. + /// + /// If the slot was not changed, this is equal to the present value. + pub previous_or_original_value: U256, + /// When loaded with sload present value is set to original value + pub present_value: U256, +} + +impl From for StorageSlot { + fn from(value: EvmStorageSlot) -> Self { + Self::new_changed(value.original_value, value.present_value) + } +} + +impl StorageSlot { + /// Creates a new _unchanged_ `StorageSlot` for the given value. + pub fn new(original: U256) -> Self { + Self { + previous_or_original_value: original, + present_value: original, + } + } + + /// Creates a new _changed_ `StorageSlot`. + pub fn new_changed(previous_or_original_value: U256, present_value: U256) -> Self { + Self { + previous_or_original_value, + present_value, + } + } + + /// Returns true if the present value differs from the original value + pub fn is_changed(&self) -> bool { + self.previous_or_original_value != self.present_value + } + + /// Returns the original value of the storage slot. + pub fn original_value(&self) -> U256 { + self.previous_or_original_value + } + + /// Returns the current value of the storage slot. + pub fn present_value(&self) -> U256 { + self.present_value + } +} + /// This storage represent values that are before block changed. /// -/// Note: Storage that we get EVM contains original values before t +/// Note: Storage that we get EVM contains original values before block changed. pub type StorageWithOriginalValues = HashMap; /// Simple plain storage that does not have previous value. diff --git a/crates/revm/src/db/states/state.rs b/crates/revm/src/db/states/state.rs index 4ca380d8..2b63b7ab 100644 --- a/crates/revm/src/db/states/state.rs +++ b/crates/revm/src/db/states/state.rs @@ -303,10 +303,10 @@ impl DatabaseCommit for State { mod tests { use super::*; use crate::db::{ - states::reverts::AccountInfoRevert, AccountRevert, AccountStatus, BundleAccount, - RevertToSlot, + states::{reverts::AccountInfoRevert, StorageSlot}, + AccountRevert, AccountStatus, BundleAccount, RevertToSlot, }; - use revm_interpreter::primitives::{keccak256, StorageSlot}; + use revm_interpreter::primitives::keccak256; #[test] fn block_hash_cache() { diff --git a/crates/revm/src/journaled_state.rs b/crates/revm/src/journaled_state.rs index a233a78c..51b27b32 100644 --- a/crates/revm/src/journaled_state.rs +++ b/crates/revm/src/journaled_state.rs @@ -1,7 +1,7 @@ use crate::interpreter::{InstructionResult, SelfDestructResult}; use crate::primitives::{ - db::Database, hash_map::Entry, Account, Address, Bytecode, EVMError, HashMap, HashSet, Log, - SpecId::*, State, StorageSlot, TransientStorage, KECCAK_EMPTY, PRECOMPILE3, U256, + db::Database, hash_map::Entry, Account, Address, Bytecode, EVMError, EvmState, EvmStorageSlot, + HashMap, HashSet, Log, SpecId::*, TransientStorage, KECCAK_EMPTY, PRECOMPILE3, U256, }; use core::mem; use revm_interpreter::primitives::SpecId; @@ -14,7 +14,7 @@ use std::vec::Vec; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct JournaledState { /// Current state. - pub state: State, + pub state: EvmState, /// [EIP-1153](https://eips.ethereum.org/EIPS/eip-1153) transient storage that is discarded after every transactions pub transient_storage: TransientStorage, /// logs @@ -62,7 +62,7 @@ impl JournaledState { /// Return reference to state. #[inline] - pub fn state(&mut self) -> &mut State { + pub fn state(&mut self) -> &mut EvmState { &mut self.state } @@ -101,7 +101,7 @@ impl JournaledState { /// /// This resets the [JournaledState] to its initial state in [Self::new] #[inline] - pub fn finalize(&mut self) -> (State, Vec) { + pub fn finalize(&mut self) -> (EvmState, Vec) { let Self { state, transient_storage, @@ -273,7 +273,7 @@ impl JournaledState { // Set all storages to default value. They need to be present to act as accessed slots in access list. // it shouldn't be possible for them to have different values then zero as code is not existing for this account, // but because tests can change that assumption we are doing it. - let empty = StorageSlot::default(); + let empty = EvmStorageSlot::default(); account .storage .iter_mut() @@ -314,7 +314,7 @@ impl JournaledState { /// Revert all changes that happened in given journal entries. #[inline] fn journal_revert( - state: &mut State, + state: &mut EvmState, transient_storage: &mut TransientStorage, journal_entries: Vec, is_spurious_dragon_enabled: bool, @@ -542,7 +542,7 @@ impl JournaledState { for slot in slots { if let Entry::Vacant(entry) = account.storage.entry(*slot) { let storage = db.storage(address, *slot).map_err(EVMError::Database)?; - entry.insert(StorageSlot::new(storage)); + entry.insert(EvmStorageSlot::new(storage)); } } Ok(account) @@ -660,7 +660,7 @@ impl JournaledState { had_value: None, }); - vac.insert(StorageSlot::new(value)); + vac.insert(EvmStorageSlot::new(value)); (value, true) } @@ -692,7 +692,7 @@ impl JournaledState { // new value is same as present, we don't need to do anything if present == new { return Ok(SStoreResult { - original_value: slot.previous_or_original_value, + original_value: slot.original_value(), present_value: present, new_value: new, is_cold, @@ -710,7 +710,7 @@ impl JournaledState { // insert value into present state. slot.present_value = new; Ok(SStoreResult { - original_value: slot.previous_or_original_value, + original_value: slot.original_value(), present_value: present, new_value: new, is_cold,