From c3107ec3acf79119016acac203b1c2437005a90e Mon Sep 17 00:00:00 2001 From: Justin Traglia <95511699+jtraglia@users.noreply.github.com> Date: Thu, 28 Mar 2024 06:25:31 -0500 Subject: [PATCH 01/87] fix: use correct rand package for thread_rng (#1233) --- Cargo.lock | 1 + crates/precompile/Cargo.toml | 1 + crates/precompile/benches/bench.rs | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 8e08200369..c857a421fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2353,6 +2353,7 @@ dependencies = [ "criterion", "k256", "once_cell", + "rand", "revm-primitives", "ripemd", "secp256k1", diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index 373e6850e1..c89c82acfc 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -35,6 +35,7 @@ secp256k1 = { version = "0.28.2", default-features = false, features = [ [dev-dependencies] criterion = { version = "0.5" } +rand = { version = "0.8", features = ["std"] } [features] default = ["std", "c-kzg", "secp256k1", "portable"] diff --git a/crates/precompile/benches/bench.rs b/crates/precompile/benches/bench.rs index 2a37013dea..48452b4abb 100644 --- a/crates/precompile/benches/bench.rs +++ b/crates/precompile/benches/bench.rs @@ -9,7 +9,7 @@ use revm_precompile::{ Bytes, }; use revm_primitives::{hex, keccak256, Env, U256, VERSIONED_HASH_VERSION_KZG}; -use secp256k1::{rand, Message, SecretKey, SECP256K1}; +use secp256k1::{Message, SecretKey, SECP256K1}; use sha2::{Digest, Sha256}; /// Benchmarks different cryptography-related precompiles. From a114438c91511113b7ee9a031e467dc60535ab8b Mon Sep 17 00:00:00 2001 From: rakita Date: Thu, 28 Mar 2024 17:52:38 +0100 Subject: [PATCH 02/87] fix(GasInspector): calculate correct remaining gas after call return (#1236) --- crates/revm/src/inspector/gas.rs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/crates/revm/src/inspector/gas.rs b/crates/revm/src/inspector/gas.rs index d22ae0451e..dc98bcaa95 100644 --- a/crates/revm/src/inspector/gas.rs +++ b/crates/revm/src/inspector/gas.rs @@ -35,14 +35,22 @@ impl Inspector for GasInspector { self.gas_remaining = interp.gas.limit(); } + fn step( + &mut self, + interp: &mut crate::interpreter::Interpreter, + _context: &mut EvmContext, + ) { + self.gas_remaining = interp.gas.remaining(); + } + fn step_end( &mut self, interp: &mut crate::interpreter::Interpreter, _context: &mut EvmContext, ) { - let last_gas_remaining = - core::mem::replace(&mut self.gas_remaining, interp.gas.remaining()); - self.last_gas_cost = last_gas_remaining.saturating_sub(self.gas_remaining); + let remaining = interp.gas.remaining(); + self.last_gas_cost = self.gas_remaining.saturating_sub(remaining); + self.gas_remaining = remaining; } fn call_end( @@ -65,8 +73,15 @@ impl Inspector for GasInspector { &mut self, _context: &mut EvmContext, _inputs: &CreateInputs, - outcome: CreateOutcome, + mut outcome: CreateOutcome, ) -> CreateOutcome { + if outcome.result.result.is_error() { + outcome + .result + .gas + .record_cost(outcome.result.gas.remaining()); + self.gas_remaining = 0; + } outcome } } From 020c6ff290b85322b3967e8a494c418dad6ccf76 Mon Sep 17 00:00:00 2001 From: Justin Traglia <95511699+jtraglia@users.noreply.github.com> Date: Thu, 28 Mar 2024 11:53:33 -0500 Subject: [PATCH 03/87] fix: use correct bn128 mul input length (#1238) --- crates/precompile/src/bn128.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/crates/precompile/src/bn128.rs b/crates/precompile/src/bn128.rs index c243e7e477..6d45240973 100644 --- a/crates/precompile/src/bn128.rs +++ b/crates/precompile/src/bn128.rs @@ -92,13 +92,17 @@ pub mod pair { } /// Input length for the add operation. -pub const ADD_INPUT_LEN: usize = 128; +/// `ADD` takes two uncompressed G1 points (64 bytes each). +pub const ADD_INPUT_LEN: usize = 64 + 64; /// Input length for the multiplication operation. -pub const MUL_INPUT_LEN: usize = 128; +/// `MUL` takes an uncompressed G1 point (64 bytes) and scalar (32 bytes). +pub const MUL_INPUT_LEN: usize = 64 + 32; /// Pair element length. -pub const PAIR_ELEMENT_LEN: usize = 192; +/// `PAIR` elements are composed of an uncompressed G1 point (64 bytes) and an uncompressed G2 point +/// (128 bytes). +pub const PAIR_ELEMENT_LEN: usize = 64 + 128; /// Reads a single `Fq` from the input slice. /// From 81b65dd841cc4a5e3b1df1f4d0d1a23fd0c4132e Mon Sep 17 00:00:00 2001 From: Justin Traglia <95511699+jtraglia@users.noreply.github.com> Date: Thu, 28 Mar 2024 12:14:22 -0500 Subject: [PATCH 04/87] nit: remove unnecessary call to into_u256() for bn128 add (#1239) * nit: remove unnecessary call to into_u256() for bn128 add * Rename out to output --- crates/precompile/src/bn128.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/crates/precompile/src/bn128.rs b/crates/precompile/src/bn128.rs index 6d45240973..49d6d3f654 100644 --- a/crates/precompile/src/bn128.rs +++ b/crates/precompile/src/bn128.rs @@ -145,16 +145,9 @@ pub fn run_add(input: &[u8]) -> Result { let mut output = [0u8; 64]; if let Some(sum) = AffineG1::from_jacobian(p1 + p2) { - sum.x() - .into_u256() - .to_big_endian(&mut output[..32]) - .unwrap(); - sum.y() - .into_u256() - .to_big_endian(&mut output[32..]) - .unwrap(); + sum.x().to_big_endian(&mut output[..32]).unwrap(); + sum.y().to_big_endian(&mut output[32..]).unwrap(); } - Ok(output.into()) } @@ -166,12 +159,12 @@ pub fn run_mul(input: &[u8]) -> Result { // `Fr::from_slice` can only fail when the length is not 32. let fr = bn::Fr::from_slice(&input[64..96]).unwrap(); - let mut out = [0u8; 64]; + let mut output = [0u8; 64]; if let Some(mul) = AffineG1::from_jacobian(p * fr) { - mul.x().to_big_endian(&mut out[..32]).unwrap(); - mul.y().to_big_endian(&mut out[32..]).unwrap(); + mul.x().to_big_endian(&mut output[..32]).unwrap(); + mul.y().to_big_endian(&mut output[32..]).unwrap(); } - Ok(out.into()) + Ok(output.into()) } pub fn run_pair( From b6bda4cc22f1bcf3eb4e5b34d5db167191101976 Mon Sep 17 00:00:00 2001 From: Justin Traglia <95511699+jtraglia@users.noreply.github.com> Date: Fri, 29 Mar 2024 06:08:40 -0500 Subject: [PATCH 05/87] docs: link to point evaluation documentation (#1241) --- documentation/src/crates/precompile.md | 3 ++- documentation/src/crates/precompile/point_evaluation.md | 5 ++--- documentation/src/crates/precompile/secp256k1.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/documentation/src/crates/precompile.md b/documentation/src/crates/precompile.md index e4f82c73ae..643ba75942 100644 --- a/documentation/src/crates/precompile.md +++ b/documentation/src/crates/precompile.md @@ -11,6 +11,7 @@ There are 6 precompiles implemented in REVM, and they are: `blake2`, `bn128` cur - [bn128](./precompile/bn128.md): Implements precompiled contracts for addition, scalar multiplication, and optimal ate pairing check on the `alt_bn128` elliptic curve. - [hash](./precompile/hash.md): Implements the `SHA256` and `RIPEMD160` hash functions. - [identity](./precompile/identity.md): Implements the `Identity` precompile, which returns the input data unchanged. +- [point_evaluation](./precompile/point_evaluation.md): Implements the point evaluation precompile for [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844). - [modexp](./precompile/modexp.md): Implements the big integer modular exponentiation precompile. - [secp256k1](./precompile/secp256k1.md): Implements the ECDSA public key recovery precompile, based on `secp256k1` curves. @@ -42,5 +43,5 @@ There are 6 precompiles implemented in REVM, and they are: `blake2`, `bn128` cur ### Re-exported Functionality: -- `Precompiles` provides a static method for each Ethereum hard fork specification (e.g., `homestead`, `byzantium`, `istanbul`, `berlin`, and `latest`), each returning a set of precompiles for that specification. +- `Precompiles` provides a static method for each Ethereum hard fork specification (e.g., `homestead`, `byzantium`, `istanbul`, `berlin`, `cancun`, and `latest`), each returning a set of precompiles for that specification. - `Precompiles` also provides methods to retrieve the list of precompile addresses (`addresses`), to check if a given address is a precompile (`contains`), to get the precompile at a given address (`get`), to check if there are no precompiles (`is_empty`), and to get the number of precompiles (`len`). diff --git a/documentation/src/crates/precompile/point_evaluation.md b/documentation/src/crates/precompile/point_evaluation.md index 9356a89a9f..df982cfe43 100644 --- a/documentation/src/crates/precompile/point_evaluation.md +++ b/documentation/src/crates/precompile/point_evaluation.md @@ -1,6 +1,5 @@ # Point Evaluation Precompile -This precompile is introduced in [EIP4844](https://eips.ethereum.org/EIPS/eip-4844) and is used to verify KZG commitments of blobspace. The precompile allows for efficient verification of commitments to blog transactions. The blob-space transaction contains a large amount of data that cannot be accessed by EVM execution, but has a commitment that can be accessed and verified. The EIP is designed to be forward compatible with danksharding architecture while giving L2s access to cheaper L1 commitments. This precompiled contract resides at the hardcoded Ethereum address `0x000000000000000000000000000000000000000A`. +This precompile is introduced in [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) and is used to verify KZG commitments of blobs. The precompile allows for efficient verification of commitments to blob transactions. Blob transactions contain a large amount of data that cannot be accessed by EVM execution, but has a commitment that can be accessed and verified. The EIP is designed to be forward compatible with [Danksharding](https://ethereum.org/en/roadmap/danksharding/) architecture while giving L2s access to cheaper L1 commitments. This precompiled contract resides at the hardcoded Ethereum address `0x000000000000000000000000000000000000000A`. - -A useful resource is the python reference implementation for the precompile, which can be found [here](https://github.com/ethereum/consensus-specs/blob/86fb82b221474cc89387fa6436806507b3849d88/specs/deneb/polynomial-commitments.md). This implementation uses the [c-kzg](https://github.com/ethereum/c-kzg-4844) audited foreign function interface bindings from the Ethereum Foundation. \ No newline at end of file +A useful resource is the Python reference implementation for the precompile, which can be found [here](https://github.com/ethereum/consensus-specs/blob/86fb82b221474cc89387fa6436806507b3849d88/specs/deneb/polynomial-commitments.md). The implementation in REVM uses [c-kzg-4844](https://github.com/ethereum/c-kzg-4844), via its [foreign function interface](https://en.wikipedia.org/wiki/Foreign_function_interface) bindings, from the Ethereum Foundation. \ No newline at end of file diff --git a/documentation/src/crates/precompile/secp256k1.md b/documentation/src/crates/precompile/secp256k1.md index 757fa577a1..4146448c1e 100644 --- a/documentation/src/crates/precompile/secp256k1.md +++ b/documentation/src/crates/precompile/secp256k1.md @@ -1,6 +1,6 @@ # Secp256k1 -This implementation Ethereum's precompiled contract `ECRECOVER`, an elliptic curve digital signature algorithm (ECDSA) recovery function that recovers the Ethereum address (public key hash) associated with a given signature. The implementation features two versions, each contingent on whether the secp256k1 cryptographic library is enabled, which depends on the build configuration. +This implements Ethereum's precompiled contract `ECRECOVER`, an elliptic curve digital signature algorithm (ECDSA) recovery function that recovers the Ethereum address (public key hash) associated with a given signature. The implementation features two versions, each contingent on whether the secp256k1 cryptographic library is enabled, which depends on the build configuration. Both versions define a `secp256k1` module that includes an `ecrecover` function. This function takes a digital signature and a message as input, both represented as byte arrays, and returns the recovered Ethereum address. It performs this operation by using the signature to recover the original public key used for signing, then hashing this public key with `Keccak256`, Ethereum's chosen hash function. The hash is then truncated to match Ethereum's 20-byte address size. From f5e56fb368610473f05c8ce72d0010c341f30b97 Mon Sep 17 00:00:00 2001 From: Justin Traglia <95511699+jtraglia@users.noreply.github.com> Date: Fri, 29 Mar 2024 06:09:54 -0500 Subject: [PATCH 06/87] fix: update/enable bn128 tests (#1242) --- crates/precompile/src/bn128.rs | 163 ++++++++++++++++----------------- 1 file changed, 79 insertions(+), 84 deletions(-) diff --git a/crates/precompile/src/bn128.rs b/crates/precompile/src/bn128.rs index 49d6d3f654..ce08da7994 100644 --- a/crates/precompile/src/bn128.rs +++ b/crates/precompile/src/bn128.rs @@ -3,31 +3,22 @@ use crate::{ Address, Error, Precompile, PrecompileResult, PrecompileWithAddress, }; use bn::{AffineG1, AffineG2, Fq, Fq2, Group, Gt, G1, G2}; -use revm_primitives::Bytes; pub mod add { use super::*; const ADDRESS: Address = crate::u64_to_address(6); + pub const ISTANBUL_ADD_GAS_COST: u64 = 150; pub const ISTANBUL: PrecompileWithAddress = PrecompileWithAddress( ADDRESS, - Precompile::Standard(|input, gas_limit| { - if 150 > gas_limit { - return Err(Error::OutOfGas); - } - Ok((150, super::run_add(input)?)) - }), + Precompile::Standard(|input, gas_limit| run_add(input, ISTANBUL_ADD_GAS_COST, gas_limit)), ); + pub const BYZANTIUM_ADD_GAS_COST: u64 = 500; pub const BYZANTIUM: PrecompileWithAddress = PrecompileWithAddress( ADDRESS, - Precompile::Standard(|input, gas_limit| { - if 500 > gas_limit { - return Err(Error::OutOfGas); - } - Ok((500, super::run_add(input)?)) - }), + Precompile::Standard(|input, gas_limit| run_add(input, BYZANTIUM_ADD_GAS_COST, gas_limit)), ); } @@ -36,24 +27,16 @@ pub mod mul { const ADDRESS: Address = crate::u64_to_address(7); + pub const ISTANBUL_MUL_GAS_COST: u64 = 6_000; pub const ISTANBUL: PrecompileWithAddress = PrecompileWithAddress( ADDRESS, - Precompile::Standard(|input, gas_limit| { - if 6_000 > gas_limit { - return Err(Error::OutOfGas); - } - Ok((6_000, super::run_mul(input)?)) - }), + Precompile::Standard(|input, gas_limit| run_mul(input, ISTANBUL_MUL_GAS_COST, gas_limit)), ); + pub const BYZANTIUM_MUL_GAS_COST: u64 = 40_000; pub const BYZANTIUM: PrecompileWithAddress = PrecompileWithAddress( ADDRESS, - Precompile::Standard(|input, gas_limit| { - if 40_000 > gas_limit { - return Err(Error::OutOfGas); - } - Ok((40_000, super::run_mul(input)?)) - }), + Precompile::Standard(|input, gas_limit| run_mul(input, BYZANTIUM_MUL_GAS_COST, gas_limit)), ); } @@ -67,7 +50,7 @@ pub mod pair { pub const ISTANBUL: PrecompileWithAddress = PrecompileWithAddress( ADDRESS, Precompile::Standard(|input, gas_limit| { - super::run_pair( + run_pair( input, ISTANBUL_PAIR_PER_POINT, ISTANBUL_PAIR_BASE, @@ -81,7 +64,7 @@ pub mod pair { pub const BYZANTIUM: PrecompileWithAddress = PrecompileWithAddress( ADDRESS, Precompile::Standard(|input, gas_limit| { - super::run_pair( + run_pair( input, BYZANTIUM_PAIR_PER_POINT, BYZANTIUM_PAIR_BASE, @@ -137,7 +120,11 @@ pub fn new_g1_point(px: Fq, py: Fq) -> Result { } } -pub fn run_add(input: &[u8]) -> Result { +pub fn run_add(input: &[u8], gas_cost: u64, gas_limit: u64) -> PrecompileResult { + if gas_cost > gas_limit { + return Err(Error::OutOfGas); + } + let input = right_pad::(input); let p1 = read_point(&input[..64])?; @@ -148,10 +135,14 @@ pub fn run_add(input: &[u8]) -> Result { sum.x().to_big_endian(&mut output[..32]).unwrap(); sum.y().to_big_endian(&mut output[32..]).unwrap(); } - Ok(output.into()) + Ok((gas_cost, output.into())) } -pub fn run_mul(input: &[u8]) -> Result { +pub fn run_mul(input: &[u8], gas_cost: u64, gas_limit: u64) -> PrecompileResult { + if gas_cost > gas_limit { + return Err(Error::OutOfGas); + } + let input = right_pad::(input); let p = read_point(&input[..64])?; @@ -164,7 +155,7 @@ pub fn run_mul(input: &[u8]) -> Result { mul.x().to_big_endian(&mut output[..32]).unwrap(); mul.y().to_big_endian(&mut output[32..]).unwrap(); } - Ok(output.into()) + Ok((gas_cost, output.into())) } pub fn run_pair( @@ -223,10 +214,12 @@ pub fn run_pair( Ok((gas_used, bool_to_bytes32(success))) } -/* #[cfg(test)] mod tests { - use crate::test_utils::new_context; + use crate::bn128::add::BYZANTIUM_ADD_GAS_COST; + use crate::bn128::mul::BYZANTIUM_MUL_GAS_COST; + use crate::bn128::pair::{BYZANTIUM_PAIR_BASE, BYZANTIUM_PAIR_PER_POINT}; + use revm_primitives::hex; use super::*; @@ -247,9 +240,7 @@ mod tests { ) .unwrap(); - let res = Bn128Add::::run(&input, 500, &new_context(), false) - .unwrap() - .output; + let (_, res) = run_add(&input, BYZANTIUM_ADD_GAS_COST, 500).unwrap(); assert_eq!(res, expected); // zero sum test @@ -268,9 +259,7 @@ mod tests { ) .unwrap(); - let res = Bn128Add::::run(&input, 500, &new_context(), false) - .unwrap() - .output; + let (_, res) = run_add(&input, BYZANTIUM_ADD_GAS_COST, 500).unwrap(); assert_eq!(res, expected); // out of gas test @@ -282,8 +271,10 @@ mod tests { 0000000000000000000000000000000000000000000000000000000000000000", ) .unwrap(); - let res = Bn128Add::::run(&input, 499, &new_context(), false); - assert!(matches!(res, Err(Return::OutOfGas))); + + let res = run_add(&input, BYZANTIUM_ADD_GAS_COST, 499); + println!("{:?}", res); + assert!(matches!(res, Err(Error::OutOfGas))); // no input test let input = [0u8; 0]; @@ -294,9 +285,7 @@ mod tests { ) .unwrap(); - let res = Bn128Add::::run(&input, 500, &new_context(), false) - .unwrap() - .output; + let (_, res) = run_add(&input, BYZANTIUM_ADD_GAS_COST, 500).unwrap(); assert_eq!(res, expected); // point not on curve fail @@ -309,11 +298,8 @@ mod tests { ) .unwrap(); - let res = Bn128Add::::run(&input, 500, &new_context(), false); - assert!(matches!( - res, - Err(Return::Other(Cow::Borrowed("ERR_BN128_INVALID_POINT"))) - )); + let res = run_add(&input, BYZANTIUM_ADD_GAS_COST, 500); + assert!(matches!(res, Err(Error::Bn128AffineGFailedToCreate))); } #[test] @@ -332,9 +318,7 @@ mod tests { ) .unwrap(); - let res = Bn128Mul::::run(&input, 40_000, &new_context(), false) - .unwrap() - .output; + let (_, res) = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 40_000).unwrap(); assert_eq!(res, expected); // out of gas test @@ -345,8 +329,9 @@ mod tests { 0200000000000000000000000000000000000000000000000000000000000000", ) .unwrap(); - let res = Bn128Mul::::run(&input, 39_999, &new_context(), false); - assert!(matches!(res, Err(Return::OutOfGas))); + + let res = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 39_999); + assert!(matches!(res, Err(Error::OutOfGas))); // zero multiplication test let input = hex::decode( @@ -363,9 +348,7 @@ mod tests { ) .unwrap(); - let res = Bn128Mul::::run(&input, 40_000, &new_context(), false) - .unwrap() - .output; + let (_, res) = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 40_000).unwrap(); assert_eq!(res, expected); // no input test @@ -377,9 +360,7 @@ mod tests { ) .unwrap(); - let res = Bn128Mul::::run(&input, 40_000, &new_context(), false) - .unwrap() - .output; + let (_, res) = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 40_000).unwrap(); assert_eq!(res, expected); // point not on curve fail @@ -391,11 +372,8 @@ mod tests { ) .unwrap(); - let res = Bn128Mul::::run(&input, 40_000, &new_context(), false); - assert!(matches!( - res, - Err(Return::Other(Cow::Borrowed("ERR_BN128_INVALID_POINT"))) - )); + let res = run_mul(&input, BYZANTIUM_MUL_GAS_COST, 40_000); + assert!(matches!(res, Err(Error::Bn128AffineGFailedToCreate))); } #[test] @@ -420,9 +398,13 @@ mod tests { hex::decode("0000000000000000000000000000000000000000000000000000000000000001") .unwrap(); - let res = Bn128Pair::::run(&input, 260_000, &new_context(), false) - .unwrap() - .output; + let (_, res) = run_pair( + &input, + BYZANTIUM_PAIR_PER_POINT, + BYZANTIUM_PAIR_BASE, + 260_000, + ) + .unwrap(); assert_eq!(res, expected); // out of gas test @@ -442,8 +424,14 @@ mod tests { 12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", ) .unwrap(); - let res = Bn128Pair::::run(&input, 259_999, &new_context(), false); - assert!(matches!(res, Err(Return::OutOfGas))); + + let res = run_pair( + &input, + BYZANTIUM_PAIR_PER_POINT, + BYZANTIUM_PAIR_BASE, + 259_999, + ); + assert!(matches!(res, Err(Error::OutOfGas))); // no input test let input = [0u8; 0]; @@ -451,9 +439,13 @@ mod tests { hex::decode("0000000000000000000000000000000000000000000000000000000000000001") .unwrap(); - let res = Bn128Pair::::run(&input, 260_000, &new_context(), false) - .unwrap() - .output; + let (_, res) = run_pair( + &input, + BYZANTIUM_PAIR_PER_POINT, + BYZANTIUM_PAIR_BASE, + 260_000, + ) + .unwrap(); assert_eq!(res, expected); // point not on curve fail @@ -468,11 +460,13 @@ mod tests { ) .unwrap(); - let res = Bn128Pair::::run(&input, 260_000, &new_context(), false); - assert!(matches!( - res, - Err(Return::Other(Cow::Borrowed("ERR_BN128_INVALID_A"))) - )); + let res = run_pair( + &input, + BYZANTIUM_PAIR_PER_POINT, + BYZANTIUM_PAIR_BASE, + 260_000, + ); + assert!(matches!(res, Err(Error::Bn128AffineGFailedToCreate))); // invalid input length let input = hex::decode( @@ -484,11 +478,12 @@ mod tests { ) .unwrap(); - let res = Bn128Pair::::run(&input, 260_000, &new_context(), false); - assert!(matches!( - res, - Err(Return::Other(Cow::Borrowed("ERR_BN128_INVALID_LEN",))) - )); + let res = run_pair( + &input, + BYZANTIUM_PAIR_PER_POINT, + BYZANTIUM_PAIR_BASE, + 260_000, + ); + assert!(matches!(res, Err(Error::Bn128PairLength))); } } -*/ From e0791cd9f730c13090d491aa5a0fd22a656a5db4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 12:10:03 +0100 Subject: [PATCH 07/87] chore(deps): bump tokio from 1.36.0 to 1.37.0 (#1244) Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.36.0 to 1.37.0. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.36.0...tokio-1.37.0) --- updated-dependencies: - dependency-name: tokio 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/revm/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c857a421fa..8ff5a78d1f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3143,9 +3143,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 5eca3309dd..4434ba0a08 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -33,7 +33,7 @@ serde_json = { version = "1.0", default-features = false, features = [ ], optional = true } # ethersdb -tokio = { version = "1.36", features = [ +tokio = { version = "1.37", features = [ "rt-multi-thread", "macros", ], optional = true } From a201a2d92c4a41f6530fe2b84ec23467255c0636 Mon Sep 17 00:00:00 2001 From: A_A <21040751+Otto-AA@users.noreply.github.com> Date: Fri, 29 Mar 2024 20:32:35 +0100 Subject: [PATCH 08/87] feat: TracerEip3155 optionally traces memory (#1234) * feat: TracerEip3155 optionally traces memory BREAKING CHANGE: the TracerEIP3155 constructor takes an additional "include_memory" flag * perf: use hex::encode_prefixed for TracerEip3155 * refactor: use builder pattern for TracerEip3155 BREAKING CHANGE: update constructor syntax for TracerEip3155 * refactor: use String for TracerEip3155 memory --- bins/revme/src/cmd/statetest/runner.rs | 7 ++----- crates/revm/src/inspector/eip3155.rs | 29 ++++++++++++++++++++++---- examples/db_by_ref.rs | 2 +- examples/generate_block_traces.rs | 2 +- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/bins/revme/src/cmd/statetest/runner.rs b/bins/revme/src/cmd/statetest/runner.rs index 3c75f38e04..d235c572fe 100644 --- a/bins/revme/src/cmd/statetest/runner.rs +++ b/bins/revme/src/cmd/statetest/runner.rs @@ -355,10 +355,7 @@ 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()), - false, - )) + .reset_handler_with_external_context(TracerEip3155::new(Box::new(stderr()))) .append_handler_register(inspector_handle_register) .build(); @@ -421,7 +418,7 @@ 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()), false)) + .with_external_context(TracerEip3155::new(Box::new(stdout()))) .append_handler_register(inspector_handle_register) .build(); let _ = evm.transact_commit(); diff --git a/crates/revm/src/inspector/eip3155.rs b/crates/revm/src/inspector/eip3155.rs index fc9ae809cc..0a7f62ec0d 100644 --- a/crates/revm/src/inspector/eip3155.rs +++ b/crates/revm/src/inspector/eip3155.rs @@ -22,6 +22,8 @@ pub struct TracerEip3155 { refunded: i64, mem_size: usize, skip: bool, + include_memory: bool, + memory: Option, } // # Output @@ -58,7 +60,7 @@ struct Output { error: Option, /// Array of all allocated values #[serde(default, skip_serializing_if = "Option::is_none")] - memory: Option>, + memory: Option, /// Array of all stored values #[serde(default, skip_serializing_if = "Option::is_none")] storage: Option>, @@ -98,12 +100,14 @@ impl TracerEip3155 { } impl TracerEip3155 { - pub fn new(output: Box, print_summary: bool) -> Self { + pub fn new(output: Box) -> Self { Self { output, gas_inspector: GasInspector::default(), - print_summary, + print_summary: true, + include_memory: false, stack: Default::default(), + memory: Default::default(), pc: 0, opcode: 0, gas: 0, @@ -113,6 +117,18 @@ impl TracerEip3155 { } } + /// Don't include a summary at the end of the trace + pub fn without_summary(mut self) -> Self { + self.print_summary = false; + self + } + + /// Include a memory field for each step. This significantly increases processing time and output size. + pub fn with_memory(mut self) -> Self { + self.include_memory = true; + self + } + fn write_value(&mut self, value: &impl serde::Serialize) -> std::io::Result<()> { serde_json::to_writer(&mut *self.output, value)?; self.output.write_all(b"\n")?; @@ -128,6 +144,11 @@ 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.memory = if self.include_memory { + Some(hex::encode_prefixed(interp.shared_memory.context_memory())) + } else { + None + }; self.pc = interp.program_counter(); self.opcode = interp.current_opcode(); self.mem_size = interp.shared_memory.len(); @@ -159,7 +180,7 @@ impl Inspector for TracerEip3155 { } else { None }, - memory: None, + memory: self.memory.take(), storage: None, return_stack: None, }; diff --git a/examples/db_by_ref.rs b/examples/db_by_ref.rs index c9094a905b..9e3615400c 100644 --- a/examples/db_by_ref.rs +++ b/examples/db_by_ref.rs @@ -72,7 +72,7 @@ fn run_transaction_and_commit(db: &mut CacheDB) -> anyhow::Result<()> { fn main() -> anyhow::Result<()> { let mut cache_db = CacheDB::new(EmptyDB::default()); - let mut tracer = TracerEip3155::new(Box::new(std::io::stdout()), true); + let mut tracer = TracerEip3155::new(Box::new(std::io::stdout())); run_transaction_and_commit_with_ext(&mut cache_db, &mut tracer, inspector_handle_register)?; run_transaction_and_commit(&mut cache_db)?; diff --git a/examples/generate_block_traces.rs b/examples/generate_block_traces.rs index 37a1550778..5270bb9abd 100644 --- a/examples/generate_block_traces.rs +++ b/examples/generate_block_traces.rs @@ -76,7 +76,7 @@ async fn main() -> anyhow::Result<()> { let mut state = StateBuilder::new_with_database(cache_db).build(); let mut evm = Evm::builder() .with_db(&mut state) - .with_external_context(TracerEip3155::new(Box::new(std::io::stdout()), true)) + .with_external_context(TracerEip3155::new(Box::new(std::io::stdout()))) .modify_block_env(|b| { if let Some(number) = block.number { let nn = number.0[0]; From 57825ff8c6b3ff82796171c3965c45004c1acb1a Mon Sep 17 00:00:00 2001 From: Justin Traglia <95511699+jtraglia@users.noreply.github.com> Date: Sat, 30 Mar 2024 05:19:52 -0500 Subject: [PATCH 09/87] nit: move div by zero check from smod to i256_mod (#1248) --- .../src/instructions/arithmetic.rs | 4 +- crates/interpreter/src/instructions/i256.rs | 140 +++++++++++++----- 2 files changed, 106 insertions(+), 38 deletions(-) diff --git a/crates/interpreter/src/instructions/arithmetic.rs b/crates/interpreter/src/instructions/arithmetic.rs index e982ccd471..583299d58c 100644 --- a/crates/interpreter/src/instructions/arithmetic.rs +++ b/crates/interpreter/src/instructions/arithmetic.rs @@ -48,9 +48,7 @@ pub fn rem(interpreter: &mut Interpreter, _host: &mut H) { pub fn smod(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::LOW); pop_top!(interpreter, op1, op2); - if *op2 != U256::ZERO { - *op2 = i256_mod(op1, *op2) - } + *op2 = i256_mod(op1, *op2) } pub fn addmod(interpreter: &mut Interpreter, _host: &mut H) { diff --git a/crates/interpreter/src/instructions/i256.rs b/crates/interpreter/src/instructions/i256.rs index a26ae69ad4..eaccbab705 100644 --- a/crates/interpreter/src/instructions/i256.rs +++ b/crates/interpreter/src/instructions/i256.rs @@ -77,7 +77,7 @@ pub fn i256_div(mut first: U256, mut second: U256) -> U256 { } let first_sign = i256_sign_compl(&mut first); - if first_sign == Sign::Minus && first == MIN_NEGATIVE_VALUE && second == U256::from(1) { + if first == MIN_NEGATIVE_VALUE && second == U256::from(1) { return two_compl(MIN_NEGATIVE_VALUE); } @@ -105,9 +105,11 @@ pub fn i256_mod(mut first: U256, mut second: U256) -> U256 { return U256::ZERO; } - let _ = i256_sign_compl(&mut second); + let second_sign = i256_sign_compl(&mut second); + if second_sign == Sign::Zero { + return U256::ZERO; + } - // necessary overflow checks are done above, perform the operation let mut r = first % second; // set sign bit to zero @@ -125,6 +127,58 @@ mod tests { use super::*; use core::num::Wrapping; + const ZERO: U256 = U256::ZERO; + const ONE: U256 = U256::from_limbs([ + 0x0000000000000001, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + ]); + const TWO: U256 = U256::from_limbs([ + 0x0000000000000002, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + ]); + const THREE: U256 = U256::from_limbs([ + 0x0000000000000003, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + ]); + const FOUR: U256 = U256::from_limbs([ + 0x0000000000000004, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + ]); + + const NEG_ONE: U256 = U256::from_limbs([ + 0xffffffffffffffff, + 0xffffffffffffffff, + 0xffffffffffffffff, + 0xffffffffffffffff, + ]); + const NEG_TWO: U256 = U256::from_limbs([ + 0xfffffffffffffffe, + 0xffffffffffffffff, + 0xffffffffffffffff, + 0xffffffffffffffff, + ]); + const NEG_THREE: U256 = U256::from_limbs([ + 0xfffffffffffffffd, + 0xffffffffffffffff, + 0xffffffffffffffff, + 0xffffffffffffffff, + ]); + + const I256_MAX: U256 = U256::from_limbs([ + 0xffffffffffffffff, + 0xffffffffffffffff, + 0xffffffffffffffff, + 0x7fffffffffffffff, + ]); + #[test] fn div_i256() { // Sanity checks based on i8. Notice that we need to use `Wrapping` here because @@ -133,70 +187,86 @@ mod tests { assert_eq!(i8::MAX / -1, -i8::MAX); // Now the same calculations based on i256 - let one = U256::from(1); - let one_hundred = U256::from(100); let fifty = U256::from(50); - let two = U256::from(2); - let neg_one_hundred = U256::from(100); - let minus_one = U256::from(1); - let max_value = U256::from(2).pow(U256::from(255)) - U256::from(1); - let neg_max_value = U256::from(2).pow(U256::from(255)) - U256::from(1); - - assert_eq!(i256_div(MIN_NEGATIVE_VALUE, minus_one), MIN_NEGATIVE_VALUE); - assert_eq!(i256_div(MIN_NEGATIVE_VALUE, one), MIN_NEGATIVE_VALUE); - assert_eq!(i256_div(max_value, one), max_value); - assert_eq!(i256_div(max_value, minus_one), neg_max_value); - assert_eq!(i256_div(one_hundred, minus_one), neg_one_hundred); - assert_eq!(i256_div(one_hundred, two), fifty); + let one_hundred = U256::from(100); + + assert_eq!(i256_div(MIN_NEGATIVE_VALUE, NEG_ONE), MIN_NEGATIVE_VALUE); + assert_eq!(i256_div(MIN_NEGATIVE_VALUE, ONE), MIN_NEGATIVE_VALUE); + assert_eq!(i256_div(I256_MAX, ONE), I256_MAX); + assert_eq!(i256_div(I256_MAX, NEG_ONE), NEG_ONE * I256_MAX); + assert_eq!(i256_div(one_hundred, NEG_ONE), NEG_ONE * one_hundred); + assert_eq!(i256_div(one_hundred, TWO), fifty); } #[test] fn test_i256_sign() { - assert_eq!(i256_sign(&U256::ZERO), Sign::Zero); - assert_eq!(i256_sign(&U256::from(1)), Sign::Plus); + assert_eq!(i256_sign(&ZERO), Sign::Zero); + assert_eq!(i256_sign(&ONE), Sign::Plus); assert_eq!(i256_sign(&MIN_NEGATIVE_VALUE), Sign::Minus); } #[test] fn test_i256_sign_compl() { - let mut positive = U256::from(1); + let mut zero = ZERO; + let mut positive = ONE; let mut negative = MIN_NEGATIVE_VALUE; + assert_eq!(i256_sign_compl(&mut zero), Sign::Zero); assert_eq!(i256_sign_compl(&mut positive), Sign::Plus); assert_eq!(i256_sign_compl(&mut negative), Sign::Minus); } #[test] fn test_two_compl() { - let value = U256::from(1); - assert_eq!(two_compl(value), U256::MAX); + assert_eq!(two_compl(ZERO), ZERO); + assert_eq!(two_compl(ONE), NEG_ONE); + assert_eq!(two_compl(NEG_ONE), ONE); + assert_eq!(two_compl(TWO), NEG_TWO); + assert_eq!(two_compl(NEG_TWO), TWO); + + // Two's complement of the min value is itself. + assert_eq!(two_compl(MIN_NEGATIVE_VALUE), MIN_NEGATIVE_VALUE); } #[test] fn test_two_compl_mut() { - let mut value = U256::from(1); + let mut value = ONE; two_compl_mut(&mut value); - assert_eq!(value, U256::MAX); + assert_eq!(value, NEG_ONE); } #[test] fn test_i256_cmp() { - assert_eq!(i256_cmp(&U256::from(1), &U256::from(2)), Ordering::Less); - assert_eq!(i256_cmp(&U256::from(2), &U256::from(2)), Ordering::Equal); - assert_eq!(i256_cmp(&U256::from(3), &U256::from(2)), Ordering::Greater); + assert_eq!(i256_cmp(&ONE, &TWO), Ordering::Less); + assert_eq!(i256_cmp(&TWO, &TWO), Ordering::Equal); + assert_eq!(i256_cmp(&THREE, &TWO), Ordering::Greater); + assert_eq!(i256_cmp(&NEG_ONE, &NEG_ONE), Ordering::Equal); + assert_eq!(i256_cmp(&NEG_ONE, &NEG_TWO), Ordering::Greater); + assert_eq!(i256_cmp(&NEG_ONE, &ZERO), Ordering::Less); + assert_eq!(i256_cmp(&NEG_TWO, &TWO), Ordering::Less); } #[test] fn test_i256_div() { - let one = U256::from(1); - let two = U256::from(2); - assert_eq!(i256_div(MIN_NEGATIVE_VALUE, one), MIN_NEGATIVE_VALUE); - assert_eq!(i256_div(U256::from(4), two), U256::from(2)); + assert_eq!(i256_div(ONE, ZERO), ZERO); + assert_eq!(i256_div(ZERO, ONE), ZERO); + assert_eq!(i256_div(ZERO, NEG_ONE), ZERO); + assert_eq!(i256_div(MIN_NEGATIVE_VALUE, ONE), MIN_NEGATIVE_VALUE); + assert_eq!(i256_div(FOUR, TWO), TWO); + assert_eq!(i256_div(MIN_NEGATIVE_VALUE, MIN_NEGATIVE_VALUE), ONE); + assert_eq!(i256_div(TWO, NEG_ONE), NEG_TWO); + assert_eq!(i256_div(NEG_TWO, NEG_ONE), TWO); } #[test] fn test_i256_mod() { - let one = U256::from(1); - let two = U256::from(2); - assert_eq!(i256_mod(U256::from(4), two), U256::ZERO); - assert_eq!(i256_mod(U256::from(3), two), one); + assert_eq!(i256_mod(ZERO, ONE), ZERO); + assert_eq!(i256_mod(ONE, ZERO), ZERO); + assert_eq!(i256_mod(FOUR, TWO), ZERO); + assert_eq!(i256_mod(THREE, TWO), ONE); + assert_eq!(i256_mod(MIN_NEGATIVE_VALUE, ONE), ZERO); + assert_eq!(i256_mod(TWO, TWO), ZERO); + assert_eq!(i256_mod(TWO, THREE), TWO); + assert_eq!(i256_mod(NEG_TWO, THREE), NEG_TWO); + assert_eq!(i256_mod(TWO, NEG_THREE), TWO); + assert_eq!(i256_mod(NEG_TWO, NEG_THREE), NEG_TWO); } } From b1ec4eb7252e4b50be791c9ae64a445d011a60a6 Mon Sep 17 00:00:00 2001 From: Pana Date: Sun, 31 Mar 2024 18:52:35 +0800 Subject: [PATCH 10/87] fix(TracerEip3155): clear Inspector data after transaction. (#1230) * 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 --- crates/revm/src/inspector/eip3155.rs | 85 ++++++++++++++++--- crates/revm/src/inspector/handler_register.rs | 2 +- .../src/crates/interpreter/instructions.md | 4 +- documentation/src/crates/revm.md | 4 +- examples/generate_block_traces.rs | 5 +- 5 files changed, 82 insertions(+), 18 deletions(-) diff --git a/crates/revm/src/inspector/eip3155.rs b/crates/revm/src/inspector/eip3155.rs index 0a7f62ec0d..ca1f6cc574 100644 --- a/crates/revm/src/inspector/eip3155.rs +++ b/crates/revm/src/inspector/eip3155.rs @@ -1,6 +1,9 @@ use crate::{ inspectors::GasInspector, - interpreter::{opcode, CallInputs, CallOutcome, Interpreter}, + interpreter::{ + opcode, CallInputs, CallOutcome, CreateInputs, CreateOutcome, Interpreter, + InterpreterResult, + }, primitives::{db::Database, hex, HashMap, B256, U256}, EvmContext, Inspector, }; @@ -97,6 +100,30 @@ impl TracerEip3155 { pub fn set_writer(&mut self, writer: Box) { self.output = writer; } + + /// Resets the Tracer to its initial state of [Self::new]. + /// This makes the inspector ready to be used again. + pub fn clear(&mut self) { + let Self { + gas_inspector, + stack, + pc, + opcode, + gas, + refunded, + mem_size, + skip, + .. + } = self; + *gas_inspector = GasInspector::default(); + stack.clear(); + *pc = 0; + *opcode = 0; + *gas = 0; + *refunded = 0; + *mem_size = 0; + *skip = false; + } } impl TracerEip3155 { @@ -134,6 +161,28 @@ impl TracerEip3155 { self.output.write_all(b"\n")?; self.output.flush() } + + fn print_summary( + &mut self, + result: &InterpreterResult, + context: &mut EvmContext, + ) { + if self.print_summary { + let spec_name: &str = context.spec_id().into(); + let value = Summary { + state_root: B256::ZERO.to_string(), + output: result.output.to_string(), + gas_used: hex_number( + context.inner.env().tx.gas_limit - self.gas_inspector.gas_remaining(), + ), + pass: result.is_ok(), + + time: None, + fork: Some(spec_name.to_string()), + }; + let _ = self.write_value(&value); + } + } } impl Inspector for TracerEip3155 { @@ -194,19 +243,31 @@ impl Inspector for TracerEip3155 { outcome: CallOutcome, ) -> CallOutcome { let outcome = self.gas_inspector.call_end(context, inputs, outcome); - if self.print_summary && context.journaled_state.depth() == 0 { - let spec_name: &str = context.spec_id().into(); - let value = Summary { - state_root: B256::ZERO.to_string(), - output: outcome.result.output.to_string(), - gas_used: hex_number(inputs.gas_limit - self.gas_inspector.gas_remaining()), - pass: outcome.result.is_ok(), - time: None, - fork: Some(spec_name.to_string()), - }; - let _ = self.write_value(&value); + if context.journaled_state.depth() == 0 { + self.print_summary(&outcome.result, context); + // clear the state if we are at the top level + self.clear(); + } + + outcome + } + + fn create_end( + &mut self, + context: &mut EvmContext, + inputs: &CreateInputs, + outcome: CreateOutcome, + ) -> CreateOutcome { + let outcome = self.gas_inspector.create_end(context, inputs, outcome); + + if context.journaled_state.depth() == 0 { + self.print_summary(&outcome.result, context); + + // clear the state if we are at the top level + self.clear(); } + outcome } } diff --git a/crates/revm/src/inspector/handler_register.rs b/crates/revm/src/inspector/handler_register.rs index 0598c4f829..ba5fb8e117 100644 --- a/crates/revm/src/inspector/handler_register.rs +++ b/crates/revm/src/inspector/handler_register.rs @@ -133,7 +133,7 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector>( let call_input_stack = Rc::>>::new(RefCell::new(Vec::new())); let create_input_stack = Rc::>>::new(RefCell::new(Vec::new())); - // Create handle + // Create handler let create_input_stack_inner = create_input_stack.clone(); let old_handle = handler.execution.create.clone(); handler.execution.create = Arc::new( diff --git a/documentation/src/crates/interpreter/instructions.md b/documentation/src/crates/interpreter/instructions.md index 7835718131..84b5b8a857 100644 --- a/documentation/src/crates/interpreter/instructions.md +++ b/documentation/src/crates/interpreter/instructions.md @@ -10,6 +10,6 @@ The `Opcode` enum represents the opcodes that are available in the Ethereum Virt The `Instruction` struct represents a single instruction in the EVM. It contains the opcode, which is the operation to be performed, and a list of bytes representing the operands for the instruction. -## `execute` Function +## `step` Function -The `execute` function interprets an instruction. It uses the opcode to determine what operation to perform and then performs the operation using the operands in the instruction. \ No newline at end of file +The `step` function interprets an instruction. It uses the opcode to determine what operation to perform and then performs the operation using the operands in the instruction. \ No newline at end of file diff --git a/documentation/src/crates/revm.md b/documentation/src/crates/revm.md index ed17b8d7d5..2ad609f40a 100644 --- a/documentation/src/crates/revm.md +++ b/documentation/src/crates/revm.md @@ -4,7 +4,7 @@ The `evm` crate is focused on the implementation of Ethereum Virtual Machine (EV This crate pulls Primitives, Interpreter and Precompiles together to deliver the rust evm. The starting point for reading the documentation is [`Evm`](./revm/evm.md), that is main structure of EVM. -Then, I read about the [`EvmBuilder`](./revm/builder.md) that is used to create the `Evm` and modify it. +Then, you can read about the [`EvmBuilder`](./revm/builder.md) that is used to create the `Evm` and modify it. After, you can read about the [`Handler`](./revm/handler.md) that is used to modify the logic of the Evm, and it will tie with how Evm introspection can be done. Finally, you can read about the [`Inspector`](./revm/inspector.md), a legacy interface for inspecting execution that is now repurposed as a handler register example. @@ -34,6 +34,6 @@ Finally, you can read about the [`Inspector`](./revm/inspector.md), a legacy int - `Database`, `DatabaseCommit`, `InMemoryDB`: These types from the `db` module are re-exported for handling the database operations. - `EVM`: The `EVM` struct from the `evm` module is re-exported, serving as the main interface to the EVM implementation. -- `EvmContext`: The `EvmContext` struct from the `evm_impl` module is re-exported, providing data structures to encapsulate EVM execution data. +- `EvmContext`: The `EvmContext` struct from the `context` module is re-exported, providing data structures to encapsulate EVM execution data. - `JournalEntry`, `JournaledState`: These types from the `journaled_state` module are re-exported, providing the journaling system for the EVM state. - `inspectors`, `Inspector`: The `Inspector` trait and its implementations from the `inspector` module are re-exported for observing the EVM execution. diff --git a/examples/generate_block_traces.rs b/examples/generate_block_traces.rs index 5270bb9abd..cfd8f030c1 100644 --- a/examples/generate_block_traces.rs +++ b/examples/generate_block_traces.rs @@ -13,6 +13,7 @@ use std::io::BufWriter; use std::io::Write; use std::sync::Arc; use std::sync::Mutex; +use std::time::Instant; macro_rules! local_fill { ($left:expr, $right:expr, $fun:expr) => { @@ -100,7 +101,7 @@ async fn main() -> anyhow::Result<()> { println!("Found {txs} transactions."); let console_bar = Arc::new(ProgressBar::new(txs as u64)); - let elapsed = std::time::Duration::ZERO; + let start = Instant::now(); // Create the traces directory if it doesn't exist std::fs::create_dir_all("traces").expect("Failed to create traces directory"); @@ -176,6 +177,8 @@ async fn main() -> anyhow::Result<()> { } console_bar.finish_with_message("Finished all transactions."); + + let elapsed = start.elapsed(); println!( "Finished execution. Total CPU time: {:.6}s", elapsed.as_secs_f64() From 90790995282ada04236418636855ce49eb83c135 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Sun, 31 Mar 2024 12:54:25 +0200 Subject: [PATCH 11/87] feat: derive serde for OpCode, improve implementations (#1215) --- crates/interpreter/src/instructions/opcode.rs | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/crates/interpreter/src/instructions/opcode.rs b/crates/interpreter/src/instructions/opcode.rs index 687637b4bc..c935775a4e 100644 --- a/crates/interpreter/src/instructions/opcode.rs +++ b/crates/interpreter/src/instructions/opcode.rs @@ -437,10 +437,17 @@ opcodes! { /// /// This is always a valid opcode, as declared in the [`opcode`][self] module or the /// [`OPCODE_JUMPMAP`] constant. -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[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(); @@ -488,20 +495,6 @@ impl OpCode { pub const fn get(self) -> u8 { self.0 } - - #[inline] - #[deprecated(note = "use `new` instead")] - #[doc(hidden)] - pub const fn try_from_u8(opcode: u8) -> Option { - Self::new(opcode) - } - - #[inline] - #[deprecated(note = "use `get` instead")] - #[doc(hidden)] - pub const fn u8(self) -> u8 { - self.get() - } } #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] From d9d1a641196c3a4feab1f66c101be17d56390d56 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sun, 31 Mar 2024 13:43:59 +0200 Subject: [PATCH 12/87] chore(deps): bump alloy 0.7.0 (#1250) --- Cargo.lock | 26 ++++++++++++++++++++++++-- crates/primitives/Cargo.toml | 2 +- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ff5a78d1f..cad509e7b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,6 +49,28 @@ name = "alloy-primitives" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "600d34d8de81e23b6d909c094e23b3d357e01ca36b78a8c5424c501eedbe86f0" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more", + "hex-literal", + "itoa", + "k256", + "keccak-asm", + "proptest", + "rand", + "ruint", + "serde", + "tiny-keccak", +] + +[[package]] +name = "alloy-primitives" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99bbad0a6b588ef4aec1b5ddbbfdacd9ef04e00b979617765b03174318ee1f3a" dependencies = [ "alloy-rlp", "arbitrary", @@ -116,7 +138,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad09ec5853fa700d12d778ad224dcdec636af424d29fad84fb9a2f16a5b0ef09" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.6.4", "alloy-sol-macro", "const-hex", "serde", @@ -2365,7 +2387,7 @@ dependencies = [ name = "revm-primitives" version = "3.1.0" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.7.0", "auto_impl", "bitflags 2.5.0", "bitvec", diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index b50815fec2..65b31d2095 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.6", default-features = false, features = [ +alloy-primitives = { version = "0.7", default-features = false, features = [ "rlp", ] } hashbrown = "0.14" From b3220c64c0a542e0ef0f99e9bcf8798fc0cf64d5 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 1 Apr 2024 02:37:23 +0200 Subject: [PATCH 13/87] chore(deps): bump other alloy deps 0.7.0 (#1252) --- Cargo.lock | 61 +++++++++++++++++++-------------------- bins/revm-test/Cargo.toml | 4 +-- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cad509e7b4..0e05b742e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,28 +44,6 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" -[[package]] -name = "alloy-primitives" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "600d34d8de81e23b6d909c094e23b3d357e01ca36b78a8c5424c501eedbe86f0" -dependencies = [ - "alloy-rlp", - "bytes", - "cfg-if", - "const-hex", - "derive_more", - "hex-literal", - "itoa", - "k256", - "keccak-asm", - "proptest", - "rand", - "ruint", - "serde", - "tiny-keccak", -] - [[package]] name = "alloy-primitives" version = "0.7.0" @@ -116,12 +94,12 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86ec0a47740b20bc5613b8712d0d321d031c4efc58e9645af96085d5cccfc27" +checksum = "452d929748ac948a10481fff4123affead32c553cf362841c5103dd508bdfc16" dependencies = [ + "alloy-sol-macro-input", "const-hex", - "dunce", "heck 0.4.1", "indexmap", "proc-macro-error", @@ -132,13 +110,28 @@ dependencies = [ "tiny-keccak", ] +[[package]] +name = "alloy-sol-macro-input" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df64e094f6d2099339f9e82b5b38440b159757b6920878f28316243f8166c8d1" +dependencies = [ + "const-hex", + "dunce", + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.55", + "syn-solidity", +] + [[package]] name = "alloy-sol-types" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad09ec5853fa700d12d778ad224dcdec636af424d29fad84fb9a2f16a5b0ef09" +checksum = "43bc2d6dfc2a19fd56644494479510f98b1ee929e04cf0d4aa45e98baa3e545b" dependencies = [ - "alloy-primitives 0.6.4", + "alloy-primitives", "alloy-sol-macro", "const-hex", "serde", @@ -1396,6 +1389,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -2387,7 +2386,7 @@ dependencies = [ name = "revm-primitives" version = "3.1.0" dependencies = [ - "alloy-primitives 0.7.0", + "alloy-primitives", "auto_impl", "bitflags 2.5.0", "bitvec", @@ -3005,9 +3004,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3d0961cd53c23ea94eeec56ba940f636f6394788976e9f16ca5ee0aca7464a" +checksum = "4497156948bd342b52038035a6fa514a89626e37af9d2c52a5e8d8ebcc7ee479" dependencies = [ "paste", "proc-macro2", diff --git a/bins/revm-test/Cargo.toml b/bins/revm-test/Cargo.toml index d3cbcc6d3c..44559d50cf 100644 --- a/bins/revm-test/Cargo.toml +++ b/bins/revm-test/Cargo.toml @@ -9,8 +9,8 @@ bytes = "1.6" hex = "0.4" revm = { path = "../../crates/revm", version = "7.2.0",default-features=false } microbench = "0.5" -alloy-sol-macro = "0.6.4" -alloy-sol-types = "0.6.4" +alloy-sol-macro = "0.7.0" +alloy-sol-types = "0.7.0" regex = "1.10.4" eyre = "0.6.12" From c3f0503faee0f238b8f0675d2c6381bae8a94918 Mon Sep 17 00:00:00 2001 From: Justin Traglia <95511699+jtraglia@users.noreply.github.com> Date: Tue, 2 Apr 2024 04:53:55 -0500 Subject: [PATCH 14/87] nit: use uint macro & fix various small things (#1253) * nit: Use uint macro & fix various small things * Move MAX_POSITIVE_VALUE back to tests --- bins/revme/src/cmd/statetest/runner.rs | 8 +- crates/interpreter/src/gas/calc.rs | 2 +- crates/interpreter/src/instructions/i256.rs | 170 ++++++++---------- crates/interpreter/src/instructions/macros.rs | 4 +- .../src/interpreter/shared_memory.rs | 6 +- crates/primitives/src/bytecode.rs | 6 +- crates/revm/src/evm.rs | 4 +- crates/revm/src/frame.rs | 8 +- crates/revm/src/handler.rs | 12 +- 9 files changed, 97 insertions(+), 123 deletions(-) diff --git a/bins/revme/src/cmd/statetest/runner.rs b/bins/revme/src/cmd/statetest/runner.rs index d235c572fe..b62e20c306 100644 --- a/bins/revme/src/cmd/statetest/runner.rs +++ b/bins/revme/src/cmd/statetest/runner.rs @@ -48,7 +48,7 @@ pub enum TestErrorKind { got_exception: Option, }, #[error("Unexpected output: {got_output:?} but test expects:{expected_output:?}")] - UnexpecteOutput { + UnexpectedOutput { expected_output: Option, got_output: Option, }, @@ -79,7 +79,7 @@ fn skip_test(path: &Path) -> bool { | "RevertPrecompiledTouch_storage.json" | "RevertPrecompiledTouch.json" - // txbyte is of type 02 and we dont parse tx bytes for this test to fail. + // txbyte is of type 02 and we don't parse tx bytes for this test to fail. | "typeTwoBerlin.json" // Need to handle Test errors @@ -139,7 +139,7 @@ fn check_evm_execution( } }; - // if we expect exception revm should return error from execution. + // If we expect exception revm should return error from execution. // So we do not check logs and state root. // // Note that some tests that have exception and run tests from before state clear @@ -155,7 +155,7 @@ fn check_evm_execution( // check output if let Some((expected_output, output)) = expected_output.zip(result.output()) { if expected_output != output { - let kind = TestErrorKind::UnexpecteOutput { + let kind = TestErrorKind::UnexpectedOutput { expected_output: Some(expected_output.clone()), got_output: result.output().cloned(), }; diff --git a/crates/interpreter/src/gas/calc.rs b/crates/interpreter/src/gas/calc.rs index 092fff7c85..b7f91b1814 100644 --- a/crates/interpreter/src/gas/calc.rs +++ b/crates/interpreter/src/gas/calc.rs @@ -92,7 +92,7 @@ pub fn exp_cost(power: U256) -> Option { } else { // EIP-160: EXP cost increase let gas_byte = U256::from(if SPEC::enabled(SPURIOUS_DRAGON) { - 50u64 + 50 } else { 10 }); diff --git a/crates/interpreter/src/instructions/i256.rs b/crates/interpreter/src/instructions/i256.rs index eaccbab705..0067c6668e 100644 --- a/crates/interpreter/src/instructions/i256.rs +++ b/crates/interpreter/src/instructions/i256.rs @@ -126,53 +126,9 @@ pub fn i256_mod(mut first: U256, mut second: U256) -> U256 { mod tests { use super::*; use core::num::Wrapping; + use revm_primitives::uint; - const ZERO: U256 = U256::ZERO; - const ONE: U256 = U256::from_limbs([ - 0x0000000000000001, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - ]); - const TWO: U256 = U256::from_limbs([ - 0x0000000000000002, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - ]); - const THREE: U256 = U256::from_limbs([ - 0x0000000000000003, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - ]); - const FOUR: U256 = U256::from_limbs([ - 0x0000000000000004, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - ]); - - const NEG_ONE: U256 = U256::from_limbs([ - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - ]); - const NEG_TWO: U256 = U256::from_limbs([ - 0xfffffffffffffffe, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - ]); - const NEG_THREE: U256 = U256::from_limbs([ - 0xfffffffffffffffd, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - ]); - - const I256_MAX: U256 = U256::from_limbs([ + const MAX_POSITIVE_VALUE: U256 = U256::from_limbs([ 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, @@ -186,87 +142,101 @@ mod tests { assert_eq!(Wrapping(i8::MIN) / Wrapping(-1), Wrapping(i8::MIN)); assert_eq!(i8::MAX / -1, -i8::MAX); - // Now the same calculations based on i256 - let fifty = U256::from(50); - let one_hundred = U256::from(100); - - assert_eq!(i256_div(MIN_NEGATIVE_VALUE, NEG_ONE), MIN_NEGATIVE_VALUE); - assert_eq!(i256_div(MIN_NEGATIVE_VALUE, ONE), MIN_NEGATIVE_VALUE); - assert_eq!(i256_div(I256_MAX, ONE), I256_MAX); - assert_eq!(i256_div(I256_MAX, NEG_ONE), NEG_ONE * I256_MAX); - assert_eq!(i256_div(one_hundred, NEG_ONE), NEG_ONE * one_hundred); - assert_eq!(i256_div(one_hundred, TWO), fifty); + uint! { + assert_eq!(i256_div(MIN_NEGATIVE_VALUE, -1_U256), MIN_NEGATIVE_VALUE); + assert_eq!(i256_div(MIN_NEGATIVE_VALUE, 1_U256), MIN_NEGATIVE_VALUE); + assert_eq!(i256_div(MAX_POSITIVE_VALUE, 1_U256), MAX_POSITIVE_VALUE); + assert_eq!(i256_div(MAX_POSITIVE_VALUE, -1_U256), -1_U256 * MAX_POSITIVE_VALUE); + assert_eq!(i256_div(100_U256, -1_U256), -100_U256); + assert_eq!(i256_div(100_U256, 2_U256), 50_U256); + } } #[test] fn test_i256_sign() { - assert_eq!(i256_sign(&ZERO), Sign::Zero); - assert_eq!(i256_sign(&ONE), Sign::Plus); - assert_eq!(i256_sign(&MIN_NEGATIVE_VALUE), Sign::Minus); + uint! { + assert_eq!(i256_sign(&0_U256), Sign::Zero); + assert_eq!(i256_sign(&1_U256), Sign::Plus); + assert_eq!(i256_sign(&-1_U256), Sign::Minus); + assert_eq!(i256_sign(&MIN_NEGATIVE_VALUE), Sign::Minus); + assert_eq!(i256_sign(&MAX_POSITIVE_VALUE), Sign::Plus); + } } #[test] fn test_i256_sign_compl() { - let mut zero = ZERO; - let mut positive = ONE; - let mut negative = MIN_NEGATIVE_VALUE; - assert_eq!(i256_sign_compl(&mut zero), Sign::Zero); - assert_eq!(i256_sign_compl(&mut positive), Sign::Plus); - assert_eq!(i256_sign_compl(&mut negative), Sign::Minus); + uint! { + let mut zero = 0_U256; + let mut positive = 1_U256; + let mut negative = -1_U256; + assert_eq!(i256_sign_compl(&mut zero), Sign::Zero); + assert_eq!(i256_sign_compl(&mut positive), Sign::Plus); + assert_eq!(i256_sign_compl(&mut negative), Sign::Minus); + } } #[test] fn test_two_compl() { - assert_eq!(two_compl(ZERO), ZERO); - assert_eq!(two_compl(ONE), NEG_ONE); - assert_eq!(two_compl(NEG_ONE), ONE); - assert_eq!(two_compl(TWO), NEG_TWO); - assert_eq!(two_compl(NEG_TWO), TWO); + uint! { + assert_eq!(two_compl(0_U256), 0_U256); + assert_eq!(two_compl(1_U256), -1_U256); + assert_eq!(two_compl(-1_U256), 1_U256); + assert_eq!(two_compl(2_U256), -2_U256); + assert_eq!(two_compl(-2_U256), 2_U256); - // Two's complement of the min value is itself. - assert_eq!(two_compl(MIN_NEGATIVE_VALUE), MIN_NEGATIVE_VALUE); + // Two's complement of the min value is itself. + assert_eq!(two_compl(MIN_NEGATIVE_VALUE), MIN_NEGATIVE_VALUE); + } } #[test] fn test_two_compl_mut() { - let mut value = ONE; - two_compl_mut(&mut value); - assert_eq!(value, NEG_ONE); + uint! { + let mut value = 1_U256; + two_compl_mut(&mut value); + assert_eq!(value, -1_U256); + } } #[test] fn test_i256_cmp() { - assert_eq!(i256_cmp(&ONE, &TWO), Ordering::Less); - assert_eq!(i256_cmp(&TWO, &TWO), Ordering::Equal); - assert_eq!(i256_cmp(&THREE, &TWO), Ordering::Greater); - assert_eq!(i256_cmp(&NEG_ONE, &NEG_ONE), Ordering::Equal); - assert_eq!(i256_cmp(&NEG_ONE, &NEG_TWO), Ordering::Greater); - assert_eq!(i256_cmp(&NEG_ONE, &ZERO), Ordering::Less); - assert_eq!(i256_cmp(&NEG_TWO, &TWO), Ordering::Less); + uint! { + assert_eq!(i256_cmp(&1_U256, &2_U256), Ordering::Less); + assert_eq!(i256_cmp(&2_U256, &2_U256), Ordering::Equal); + assert_eq!(i256_cmp(&3_U256, &2_U256), Ordering::Greater); + assert_eq!(i256_cmp(&-1_U256, &-1_U256), Ordering::Equal); + assert_eq!(i256_cmp(&-1_U256, &-2_U256), Ordering::Greater); + assert_eq!(i256_cmp(&-1_U256, &0_U256), Ordering::Less); + assert_eq!(i256_cmp(&-2_U256, &2_U256), Ordering::Less); + } } #[test] fn test_i256_div() { - assert_eq!(i256_div(ONE, ZERO), ZERO); - assert_eq!(i256_div(ZERO, ONE), ZERO); - assert_eq!(i256_div(ZERO, NEG_ONE), ZERO); - assert_eq!(i256_div(MIN_NEGATIVE_VALUE, ONE), MIN_NEGATIVE_VALUE); - assert_eq!(i256_div(FOUR, TWO), TWO); - assert_eq!(i256_div(MIN_NEGATIVE_VALUE, MIN_NEGATIVE_VALUE), ONE); - assert_eq!(i256_div(TWO, NEG_ONE), NEG_TWO); - assert_eq!(i256_div(NEG_TWO, NEG_ONE), TWO); + uint! { + assert_eq!(i256_div(1_U256, 0_U256), 0_U256); + assert_eq!(i256_div(0_U256, 1_U256), 0_U256); + assert_eq!(i256_div(0_U256, -1_U256), 0_U256); + assert_eq!(i256_div(MIN_NEGATIVE_VALUE, 1_U256), MIN_NEGATIVE_VALUE); + assert_eq!(i256_div(4_U256, 2_U256), 2_U256); + assert_eq!(i256_div(MIN_NEGATIVE_VALUE, MIN_NEGATIVE_VALUE), 1_U256); + assert_eq!(i256_div(2_U256, -1_U256), -2_U256); + assert_eq!(i256_div(-2_U256, -1_U256), 2_U256); + } } #[test] fn test_i256_mod() { - assert_eq!(i256_mod(ZERO, ONE), ZERO); - assert_eq!(i256_mod(ONE, ZERO), ZERO); - assert_eq!(i256_mod(FOUR, TWO), ZERO); - assert_eq!(i256_mod(THREE, TWO), ONE); - assert_eq!(i256_mod(MIN_NEGATIVE_VALUE, ONE), ZERO); - assert_eq!(i256_mod(TWO, TWO), ZERO); - assert_eq!(i256_mod(TWO, THREE), TWO); - assert_eq!(i256_mod(NEG_TWO, THREE), NEG_TWO); - assert_eq!(i256_mod(TWO, NEG_THREE), TWO); - assert_eq!(i256_mod(NEG_TWO, NEG_THREE), NEG_TWO); + uint! { + assert_eq!(i256_mod(0_U256, 1_U256), 0_U256); + assert_eq!(i256_mod(1_U256, 0_U256), 0_U256); + assert_eq!(i256_mod(4_U256, 2_U256), 0_U256); + assert_eq!(i256_mod(3_U256, 2_U256), 1_U256); + assert_eq!(i256_mod(MIN_NEGATIVE_VALUE, 1_U256), 0_U256); + assert_eq!(i256_mod(2_U256, 2_U256), 0_U256); + assert_eq!(i256_mod(2_U256, 3_U256), 2_U256); + assert_eq!(i256_mod(-2_U256, 3_U256), -2_U256); + assert_eq!(i256_mod(2_U256, -3_U256), 2_U256); + assert_eq!(i256_mod(-2_U256, -3_U256), -2_U256); + } } } diff --git a/crates/interpreter/src/instructions/macros.rs b/crates/interpreter/src/instructions/macros.rs index 861489d38f..b194f36ac9 100644 --- a/crates/interpreter/src/instructions/macros.rs +++ b/crates/interpreter/src/instructions/macros.rs @@ -1,4 +1,4 @@ -//! Utility macros to help implementementing opcode instruction functions. +//! Utility macros to help implementing opcode instruction functions. /// Fails the instruction if the current call is static. #[macro_export] @@ -78,7 +78,7 @@ macro_rules! resize_memory { return $ret; } - // Gas is calculated in evm words (256bits). + // Gas is calculated in evm words (256 bits). let words_num = rounded_size / 32; if !$interp .gas diff --git a/crates/interpreter/src/interpreter/shared_memory.rs b/crates/interpreter/src/interpreter/shared_memory.rs index c49cc319ed..433e24abb0 100644 --- a/crates/interpreter/src/interpreter/shared_memory.rs +++ b/crates/interpreter/src/interpreter/shared_memory.rs @@ -303,7 +303,8 @@ impl SharedMemory { } } -/// Rounds up `x` to the closest multiple of 32. If `x % 32 == 0` then `x` is returned. +/// 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. #[inline] pub fn next_multiple_of_32(x: usize) -> usize { let r = x.bitand(31).not().wrapping_add(1).bitand(31); @@ -330,6 +331,9 @@ mod tests { 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)); } #[test] diff --git a/crates/primitives/src/bytecode.rs b/crates/primitives/src/bytecode.rs index e13040bd43..8fc436a982 100644 --- a/crates/primitives/src/bytecode.rs +++ b/crates/primitives/src/bytecode.rs @@ -105,12 +105,12 @@ impl Bytecode { } } - /// Create new checked bytecode + /// Create new checked bytecode. /// /// # Safety /// - /// Bytecode need to end with STOP (0x00) opcode as checked bytecode assumes - /// that it is safe to iterate over bytecode without checking lengths + /// 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 { bytecode, diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index d9307cccba..76bf4b633c 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -217,7 +217,7 @@ impl Evm<'_, EXT, DB> { &mut self, first_frame: Frame, ) -> Result> { - // take instruction talbe + // take instruction table let table = self .handler .take_instruction_table() @@ -265,7 +265,7 @@ impl Evm<'_, EXT, DB> { 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 its interacting with Host. + // This error is set From Interpreter when it's interacting with Host. core::mem::replace(&mut self.context.evm.error, Ok(()))?; // take shared memory back. shared_memory = interpreter.take_memory(); diff --git a/crates/revm/src/frame.rs b/crates/revm/src/frame.rs index 3a7ade26e6..a48fd3c14c 100644 --- a/crates/revm/src/frame.rs +++ b/crates/revm/src/frame.rs @@ -12,7 +12,7 @@ use std::boxed::Box; pub struct CallFrame { /// Call frame has return memory range where output will be stored. pub return_memory_range: Range, - /// Frame data + /// Frame data. pub frame_data: FrameData, } @@ -20,15 +20,15 @@ pub struct CallFrame { pub struct CreateFrame { /// Create frame has a created address. pub created_address: Address, - /// Frame data + /// Frame data. pub frame_data: FrameData, } #[derive(Debug)] pub struct FrameData { - /// Journal checkpoint + /// Journal checkpoint. pub checkpoint: JournalCheckpoint, - /// Interpreter + /// Interpreter. pub interpreter: Interpreter, } diff --git a/crates/revm/src/handler.rs b/crates/revm/src/handler.rs index 6cd2e5b244..a6dfde551e 100644 --- a/crates/revm/src/handler.rs +++ b/crates/revm/src/handler.rs @@ -21,7 +21,7 @@ use self::register::{HandleRegister, HandleRegisterBox}; /// sections of the code. This allows nice integration of different chains or /// to disable some mainnet behavior. pub struct Handler<'a, H: Host + 'a, EXT, DB: Database> { - /// Handler config. + /// Handler configuration. pub cfg: HandlerCfg, /// Instruction table type. pub instruction_table: Option>, @@ -29,9 +29,9 @@ pub struct Handler<'a, H: Host + 'a, EXT, DB: Database> { pub registers: Vec>, /// Validity handles. pub validation: ValidationHandler<'a, EXT, DB>, - /// Pre execution handle + /// Pre execution handle. pub pre_execution: PreExecutionHandler<'a, EXT, DB>, - /// post Execution handle + /// Post Execution handle. pub post_execution: PostExecutionHandler<'a, EXT, DB>, /// Execution loop that handles frames. pub execution: ExecutionHandler<'a, EXT, DB>, @@ -40,7 +40,7 @@ pub struct Handler<'a, H: Host + 'a, EXT, DB: Database> { impl<'a, EXT, DB: Database> EvmHandler<'a, EXT, DB> { /// Created new Handler with given configuration. /// - /// Internaly it calls `mainnet_with_spec` with the given spec id. + /// Internally it calls `mainnet_with_spec` with the given spec id. /// Or `optimism_with_spec` if the optimism feature is enabled and `cfg.is_optimism` is set. pub fn new(cfg: HandlerCfg) -> Self { cfg_if::cfg_if! { @@ -85,7 +85,7 @@ impl<'a, EXT, DB: Database> EvmHandler<'a, EXT, DB> { handler } - /// Optimism with spec. Similar to [`Self::mainnet_with_spec`] + /// Optimism with spec. Similar to [`Self::mainnet_with_spec`]. #[cfg(feature = "optimism")] pub fn optimism_with_spec(spec_id: SpecId) -> Self { spec_to_generic!(spec_id, Self::optimism::()) @@ -185,7 +185,7 @@ impl<'a, EXT, DB: Database> EvmHandler<'a, EXT, DB> { let registers = core::mem::take(&mut self.registers); // register for optimism is added as a register, so we need to create mainnet handler here. let mut handler = Handler::mainnet_with_spec(spec_id); - // apply all registers to default handeler and raw mainnet instruction table. + // apply all registers to default handler and raw mainnet instruction table. for register in registers { handler.append_handler_register(register) } From 52f1f01d0dc65ad3b3d85b835a7ee439ad40e800 Mon Sep 17 00:00:00 2001 From: Justin Traglia <95511699+jtraglia@users.noreply.github.com> Date: Tue, 2 Apr 2024 13:55:46 -0500 Subject: [PATCH 15/87] feat: add tests for shift instructions (#1254) * feat: add tests for shift instructions * Use LatestSpec instead of CancunSpec * Run cargo fmt * Use parans instead of brackets * Simplify host/interpreter initialization * Remove unused imports * Remove test case comments * Use U256 types --- bins/revm-test/src/bin/analysis.rs | 2 +- .../interpreter/src/instructions/bitwise.rs | 285 +++++++++++++++++- 2 files changed, 284 insertions(+), 3 deletions(-) diff --git a/bins/revm-test/src/bin/analysis.rs b/bins/revm-test/src/bin/analysis.rs index 49fdbc57a7..b8557b6926 100644 --- a/bins/revm-test/src/bin/analysis.rs +++ b/bins/revm-test/src/bin/analysis.rs @@ -25,7 +25,7 @@ fn main() { .with_db(BenchmarkDB::new_bytecode(bytecode_raw)) .build(); - // just to spead up processor. + // Just to warm up the processor. for _ in 0..10000 { let _ = evm.transact().unwrap(); } diff --git a/crates/interpreter/src/instructions/bitwise.rs b/crates/interpreter/src/instructions/bitwise.rs index 3f49dc57eb..d832964214 100644 --- a/crates/interpreter/src/instructions/bitwise.rs +++ b/crates/interpreter/src/instructions/bitwise.rs @@ -5,6 +5,7 @@ use crate::{ Host, Interpreter, }; use core::cmp::Ordering; +use revm_primitives::uint; pub fn lt(interpreter: &mut Interpreter, _host: &mut H) { gas!(interpreter, gas::VERYLOW); @@ -103,7 +104,11 @@ pub fn sar(interpreter: &mut Interpreter, _host: &mut H) { let value_sign = i256_sign_compl(op2); - *op2 = if value_sign == Sign::Zero || op1 >= U256::from(256) { + // 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, @@ -111,7 +116,8 @@ pub fn sar(interpreter: &mut Interpreter, _host: &mut H) { Sign::Minus => U256::MAX, } } else { - const ONE: U256 = U256::from_limbs([1, 0, 0, 0]); + 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), @@ -119,3 +125,278 @@ pub fn sar(interpreter: &mut Interpreter, _host: &mut H) { } }; } + +#[cfg(test)] +mod tests { + use crate::instructions::bitwise::{sar, shl, shr}; + use crate::{Contract, DummyHost, Interpreter}; + use revm_primitives::{uint, Env, LatestSpec, U256}; + + #[test] + fn test_shift_left() { + let mut host = DummyHost::new(Env::default()); + let mut interpreter = Interpreter::new(Contract::default(), u64::MAX, false); + + struct TestCase { + value: U256, + shift: U256, + expected: U256, + } + + uint! { + let test_cases = [ + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0x00_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0x01_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000002_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0xff_U256, + expected: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0x0100_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0x0101_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x00_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x01_U256, + expected: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0xff_U256, + expected: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x0100_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x01_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x01_U256, + expected: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe_U256, + }, + ]; + } + + for test in test_cases { + host.clear(); + push!(interpreter, test.value); + push!(interpreter, test.shift); + shl::(&mut interpreter, &mut host); + pop!(interpreter, res); + assert_eq!(res, test.expected); + } + } + + #[test] + fn test_logical_shift_right() { + let mut host = DummyHost::new(Env::default()); + let mut interpreter = Interpreter::new(Contract::default(), u64::MAX, false); + + struct TestCase { + value: U256, + shift: U256, + expected: U256, + } + + uint! { + let test_cases = [ + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0x00_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0x01_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x01_U256, + expected: 0x4000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0xff_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + }, + TestCase { + value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x0100_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x0101_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x00_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x01_U256, + expected: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0xff_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x0100_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x01_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + ]; + } + + for test in test_cases { + host.clear(); + push!(interpreter, test.value); + push!(interpreter, test.shift); + shr::(&mut interpreter, &mut host); + pop!(interpreter, res); + assert_eq!(res, test.expected); + } + } + + #[test] + fn test_arithmetic_shift_right() { + let mut host = DummyHost::new(Env::default()); + let mut interpreter = Interpreter::new(Contract::default(), u64::MAX, false); + + struct TestCase { + value: U256, + shift: U256, + expected: U256, + } + + uint! { + let test_cases = [ + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0x00_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + shift: 0x01_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x01_U256, + expected: 0xc000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0xff_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x0100_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0x8000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x0101_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x00_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x01_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0xff_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x0100_U256, + expected: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + }, + TestCase { + value: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0x01_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x4000000000000000000000000000000000000000000000000000000000000000_U256, + shift: 0xfe_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + }, + TestCase { + value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0xf8_U256, + expected: 0x000000000000000000000000000000000000000000000000000000000000007f_U256, + }, + TestCase { + value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0xfe_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000001_U256, + }, + TestCase { + value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0xff_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + TestCase { + value: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_U256, + shift: 0x0100_U256, + expected: 0x0000000000000000000000000000000000000000000000000000000000000000_U256, + }, + ]; + } + + for test in test_cases { + host.clear(); + push!(interpreter, test.value); + push!(interpreter, test.shift); + sar::(&mut interpreter, &mut host); + pop!(interpreter, res); + assert_eq!(res, test.expected); + } + } +} From 4a8c0bfcd016f3ac7f29ee799b7b2dbcdd41b6e7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 21:05:20 +0200 Subject: [PATCH 16/87] chore: release (#1231) Signed-off-by: GitHub Action Co-authored-by: GitHub Action --- Cargo.lock | 10 +++++----- bins/revm-test/Cargo.toml | 2 +- bins/revme/CHANGELOG.md | 8 ++++++++ bins/revme/Cargo.toml | 4 ++-- crates/interpreter/CHANGELOG.md | 14 ++++++++++++++ crates/interpreter/Cargo.toml | 4 ++-- crates/precompile/CHANGELOG.md | 10 ++++++++++ crates/precompile/Cargo.toml | 4 ++-- crates/primitives/CHANGELOG.md | 9 +++++++++ crates/primitives/Cargo.toml | 2 +- crates/revm/CHANGELOG.md | 18 ++++++++++++++++++ crates/revm/Cargo.toml | 6 +++--- 12 files changed, 75 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0e05b742e2..efc16bdbec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2339,7 +2339,7 @@ dependencies = [ [[package]] name = "revm" -version = "7.2.0" +version = "8.0.0" dependencies = [ "anyhow", "auto_impl", @@ -2359,7 +2359,7 @@ dependencies = [ [[package]] name = "revm-interpreter" -version = "3.4.0" +version = "4.0.0" dependencies = [ "revm-primitives", "serde", @@ -2367,7 +2367,7 @@ dependencies = [ [[package]] name = "revm-precompile" -version = "5.1.0" +version = "6.0.0" dependencies = [ "aurora-engine-modexp", "c-kzg", @@ -2384,7 +2384,7 @@ dependencies = [ [[package]] name = "revm-primitives" -version = "3.1.0" +version = "3.1.1" dependencies = [ "alloy-primitives", "auto_impl", @@ -2417,7 +2417,7 @@ dependencies = [ [[package]] name = "revme" -version = "0.3.1" +version = "0.4.0" dependencies = [ "alloy-rlp", "hash-db", diff --git a/bins/revm-test/Cargo.toml b/bins/revm-test/Cargo.toml index 44559d50cf..6034e26f1c 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 = "7.2.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/revme/CHANGELOG.md b/bins/revme/CHANGELOG.md index ea97533f20..34abf0043d 100644 --- a/bins/revme/CHANGELOG.md +++ b/bins/revme/CHANGELOG.md @@ -6,6 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.4.0](https://github.com/bluealloy/revm/compare/revme-v0.3.1...revme-v0.4.0) - 2024-04-02 + +### Added +- [**breaking**] TracerEip3155 optionally traces memory ([#1234](https://github.com/bluealloy/revm/pull/1234)) + +### Other +- use uint macro & fix various small things ([#1253](https://github.com/bluealloy/revm/pull/1253)) + ## [0.3.1](https://github.com/bluealloy/revm/compare/revme-v0.3.0...revme-v0.3.1) - 2024-03-19 ### Other diff --git a/bins/revme/Cargo.toml b/bins/revme/Cargo.toml index 7caead93b0..95290714c3 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.3.1" +version = "0.4.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 = "7.2.0", default-features = false, features = [ +revm = { path = "../../crates/revm", version = "8.0.0", default-features = false, features = [ "ethersdb", "std", "serde-json", diff --git a/crates/interpreter/CHANGELOG.md b/crates/interpreter/CHANGELOG.md index 8647c3585b..97303ef63a 100644 --- a/crates/interpreter/CHANGELOG.md +++ b/crates/interpreter/CHANGELOG.md @@ -6,6 +6,20 @@ 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-interpreter-v3.4.0...revm-interpreter-v4.0.0) - 2024-04-02 + +### Added +- add tests for shift instructions ([#1254](https://github.com/bluealloy/revm/pull/1254)) +- derive serde for OpCode, improve implementations ([#1215](https://github.com/bluealloy/revm/pull/1215)) +- *(interpreter)* expose mutable access methods on stack and memory ([#1219](https://github.com/bluealloy/revm/pull/1219)) + +### Other +- use uint macro & fix various small things ([#1253](https://github.com/bluealloy/revm/pull/1253)) +- move div by zero check from smod to i256_mod ([#1248](https://github.com/bluealloy/revm/pull/1248)) +- *(interpreter)* unbox contract field ([#1228](https://github.com/bluealloy/revm/pull/1228)) +- *(interpreter)* keep track of remaining gas rather than spent ([#1221](https://github.com/bluealloy/revm/pull/1221)) +- *(interpreter)* don't run signextend with 31 too ([#1222](https://github.com/bluealloy/revm/pull/1222)) + ## [3.4.0](https://github.com/bluealloy/revm/compare/revm-interpreter-v3.3.0...revm-interpreter-v3.4.0) - 2024-03-19 ### Added diff --git a/crates/interpreter/Cargo.toml b/crates/interpreter/Cargo.toml index 945314e874..e2bc35ffe1 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 = "3.4.0" +version = "4.0.0" readme = "../../README.md" [package.metadata.docs.rs] @@ -14,7 +14,7 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -revm-primitives = { path = "../primitives", version = "3.1.0", default-features = false } +revm-primitives = { path = "../primitives", version = "3.1.1", default-features = false } # optional serde = { version = "1.0", default-features = false, features = [ diff --git a/crates/precompile/CHANGELOG.md b/crates/precompile/CHANGELOG.md index 9a23e04141..008c66f604 100644 --- a/crates/precompile/CHANGELOG.md +++ b/crates/precompile/CHANGELOG.md @@ -6,6 +6,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [6.0.0](https://github.com/bluealloy/revm/compare/revm-precompile-v5.1.0...revm-precompile-v6.0.0) - 2024-04-02 + +### Fixed +- update/enable bn128 tests ([#1242](https://github.com/bluealloy/revm/pull/1242)) +- use correct bn128 mul input length ([#1238](https://github.com/bluealloy/revm/pull/1238)) +- use correct rand package for thread_rng ([#1233](https://github.com/bluealloy/revm/pull/1233)) + +### Other +- remove unnecessary call to into_u256() for bn128 add ([#1239](https://github.com/bluealloy/revm/pull/1239)) + ## [5.1.0](https://github.com/bluealloy/revm/compare/revm-precompile-v5.0.0...revm-precompile-v5.1.0) - 2024-03-19 ### Added diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index c89c82acfc..7690195c9a 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -6,14 +6,14 @@ keywords = ["no_std", "ethereum", "evm", "revm", "precompiles"] license = "MIT" name = "revm-precompile" repository = "https://github.com/bluealloy/revm" -version = "5.1.0" +version = "6.0.0" [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -revm-primitives = { path = "../primitives", version = "3.1.0", default-features = false } +revm-primitives = { path = "../primitives", version = "3.1.1", 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 626ef9d6da..79148d55ba 100644 --- a/crates/primitives/CHANGELOG.md +++ b/crates/primitives/CHANGELOG.md @@ -6,6 +6,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [3.1.1](https://github.com/bluealloy/revm/compare/revm-primitives-v3.1.0...revm-primitives-v3.1.1) - 2024-04-02 + +### Fixed +- fix eip3155 summary gas_used bug and add fork name ([#1216](https://github.com/bluealloy/revm/pull/1216)) + +### Other +- use uint macro & fix various small things ([#1253](https://github.com/bluealloy/revm/pull/1253)) +- *(deps)* bump alloy 0.7.0 ([#1250](https://github.com/bluealloy/revm/pull/1250)) + ## [3.1.0](https://github.com/bluealloy/revm/compare/revm-primitives-v3.0.0...revm-primitives-v3.1.0) - 2024-03-19 ### Added diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 65b31d2095..e3ef145d2b 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.0" +version = "3.1.1" readme = "../../README.md" # Don't need to run build script outside of this repo diff --git a/crates/revm/CHANGELOG.md b/crates/revm/CHANGELOG.md index 090b67cb26..1b01a63387 100644 --- a/crates/revm/CHANGELOG.md +++ b/crates/revm/CHANGELOG.md @@ -6,6 +6,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [8.0.0](https://github.com/bluealloy/revm/compare/revm-v7.2.0...revm-v8.0.0) - 2024-04-02 + +### Added +- [**breaking**] TracerEip3155 optionally traces memory ([#1234](https://github.com/bluealloy/revm/pull/1234)) + +### Fixed +- *(TracerEip3155)* clear Inspector data after transaction. ([#1230](https://github.com/bluealloy/revm/pull/1230)) +- *(GasInspector)* calculate correct remaining gas after call return ([#1236](https://github.com/bluealloy/revm/pull/1236)) +- fix eip3155 summary gas_used bug and add fork name ([#1216](https://github.com/bluealloy/revm/pull/1216)) + +### Other +- use uint macro & fix various small things ([#1253](https://github.com/bluealloy/revm/pull/1253)) +- *(deps)* bump tokio from 1.36.0 to 1.37.0 ([#1244](https://github.com/bluealloy/revm/pull/1244)) +- *(interpreter)* unbox contract field ([#1228](https://github.com/bluealloy/revm/pull/1228)) +- *(primitives)* kzg intro ([#1209](https://github.com/bluealloy/revm/pull/1209)) +- *(interpreter)* keep track of remaining gas rather than spent ([#1221](https://github.com/bluealloy/revm/pull/1221)) +- Improve `EthersDB` ([#1208](https://github.com/bluealloy/revm/pull/1208)) + ## [7.2.0](https://github.com/bluealloy/revm/compare/revm-v7.1.0...revm-v7.2.0) - 2024-03-19 ### Added diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index 4434ba0a08..856bc89294 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 = "7.2.0" +version = "8.0.0" readme = "../../README.md" [package.metadata.docs.rs] @@ -15,8 +15,8 @@ rustdoc-args = ["--cfg", "docsrs"] [dependencies] # revm -revm-interpreter = { path = "../interpreter", version = "3.4.0", default-features = false } -revm-precompile = { path = "../precompile", version = "5.1.0", default-features = false } +revm-interpreter = { path = "../interpreter", version = "4.0.0", default-features = false } +revm-precompile = { path = "../precompile", version = "6.0.0", default-features = false } # misc auto_impl = { version = "1.2", default-features = false } From 2e2babcfe7e40a0d01ec2096288f2733a7aa51c9 Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 2 Apr 2024 21:17:11 +0200 Subject: [PATCH 17/87] chore: main CHANGELOG, tag v35 (#1255) --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d214110e6..6d60f59271 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ Because this is workspace with multi libraries, tags will be simplified, and with this document you can match version of project with git tag. +# v35 tag +date: 02.04.2024 + +Small release. Alloy bump. Small refactors and deprecated functions removed. + +revme: 0.3.1 -> 0.4.0 (✓ API compatible changes) +revm: 7.2.0 -> 8.0.0 (⚠️ API breaking changes) +revm-interpreter: 3.4.0 -> 4.0.0 (⚠️ API breaking changes) +revm-primitives: 3.1.0 -> 3.1.1 (✓ API compatible changes) +revm-precompile: 5.1.0 -> 6.0.0 (⚠️ API breaking changes) +revm-test: 0.1.0 + # v34 tag date: 20.03.2024 From 1640b8f6989d0d4a19dfeb343e7967d501f6e195 Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 2 Apr 2024 21:30:23 +0200 Subject: [PATCH 18/87] chore: simple publish script (#1256) --- publish.sh | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100755 publish.sh diff --git a/publish.sh b/publish.sh new file mode 100755 index 0000000000..ce3c389cab --- /dev/null +++ b/publish.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +cargo publish --package revm-primitives +cargo publish --package revm-precompiles +cargo publish --package revm-interpreter +cargo publish --package revm +cargo publish --package revme + +echo "All crates published" From 223f6cd0b7bbb5b65df3f84021e101f2883af30a Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 2 Apr 2024 22:08:49 +0200 Subject: [PATCH 19/87] 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 ce3c389cab..b6944ae0f1 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 20/87] 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 fff18bb848..6caecee479 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 583299d58c..2d76727951 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 d832964214..586af76ce3 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 61a132e940..26333b77a7 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 7357adf4f3..b19d0dfc01 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 3156c9a75b..05a7a20334 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 230bb39b37..1b0c399559 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 264c4c61c7..6ee2d88f93 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 c935775a4e..8896c9da27 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 14d9e35238..5267687591 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 55109d8004..be81fb3116 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 2a1e99a377..4ee51db756 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 ba5fb8e117..0cf496a480 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 21/87] 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 efc16bdbec..50451980ac 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 7690195c9a..7284430978 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 22/87] 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 01598cc159..51739b1057 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 b7f91b1814..dcc949c008 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 2d76727951..8d1e512773 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 b19d0dfc01..cd5d735ef7 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 05a7a20334..803d0e6235 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 4ee51db756..cc9184ef47 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 6d75e25c44..c976702839 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 dc1514ea8b..ba79aabe4b 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 29c441f135..176e0e8282 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 fe6ee94cbb..600d6709d0 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 23/87] 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 cc9184ef47..4da1b58df3 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 24/87] 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 98a4d5679b..16ffe8a2f2 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 76bf4b633c..239aa64eee 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 ba79aabe4b..f5c0eb2964 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 a0b81a0dc0..6230b882fc 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 25/87] 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 50451980ac..88b5b1e04d 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 856bc89294..73c7c34fe4 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 f891358034..bcb3aa463c 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 0000000000..a9541991d9 --- /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 26/87] 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 7980f087a0..5e9c14fb98 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 ebeafb20a1..5951f3cdd7 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 27/87] 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 ed1d42fa7c..1e21cc7a66 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 28/87] 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 94f3a6c9db..7d1e217b1a 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 29/87] 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 26333b77a7..7e0df53093 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 cd5d735ef7..f506904350 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 6ee2d88f93..73dd4126ae 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 be81fb3116..25cb8dd69a 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 2b2c9b6d7f..a15b1e9cba 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 239aa64eee..3e627d0ea7 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 30/87] 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 8896c9da27..58aea3172e 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 31/87] 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 88b5b1e04d..d1addf1074 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 e3ef145d2b..7542c9298b 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 32/87] 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 c976702839..e106e8fd79 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 e69de29bb2..0000000000 diff --git a/crates/revm/src/frame/result.rs b/crates/revm/src/frame/result.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/documentation/src/SUMMARY.md b/documentation/src/SUMMARY.md index 05a9255851..d40b1b2b61 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 bc058e5a1d..45d57594ef 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 6bd7bcc1e9..accd1be6cc 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 33/87] 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 d1addf1074..d008a35c85 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 6034e26f1c..f26c4e7882 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 b8557b6926..40bbcf39c4 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 3734b69bd9..ec4d419a35 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 0000000000..9bc8a92e15 --- /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 b62e20c306..f2a58b6115 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 e2bc35ffe1..e828fb0719 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 0000000000..ef786cd662 --- /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 51739b1057..94c440f404 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 dcc949c008..18d0fd70bf 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 ed3c7aa38a..9475e3b33a 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 6caecee479..49ffbd02a6 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 519d3e06ee..4a069bfa63 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 550fab19c3..0000000000 --- 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 13e250ee3d..9e0f6e1264 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 ae56015699..7f11f93f4d 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 0000000000..4d3924be95 --- /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 0000000000..ae8b9ed689 --- /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 7e0df53093..02e2de7d28 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 0000000000..1475d24c41 --- /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 f506904350..77fdf0df20 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 1b0c399559..ce934d492f 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 0067c6668e..d806eacfb8 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 b194f36ac9..a50dddfcb4 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 73dd4126ae..e5bdde911c 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 5267687591..fa6c1be91c 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 25cb8dd69a..a5cec5368f 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 0000000000..55b1212771 --- /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 4da1b58df3..6d0b6320ef 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 4b363a84bc..bc2d96d2f5 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 a5896cc865..5959c7cfed 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 433e24abb0..3ee25bf697 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 a15b1e9cba..44dbb48a64 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 0000000000..a6a3aa216b --- /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 0000000000..5f9cb32abf --- /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 0000000000..6db951831a --- /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 0000000000..a5ce043c11 --- /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 0000000000..031e11803f --- /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 c70c25cd91..7d749fb9b1 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 0000000000..401c7c378e --- /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 0000000000..d593d9a7fa --- /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 0000000000..21b5f80230 --- /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 0000000000..aa31614039 --- /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 0000000000..4d78c6442b --- /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 0000000000..0e07dd4823 --- /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 0000000000..684a03c852 --- /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 0000000000..497cbd18f6 --- /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 0000000000..36505b9187 --- /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 0000000000..4a160d1954 --- /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 0000000000..8ca3ca3cf6 --- /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 0000000000..275c6a9cf3 --- /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 0000000000..d150cbac85 --- /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 0000000000..8e10968c99 --- /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 0000000000..eb96abcffe --- /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 0000000000..8f6595f4cb --- /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 0000000000..c5a120807e --- /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 0000000000..37748c14ee --- /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 0000000000..b394324a18 --- /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 0000000000..2940c81713 --- /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 0000000000..0d8513f604 --- /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 0000000000..38c7abe293 --- /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 0000000000..928b771d26 --- /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 0000000000..0afe03ba0a --- /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 0000000000..698bf85665 --- /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 0000000000..17cb8a34f9 --- /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 0000000000..6a83b1a98c --- /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 0000000000..2d046aa7a7 --- /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 0000000000..be7ee59297 --- /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 0000000000..60252e7d33 --- /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 0000000000..1ae65f3ec4 --- /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 0000000000..8f2d5863d0 --- /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 0000000000..b119e62e70 --- /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 0000000000..1eab63f429 --- /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 0000000000..adf48163a2 --- /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 0000000000..17c521a9e8 --- /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 0000000000..5bb7cf0c34 --- /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 0000000000..8fc104acfe --- /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 0000000000..1c77f0921a --- /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 0000000000..893f226fee --- /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 0000000000..663059882f --- /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 0000000000..c91d4ac595 --- /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 0000000000..fa9d847516 --- /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 0000000000..9f2cc36649 --- /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 0000000000..a82c85ba26 --- /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 0000000000..ae4289f8b8 --- /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 0000000000..4c15cc70d3 --- /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 0000000000..6309192917 --- /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 0000000000..fe3b175a7e --- /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 0000000000..774f82caf0 --- /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 0000000000..f753f692e9 --- /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 0000000000..f934ccab93 --- /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 0000000000..19479cd60b --- /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 0000000000..14724fd6af --- /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 0000000000..3da4711525 --- /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 0000000000..9cc794d5c0 --- /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 0000000000..4fab55d449 --- /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 0000000000..b9aba3a0c5 --- /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 0000000000..b79ea57bb5 --- /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 0000000000..05c74681b7 --- /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 0000000000..656812192b --- /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 0000000000..646333188a --- /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 0000000000..6d00623aae --- /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 0000000000..69b66da04c --- /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 0000000000..3155e80573 --- /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 0000000000..29a4384403 --- /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 0000000000..0fd093f540 --- /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 0000000000..3627dd3474 --- /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 0000000000..4e0e76d213 --- /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 0000000000..972572398a --- /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 0000000000..cdc6a5873a --- /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 0000000000..427148d464 --- /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 0000000000..fae2f6081e --- /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 0000000000..0cce8488cd --- /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 0000000000..bc17fd15a5 --- /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 0000000000..cd78ff8f8f --- /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 0000000000..b0eda869ce --- /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 0000000000..a6f5af7c67 --- /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 0000000000..85ac3816a7 --- /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 0000000000..e34d293dd3 --- /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 0000000000..830e71fe4b --- /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 0000000000..99fddf702c --- /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 0000000000..831f357963 --- /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 0000000000..e2b99000ae --- /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 0000000000..62c5fb2b5b --- /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 0000000000..b7f9d445bb --- /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 0000000000..cc0c419203 --- /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 0000000000..dcfe6faa9d --- /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 0000000000..a4d3aea555 --- /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 0000000000..1b7a0d95cc --- /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 0000000000..4554f84bfa --- /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 0000000000..7cfccdeaf7 --- /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 0000000000..8ac969b806 --- /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 0000000000..4731686f08 --- /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 0000000000..af4bc13d39 --- /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 0000000000..cd30b9ffd2 --- /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 0000000000..d83e86a0b5 --- /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 0000000000..dda6c5a12c --- /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 0000000000..95903fbe84 --- /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 0000000000..825c7b9a46 --- /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 0000000000..0c0d2608fa --- /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 0000000000..7d6e133833 --- /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 0000000000..7c545a45b6 --- /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 0000000000..768020dcae --- /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 0000000000..276041f4b2 --- /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 0000000000..e44554ec1b --- /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 0000000000..035174da52 --- /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 0000000000..fe8ac098b6 --- /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 0000000000..485b898784 --- /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 0000000000..9c7d8d3bde --- /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 0000000000..0e11c22b9b --- /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 0000000000..a55f420058 --- /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 0000000000..4f60ba26ec --- /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 0000000000..2f33a251b2 --- /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 0000000000..84bfc347ff --- /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 48b566bb92..057bba74d4 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 fd34bd6358..aa3ffadfb1 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 8fc436a982..538a57af44 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 0000000000..67580c1577 --- /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 0000000000..3759372b8a --- /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 0000000000..d2d2eb555d --- /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 0000000000..bd7a33d7b7 --- /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 0000000000..84db61f019 --- /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 0000000000..18949f0aa6 --- /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 0000000000..af86178775 --- /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 e0db9bda01..3b1c6dc803 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 bd0e52ce52..9a4470a912 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 b2894d697b..f57a3e8c99 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 50e6d35d3f..de906f3dff 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 5a563f7ed5..516ce25160 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 e106e8fd79..fbd8d22abc 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 8f6736bd79..d0038f8d73 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 9d07334692..d98d35199b 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 5435722e7d..84b1c4ff13 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 16ffe8a2f2..63e1146721 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 6495ce1735..9911612837 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 7ecf5236c0..00602d78b5 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 3e627d0ea7..7c888d3d91 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 a48fd3c14c..64f1900918 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 f4300de996..d13dd2057a 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 605e4f7c3a..f02a8167ff 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 f5c0eb2964..c4985b5445 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 176e0e8282..22dfb5f4bc 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 dbbd1876c9..170a42cd26 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 5e8c948b2e..ac7dd26537 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 ca1f6cc574..cbc4b81734 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 0cf496a480..65a60daee9 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 9fb0e4cab6..a5eee7e20c 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 03f7356a20..5696488c23 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 34/87] 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 1284f41ae4..cc082cb0d4 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 f2a58b6115..2094056a91 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 35/87] 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 d17a4e3238..d9bdfe8b65 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 36/87] 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 e828fb0719..3f2fa56127 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 7284430978..3d1c8e71a3 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 7542c9298b..b9fbb9fceb 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 de906f3dff..2ce1a8e556 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 73c7c34fe4..f8be0f7ee4 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 37/87] 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 d008a35c85..10b8c1f8ac 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 3f2fa56127..e9fe68cb3b 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 ef786cd662..3f0f5d640c 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 94c440f404..387f473774 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 6d0b6320ef..1d41577228 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 5959c7cfed..f8625e8533 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 0000000000..eb4d8524fc --- /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 a6a3aa216b..25dc1448dd 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 c7efc9c520..f51c01fca7 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 db43eb769b..5cdfcf41b8 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 a5ce043c11..25dac1e046 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 031e11803f..9ec669a070 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 64f1900918..7257650581 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 a5eee7e20c..18899509d8 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 38/87] 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 538a57af44..e36afa48ba 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 18949f0aa6..3e6f2d2b90 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 39/87] 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 2094056a91..72562356f7 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 40/87] 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 58aea3172e..0000000000 --- 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 401c7c378e..7e5ade8198 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 41/87] 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 8d1e512773..34c98a348b 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 7e5ade8198..883ceed7ce 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 42/87] 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 3f0f5d640c..e6482d8e40 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 fa6c1be91c..dfd2a58b06 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 a5cec5368f..477d407909 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 84b1c4ff13..a313226bcf 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 0b5a6da573..5f189041d9 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 43/87] 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 477d407909..b7fbe01b9e 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 e36afa48ba..6236c3ea84 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 44/87] 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 10b8c1f8ac..d7dcdf72b0 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 f8be0f7ee4..8510a9edd0 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 45/87] 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 4d3924be95..f5e040a27d 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 02e2de7d28..f1c5417a3d 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 1475d24c41..5d18a89899 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 77fdf0df20..bad571de35 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 a50dddfcb4..214a6c79b1 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 dfd2a58b06..d75067e1f2 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 b7fbe01b9e..0887a874f4 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 46/87] 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 5e9c14fb98..c6239d627a 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 47/87] 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 7654431f4f..4eed0dcc67 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 48/87] 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 218ac0b85d..10894c4dc2 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 1e21cc7a66..ad79a05a3e 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 49/87] 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 9a4470a912..9d0bc100a1 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 50/87] 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 f5e040a27d..acb896f4a0 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 25dc1448dd..0581e220e4 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 5f9cb32abf..196f7b1a6d 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 7d749fb9b1..505074098a 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 a313226bcf..b92d711da8 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 51/87] 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 72562356f7..c9f8aede3a 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 52/87] 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 bc2d96d2f5..2b2d89f796 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 883ceed7ce..eb4ff27363 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 d593d9a7fa..dc22688222 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 84db61f019..7695dc97ff 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 cbc4b81734..b5331157dc 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 53/87] 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 1d41577228..18921a6877 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 6236c3ea84..2e44672659 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 3e6f2d2b90..2a44fefd43 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 54/87] 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 d7dcdf72b0..a51b8d5423 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 3d1c8e71a3..a9893a824d 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 55/87] 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 214a6c79b1..a2b7f37c48 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 1b8d827983..5508fa9cf3 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 56/87] 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 387f473774..5d1b5d75ce 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 c4985b5445..852dab3721 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 dc98bcaa95..7542c3d3bf 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 600d6709d0..0d3bcf4048 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 57/87] 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 44dbb48a64..28b0baf3c1 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 196f7b1a6d..0e51bd5ec6 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 58/87] 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 a51b8d5423..aeac26d038 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 59/87] 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 aeac26d038..b86ba8d2f2 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 8510a9edd0..2a517a4a17 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 0000000000..9171da10ac --- /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 60/87] 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 7d1e217b1a..a931dc3a31 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 5d1b5d75ce..192dcc7bc0 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 18d0fd70bf..7337a99180 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 a2b7f37c48..7a964fde94 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 18921a6877..3546e48d56 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 3ee25bf697..e76015a58c 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 505074098a..27df443bd4 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 61/87] 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 b86ba8d2f2..8a57162cde 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 e9fe68cb3b..1b59e7d33a 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 eb4ff27363..725f86942b 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 62/87] 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 7c888d3d91..25ff0d017c 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 393b321aab..1b9e9fdc3b 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 f02a8167ff..3bf7da305f 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 6230b882fc..bf73236159 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 18899509d8..96a1c186c5 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 c6239d627a..9222d8ba9e 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 63/87] 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 bad571de35..43cba873b0 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 7a964fde94..310ccdc3c0 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 725f86942b..5114c2ae19 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 07745dd3cc..c8223300bf 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 64/87] 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 7337a99180..828e6112f8 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 65/87] 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 10894c4dc2..fb41e3ee3b 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 1b9e9fdc3b..f2149e8903 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 66/87] 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 c9f8aede3a..dcf8fcc3a5 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 d806eacfb8..d7f72446d9 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 310ccdc3c0..abac40bc27 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 1dc6bc33dd..599bc290b0 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 b5331157dc..aec20ffd8f 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 67/87] 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 ae8b9ed689..8746f2ec48 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 803d0e6235..0000000000 --- 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 68/87] 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 8a57162cde..fcfa74fc4e 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 b9fbb9fceb..32ab4efb40 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 2a517a4a17..a10599acd8 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 a9541991d9..932fc32dbe 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 9171da10ac..a57a982642 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 69/87] 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 dcf8fcc3a5..16cf237938 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 70/87] 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 9d0bc100a1..99b5557149 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 516ce25160..659c4fe357 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 71/87] 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 fcfa74fc4e..737365a5d4 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 72/87] 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 737365a5d4..f0b5bdce52 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 73/87] 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 f0b5bdce52..b10795368b 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 74/87] 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 5508fa9cf3..4b2a81ec4f 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 aba8f27d53..343dfcf985 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 63e1146721..109b16a7a6 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 25ff0d017c..2fcf932452 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 a6dfde551e..fab20b1229 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 d13dd2057a..b69354a591 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 3bf7da305f..b02e96bfdf 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 852dab3721..9e1ff3ef54 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 73c28439ee..4b9fa31377 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 65a60daee9..01bc11c577 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 75/87] 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 1b59e7d33a..db705bd976 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 27df443bd4..01db032788 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 a9893a824d..8c7c7e6fcb 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 aa3ffadfb1..4dc6cae518 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 32ab4efb40..07b049a0e7 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 2ce1a8e556..c57f900b90 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 a10599acd8..7ddb717591 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 96a1c186c5..a233a78ca0 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 cf9b275a66..6b69b5bd2a 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 76/87] 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 1414a97054..8c93d3182b 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 77/87] 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 4dc6cae518..7903d38b27 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 78/87] 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 b10795368b..9c1edc6c9f 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 8c7c7e6fcb..14c009d7d6 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 07b049a0e7..b23697b172 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 79/87] 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 3b972f7721..c4c1c8dfbc 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 9c1edc6c9f..b074209e32 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 95290714c3..84a695d7ca 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 14c009d7d6..a2f4e86373 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 0000000000..28e5a845d4 --- /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 0000000000..e3adba016a --- /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 0000000000..a339d86039 --- /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 0000000000..171de875c8 --- /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 0000000000..0c861e7f7d --- /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 0000000000..2d7e95edf6 --- /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 0000000000..8ea82c2024 --- /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 0000000000..be3f4f9f14 --- /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 0000000000..6448dda6f6 --- /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 0000000000..f0d273f3bf --- /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 0000000000..764c4a50a1 --- /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 0000000000..e26ea3ebb2 --- /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 0000000000..2cd5cf9a6d --- /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 0000000000..38673d66b7 --- /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 7903d38b27..97c4282daa 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 7ddb717591..9b8446ad26 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 80/87] 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 97c4282daa..fe2486d3d1 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 81/87] 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 28e5a845d4..163afb3e5b 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 e3adba016a..358ab0cc0b 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 a339d86039..c02f055bb2 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 171de875c8..8982cb5896 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 0c861e7f7d..538bc5beec 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 2d7e95edf6..28ca3f819f 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 8ea82c2024..a17c5c47de 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 be3f4f9f14..d7d6883b23 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 6448dda6f6..4615ffd862 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 f0d273f3bf..b161f7d397 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 e26ea3ebb2..9ddeedc015 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 2cd5cf9a6d..fb83e44807 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 38673d66b7..3617a752c3 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 82/87] 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 29c9ad2df7..0d748be079 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 83/87] 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 64b41e7045..c0f4fe7bde 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 84/87] 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 2e44672659..232d61f66d 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 85/87] 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 b074209e32..a6e1d0203b 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 f26c4e7882..ef50c94059 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 34abf0043d..41e895456c 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 84a695d7ca..71d9d6543d 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 97303ef63a..be64279f7d 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 db705bd976..cd6b3d9668 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 008c66f604..ac868f2e44 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 a2f4e86373..bd145fa9b1 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 79148d55ba..ad68b29b62 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 b23697b172..a9d009d2e4 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 1b01a63387..fc2408cb5c 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 9b8446ad26..5f2407ec7e 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 86/87] chore: main CHANGELOG, tag v36 (#1397) --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d60f59271..bd62fd2c56 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 87/87] 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 a6e1d0203b..c08fc32083 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 5f2407ec7e..9f9c9db9f0 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"